专题目录
一文搞懂国际化(一)背景概览
一文搞懂国际化(二)架构设计
一文搞懂国际化(三)落地实践
一文搞懂国际化(四)总结提升
一、多语言落地
按照之前第二节的设计,我们多语言翻译区分静态和动态两大类。静态翻译直接前端实现,动态翻译需要后端实现。下面我们看下详细步骤。
1.1 前端静态多语言
1.1.1 设计
- 1.个性化设置语言、时区。
- 2.登录后/设置完后,更新设置缓存。
- 3.前端读取缓存配置从本地语言包中选择制定语言、时区渲染。
1.1.2 使用逻辑
- 1.用户设置的
- 2.未设置,取系统的(APP取手机端的、web浏览器)
- 3.系统取不到,兜底默认中文(apollo可配置)
1.1.3 实现细节
前端没啥特别的,根据不同前端(手机端APP、web浏览器)缓存使用不同技术即可,不展开细讲。
1.2后端动态多语言
1.2.1 设计
- 1.后端应用启动时,缓存一份服务依赖的多语言包数据进内存缓存。
- 2.业务接口请求时,header传参制定语言,返回时(序列化),做翻译。
1.2.2 使用逻辑
- 1.前端请求header请求带过来的(用户设置/客户端local系统跟随)
- 2.未设置,兜底默认中文(apollo可配置)
1.2.3 实现细节
1.注解在实体类上 @EnableI18nSerializer 在具体字段上@I18nFieldTrans(translateKey = "c.key"),定义好key
2. 序列化时(接口数据返回时)把翻译后的值写进去。
1 public abstract class AbstractI18nJsonSerializer extends JsonSerializer { 2 3 }
不在往下细化,就是从缓存中取翻译值。
二、时区时间改造
2.1 前后端接口改造
2.1.1 方案描述
方案回顾:重新部署一套UTC0环境(后端服务、组件、数据库、洗数据)。
- 前端:发起请求,传值ISO格式时间,例如:韩国东九区时间“2024-01-12T09:00:00+09:00”。ISO8601格式的时间(上跳第一章第三节),是为了有更好的可读性,且能表示唯一时间。
- 后端:请求到后端时,在入参接收时,框架把本地时区时间转换为系统默认时区(UTC0)的时间。(图中UTC9→UTC0)
- 后端:执行业务逻辑,数据落库(UTC0)。
- 后端:请求返回在序列化时,框架统一在序列化时返回ISO零时区时间。
- 前端:拿到后端返回的数据,接收ISO时间自动转成客户端本地时区时间,格式化后展示。
2.1.2 实现细节
一、前端处理
1、接口入参格式化
dayjs 默认本地时区的ISO-8601格式时间
2、返回数据格式化方法
dayjs 转为当地时区并格式化显示
二、后端处理
接口传输用OffsetDateTime即可表示瞬时时区偏移。
- 目前:使用LocalDateTime接收,对应数据库timestamp。
- 完美:使用OffsetDateTime接收,对应数据库timestampz,这个方案需要改数据库字段类型和Java类型,更加彻底,但是成本更大。
Json格式的Spring默认使用了Jackson序列化和反序列化。由于LocalDateTime本生不带时区,现在想要转换时间,我们需要对LocalDateTime进行增强处理。
1.入参解析
1)base-mybatis查询map入参:LocalDateTime。QueryParamUtils的castType方法:
2)入参单个时间String:-->后端LocalDateTime接收的情况,需要配置全局的日期转换器。借用Spring的启动机制加载进去。
3)json请求(Content-Type=application/json):JSON反序列化。LocalDateTime Jackson默认反序列化包中已支持“2024-01-12T00:00:00Z”,只需要增强处理带时区的“+08:00”。
UTCLocalDateTimeDeserializer extends JsonDeserializer implements ContextualDeserializer
2.返回数据
JSON序列化:返回类型都是JSON格式的,直接在序列化方法中转换“2024-01-12T00:00:00Z”。即可。
继承JsonSerializer 实现ContextualSerializer接口。定义LocalDateTime的序列化对象。
2.2 云边协同
2.2.1 方案描述
步骤:
1)业务应用系统指令下发给IOT
2)IOT协议下发MQTT给到边缘端,
3)边缘端执行完后再协议上报给IOT
4)IOT结果上报给业务应用系统
2.2.2 实现细节
- 边缘端、设备都设置成本地时区。边缘框架提供一个时区设置的通用协议,供引擎和设备同步时间时区用。
- 云边交互协议:普通下发、上报的协议、云边同步事件,创建时间,修改时间,业务操作时间,必须全部使用时间戳。
- 边端设置本地时区。
边端时区设置
1、边缘引擎需要支持系统时区设置,包括操作系统、PG、Clickhouse需要保持一致(前期没有就只能手动设置)。
1.1 PG 默认跟随服务器时区(因为挂载了宿主机的timezone,所以修改宿主机时区即可)
1.2 CK 默认跟随服务器时区,需要更新镜像,移除配置文件指定时区(因为挂载了宿主机的timezone,所以修改宿主机时区即可)
考虑到日志分析便利性、技术实现的复杂度,直接修改边缘引擎系统时间是最合适的。
时区设置功能建议设计在 "边缘引擎主机管理" ,设备安装交付时统一设置,边缘引擎出厂默认UTC 8。
边缘设备
边端跟设备 交互都是时间戳,很标准的时间,不用修改。
不同业务用的设备都不一样,需要找硬件产品梳理。
注:
这里可能需要边缘框架提供一个时区设置的通用协议。
实际操作:----需要跟硬件嵌软沟通确认。
- 旧设备要刷一下嵌软,刷成UTC0。
- 新设备统一固件,UTC0。
2.3 大数据统计
2.3.1 场景描述
典型应用场景:
- 明细类: 通过前端传递时间 通过sql 方式,大数据网关查询明细表。
- 聚合类: 如果是按天统计提前聚合跑数,大数据网关查询查询聚合表。
大数据目前方案:按某原表字段,按天聚合,每小时跑一遍全量数据。
2.3.2 实现细节
业务原表-时间字段同步到大数据ODS层,做时区转换。
- 方案1:原字段修改转换后数据:增量数据写Kafka时就转换时区(按照某业务区域划分时区)。后续有时区切换,源库变时间,大数据统一全量同步。----大数据分层表不变。
- 方案2:加表存储转换后数据:同步消费时去在ODS层再加一层表,doris、PG存储都需要增加一倍的表。较为繁琐,但原始业务数据保留下来。
方案1如下图所示:
2.4 后端定时任务
2.4.1 场景分析
XXL-JOB中配置的、直接java代码程序启动线程。
1.指定某时间点执行(低频执行):由于数据统计期望根据猪场级别统计,而每个猪场可能在不同时区,会出现根据时间段的时间偏移,导致数据统计不正确,需要处理。
2.指定时间间隔执行(高频轮训):高频轮训的任务,例如每1分钟、每5分钟执行一次。不受时区影响(时区偏移最小单位为小时级),可以忽略不处理。
2.4.2 实现细节
针对低频任务(小时级),例如一天只有凌晨12点跑一次数据,或者固定几个时间点执行一次。
- 方案1:所有小时级任务全部配置为一小时执行一次。如果涉及复杂计算,对数据库会增加额外负担且1小时不一定跑的完。---适合执行时间短(必须小于1小时),对数据库压力不大的任务。
- 方案:2:执行频率变为1分钟一次,进入任务后,判定时区转换后的时间点是否匹配,匹配时再执行。这样执行次数不变,只是增加了开始执行时间的判定逻辑。--适合执行时间长,对数据库压力大的任务。方案2如下图:
2.5 数据导入
2.5.1 场景描述
存在需要通过上传EXCEL文件,把某时区的公司业务数据导入系统的场景。
此时,客户使用系统导入功能,一般EXCEL表格中填的业务时间,肯定是本地时间(实际发生时间)。如果直接导入系统,客户的本地时间的时区和服务端数据库的时区很有可能不一致,此时时间就错乱了。
2.5.2 实现细节
- 方案1:EXCEL中标明时间字段转换成ISO UTC0时区时间再上传。----要求客户转时间,执行难度大,不采纳。
- 方案2:请求头带时区,后端转换。具体方案如下图:
步骤:
1)前端文件上传,EXCEL中时间字段是本地时间。
2)后端解析EXCEL文件,根据请求头中的时区,做时区转换,转换成后端统一时区UTC0时间。
3)UTC0时区时间数据插入数据库。
2.6 三方通信
2.6.1 场景描述
目前接入的都是UTC8时区的国内系统,问题没有暴露。但是将来对接国际化三方系统时,如果还是按照现在的UTC8时间去交互API,如果对接的三方时区不是UTC8,直接传UTC8时区的时间字符串,时间就错乱了。
2.6.2 实现细节
不可能要求第三方系统也要改造UTC0时间,因此基于第三方不改造前提下,需要针对第三方配置--->第三方所属时区,接收和返回参数按照时区转化后处理。
- 开放平台配置第三方是否支持国际化(时间都是时间戳/ISO格式):如果不支持,配置好三方的时区。
- 第三方不支持国际化的(时间不是时间戳/ISO格式):例如UTC9时区时间,根据开放平台配置的时区,做时间转换。
- 第三方支持国际化的(时间都是时间戳/ISO格式),不需要做转换直接调用即可。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |