关于时区的整理
一旦涉及跨服务器的服务,那么难免碰到时区同步的问题,而 Web 服务很少是单机提供的,因此做现在的 Web 架构中应当处理好时区问题。
之前在写业务接口的时候,将系统所有的入口和出口都做了时区转换的处理,在内部各函数之间使用无时区的 datetime 格式传递时间,避免一些常见的小错误:
- 单方面使用 arrow 库的对象
- 将带时区和不带时区的 datetime 作比较
- 将零时区的日期入库导致差错
结果今天 airflow 从 1.8.0 升级到 1.9.0,也发生了时区问题,具体表现为 scheduler 成功调度了一个 DAG,但是却没有真正生成 DAG RUN,手动执行 airflow run 也无法执行。所以需要基于几个原则进行排查,看错误发生在哪一步:
- 所有的服务(包括数据库、终端 UI)都是有时区的
- 服务入口对时间进行时区转换,拒绝不带时区的时间,保证服务内部时区的统一。
- 服务出口为带时区的时间。
- 如果大家都遵循同一种规范(默认时区),则可以接受和传递不带时区的时间,但这事实上是不可能的,因为终端 UI 的默认时区是不可控的。
目前的情况是:
- scheduler 按照零时区的时间进行调度,之前以 contab 格式运行的 DAG 都会偏差 8 小时。
- webserver 按照零时区的时间进行显示
- log 使用的是服务器的默认时区
至少需要使 scheduler 的调度正确,最好 webserver 也能显示正确。
解决方式是使 scheduler 使用正确的时区,在创建 TI、执行 run 指令的时候时间正确。
- 尝试通过 default_timezone = Asia/Shanghai 配置,但是未生效。
- 发现 default_timezone 是在 1.10 才能生效,但是该版本目前处于开发中,可能有其他问题。
结论:
- 由于时区问题,1.8 升级到 1.9以后会存在 8 小时的死时间,这段时间的任务会被认为已经执行过了,无法运行。
- 由于时区问题,需要在每天的指定小时运行的任务会延迟 8 小时。
- 在不改 DAG 的情况下,不能升级 1.9,需要继续使用 1.8。