扶翼重构技术方案

重构目标

问题与目标

维度 问题 目标
可用性 1. 依赖于第三方,第三方接口故障导致不可用
2. 部分功能故障,占用web container线程池,造成整体不可用
3. jvm OOM等问题,没有监控
4. 定时任务失败,没有重复执行或者故障转移
1. 应用服务器的监控
2. 建立舱壁模式,接口之间相互不影响
3. 定时任务故障转移
性能 1.第三方性能下降,无法快速定位问题
2.没有并行调用
3.没有异步调用
4.前端js没有拆分,下载时间长
5.接口数据量过大,导致加载缓慢
1. 熔断器模式,保证高优先级接口正常调用
2. 用消息队列进行解耦
3. 使用CompleteableFuture或者RxJava并发调用
4. 前端框架更新
5. 优化接口
易用性 1. UI交互及数据组织不合理之处
2. 提示信息不规范
1. 重新设计页面交互
2. 整体提示信息
风险及包袱 1. 代码没有规范,多年慢慢腐化散发臭味
2.日志记录没有规范,排查问题不方便
3.临时处理方案渐渐变成永久的,隐藏的深坑
4.文档缺失,从需求文档到设计文档,啥都木有了
5.没有可以反复执行测试用例
1. 重写主要流程代码
2. CodeReview
3. 补充设计文档
4. 增加测试用例
架构 1. 架构陈旧,无法利用很多新技术
2. 无法很好的在现有基础上建立OpenApi
3. 龙渊、扶翼、SAX底层在一个库中,风险很高,同时相互影响,很容易出现主从延迟的情况
1. 使用新架构
2. 数据库独立出去,并且进行数据迁移

重构切换步骤

  1. 保证新旧系统同时运行,新系统有故障时,可以返回旧系统进行操作。
  2. 新旧系统的数据隔离,数据不做迁移
  3. 新系统能够灰度上线,暂时提供给部分代理商使用。新系统会采用新域名,可以在前端做分区,分别路由到不同的域名。

技术选型

架构风格

选用微服务方案,业界已经比较流行,并且对于现有的广告业务来说也是比较合适的。主要优点如下:

  1. 可组合性,易于重用已有功能
  2. 技术异构性,每个服务可以选择适合自己的技术栈
  3. 避免系统变得过大,和团队的人员结构进行匹配

同时,微服务也会带来一定的风险,主要有以下几点:

  1. 有可能分布式事务
  2. 网络超时问题,幂等性设计
  3. 测试与部署复杂度上升
    针对上面的问题,后续设计的过程中会提及到克服的方案。

整体架构

说明:

  1. 后端分为API网关层、服务层
  2. 对外的接口调用都在服务层进行
  3. 需要有构建、部署、测试的自动化
    整体架构

选型确定

后端技术选型

架构说明

整体架构图

整体架构

说明:

  1. 扶翼服务主要分为核心服务和数据服务,核心服务暂时不做进一步的拆分
  2. ElasticJob负责所有定时任务的执行,多实例部署,带故障漂移功能;对执行时间有要求的任务分片执行
  3. Eureka Server作为注册中心,注册中心只作注册发现,Provider与Consumer的调用不通过注册中心
  4. OpenApi与Web都作为服务的Consumer,分别作为ApiGateway实现,因为两者对外的接口与职能完全不同。OpenApi会有OAuth2验证,配额管理,封禁策略等,且接口格式不同。二者都基于Service既能保证底层服务的复用,又能使得内部功能快速上线。
  5. 所有的日志推送至ELK, 由于机器紧张,后续与引擎公用ELK
  6. 分布式配置管理作为统一服务,提供动态配置修改功能

系统交互

系统交互图

统一登录

目前的统一登录逻辑是比较混乱的,主要存在以下问题:

  1. 同时有不止一个账号处于登录状态。如:代理商平台使用代理商账号登录,同时使用一个客户账号在客户平台登录,两者可以同时使用。
  2. 前后端都和SSO打交道,发生修改时,所有系统都需要进行修改。
  3. 在使用SSO体系的前提下,商业产品账号和用户产品混淆,长期来看,应该建立商业产品的账号体系。

时序图

遗留问题
前端还依赖于SSO,因为要写cookie,目前没有更好的方案。

操作日志服务

目前操作日志的问题

  1. 直接写入数据库,速度慢;并且操作日志的写入失败会引起事务的回滚
  2. 扶翼的操作日志写入在扶翼库中,而在商业门户中展示
  3. 随着日志量越来越大,每天的新增5万条左右,查询性能差
  4. 操作日志属于非结构化数据,使用mysql做检索非常不便

改进方案

  1. 由日志服务统一提供操作日志的存储和查询功能
  2. 存储使用es,mongodb等支持非结构化数据存储,并提高查询性能
  3. 异步记录提高写入性能

架构图

推送S3

创意提交(新需求不一定能够这么做)

改进前

  • 创意提交时图片上传至S3
  • 目前采用的是同步的方式,返回速度依赖于S3
  • S3不稳定,保存至S3失败会导致用户创意提交失败

现状时序图

改进后

  • 采用异步方式
  • 扶翼访问推送S3服务,该服务把图片推送消息队列后返回
  • 扶翼提示用户保持创意成功
  • 推送S3服务从消息队列中获取图片推送S3
  • 失败时,重试;超过规定次数,报警

改进后时序图

创意审核流程

改进前

  • 审核处理流程比较长,完全是同步进行处理,速度慢
  • 批量审核时慢得令人发指

改进前时序图

改进后

  • 采取异步的方式
  • 审核通过后的创意需要在静态池中存在后,才能通知引擎,否则会出现天窗的情况
  • 用户响应速度大大提高

改进后时序图

ElasticJob

在进行了众多的异步改造以后,系统中有更多的地方都需要使用定时任务进行处理,对定时任务的可靠性,并发处理能力等都提出了更高的要求,所以需要更深入的使用ElasticJob来解决问题。
关于ElasticJob, 后续会专门写一篇文章来介绍,这里略过。