今年是回到广州工作的第二年,本年度继续负责埋点平台相关的工作,工作重点从客户端转移到了服务端,在团队中的角色也从辅助开发变成了埋点管理平台和服务端埋点组件的核心开发,由于今年的开发项目都是并行的,所以以项目顺序说一下自己对今年所做项目的一些心得和想法。
Android埋点SDK开发(java + kotlin)
本年度安卓埋点SDK没有较大的功能开发,主要是对之前的功能进行补充和完善,对自身并没有太多的提高,完成的功能如下:
配置热切换
本来SDK要通过分包才能切换配置,开发这个功能后,SDK可以通过接口来控制当前应用的配置,相比之前更加灵活。
CRC校验
客户端与网关使用相同的CRC算法,对上报数据体进行CRC计算,对比是否一致以确定数据准确性,用来解决数据上报被截断的问题。
插件模式
换而言之,利用反射去调用其他包的代码,忽略不写。
数据质量
换而言之,心跳上报,忽略不写。
日志全局回调
由于业务方提出需要一个接口去提取上报是否成功的信息而不使用原来log输出的方式,使用了观察者模式去监控数据上报情况,当上报成功时便将信息通知观察者,并让观察者的接口方法拿到信息,尔后再让业务方进行处理。
埋点管理平台服务端开发(java)
本年度一半以上的工作都在参与埋点管理平台的开发,以下提取一些值得记录的点进行叙述。
埋点版本
今年完成最大的功能是埋点管理平台的版本管理系统,以下将挑出值得思考的四点进行回顾:
版本
首先以我看来版本这个概念主要实现了两个目的:
- 将当前版本的埋点和过往版本的埋点在测试环境进行隔离
- 将测试环境已经完成的埋点直接同步到生产环境
但是想实现上述目的,会遭遇几个困难:
- 需要提交版本才能更改过往版本的埋点,不能实时修改
- 测试环境和生产环境的数据需要一致,不然会引发合并错误
至于问题1:
产品的建议是根据用户角色开启后门,使得高权限用户可以直接修改已发布版本的元数据,这样做虽然方便,但是会引发问题2,导致生产环境和测试环境的元数据不一致影响合并,而实际上测试同学也试过误操作影响系统的正常使用。
而我这边的建议是开发一个操作审批系统,对于已发布的版本元数据的操作,必须要最高权限的角色进行审批才能进行,以保证不会出席脏数据。
至于问题2:
对于旧应用会造成影响,目前仍需要人工进行校准,看看在新的一年接入更多业务时,有无更好的解决方法。
事件、平台与角色
在版本中的事件,会有平台和角色的概念,一个事件会属于多个平台,而一个平台又会由多个角色来负责,在这里我目前设计的是两张表去解决,一张事件平台表,一张事件平台角色表,但是在后面深入的开发中,我觉得事件平台表显得冗余,考虑用一张事件平台角色表概括直接管理这个两层模型,看看在2023能否进行重构。
事件与子事件
在版本中的事件存在事件与子事件的概念,原因是因为产品期望在版本中可以有同名事件,而在元数据中事件名需要唯一,因此引出了子事件属性关系表,目前是通过id去区分事件和子事件间的关系,但是细想这边仍有优化的空间,暂且先作记录。
版本创建同步信息
目前需求期望,新版本创建时,需要将元数据事件属性和旧版本搁置事件全部同步到新版本中,在小数据量时,这样的操作并无太大问题,但数据量大时,因为事件的插入需要同时影响事件平台表,事件角色表,事件属性表,会造成数据库处理时间过长,而前端返回客户504的情况,对用户体验造成影响。针对这个问题,和产品沟通时提出了几个方案:
- 版本合并后,立刻创建新版本,等用户操作时只是假创建,避免超时。
- 异步创建元数据
- 简化元数据创建过程
以上方案,将在年后进行预研实施。
标签系统
目前平台中的属性均可被打上标签,被打上标签的属性可以被统一与某一事件绑定关系,目前的设计是用一张标签属性关系表去管理,这样看起来没问题,但是产品又要求,要在事件侧展示所绑定的标签,然后就引出一个问题,先要查出事件属性的关系,然后再查出属性标签的关系才能进行展示,而每次属性和标签进行解绑/绑定的时候,要去计算出所有受影响的事件进行计算,这样就会影响到效率,影响用户体验。
其次标签是和属性id进行绑定,每创一次版本,版本属性就会产生新的属性id,换而言之,每一次创建版本,都要创建一次标签属性id关系,这样个人意见是会导致存储的冗余,久而久之也会造成影响。
针对以上问题,我的建议是标签和应用属性的名字进行直接绑定,方便进行控制和避免产生冗余数据,同时也会减少第一个问题的计算量和缓存所需内存量。
KAFKA消息注解化
针对重复的代码操作,使用注解+AOP的方式,在切面将其实现,提高了代码的可维护性,但需要注意的一个问题是,同一个方法追加多个注解时,注解的执行顺序不是固定的。
请求拦截器
修改HandlerInterceptor类和HttpServletRequestWrapper 类,记录每一次请求的信息,方便排查问题。
数据采集器组件开发与容器化(java)
数据采集器开发是今年的第二个重要任务,也是挑出值得提及的几点进行叙述。
远程配置下发
之前的数据采集器配置是读取本地文件的,这样做的弊端很明显:
- 部署困难
- 管理困难
针对以上问题,改成了从服务器中根据pod名字或者配置id进行读取,便于管理和部署。
管理后台开发
之前数据采集器,没有监控质量、进度和配置的平台,开发以上平台解决以上问题,方便查询管理和查询异常。
容器化
今年响应okr号召,将数据采集器进行了容器化操作,容器化之后,资源的调度更方便,部署更加简单,自己也学会了更多k8s的知识。
退出与进度保存
优雅退出是今年数据采集器遇到的一个难题,容器化前的进程退出,是进程停止三十秒接收数据,然后保存进度,最终停掉进程,这种操作在非容器化前很合理,但是在容器化后却出现了问题,k8s中,一个pod被kill掉后,在旧的pod未完全结束前,新的pod是已经进行重启的,这时候就会出现一个双pod并行的情况,造成数据重复,针对这点,一开始考虑的是prestop钩子方法去解决,虽然这个方法是有执行,但是却不能保证新的pod在旧pod完全保存进度后,再启动,为了保证新pod一定要在旧pod完成进度保存后再启动,将程序延时一分钟再启动,避免重复,但是感觉这种解决方法比较粗暴,期望自己对k8s有新的理解后,有更好的解决方案。
组内项目看板项目开发(java)
这个是领导交予的一个组内项目,基本都是CURD的功能,唯一有一点难点的只有单点登录的接入,不过是第一次作为项目组长去做项目,在其中锻炼了自己写周报的能力。
总结
- 今年还是做了很多crud工作,提升了自己crud和抽象设计的能力
- 接触了k8s,开始熟悉容器
- 还是没接触flink,2023期望可以接触