B端架构升级之路
一、背景
随着B端业务快速发展,系统愈趋复杂。我们发起了B端架构升级专项,基于B端业务的特点,从研发规范建设、B端架构基建、系统架构升级和落地保障等多方面提升了B端的架构水平。
二、升级思路
架构是一项复杂的工程,每个团队、每个服务都有自己的诉求。在B端架构升级项目中,我们的整体思路是先解决上线变更带来的稳定性风险,然后再逐步过渡到架构架构基建和架构规范,最后推动业务服务的架构升级。

1、首先是建设完善的流程规范及落地保障机制建设
根据稳定性的二八定律:80%的故障是变更导致的,因此研发流程及规范是优先要做的,在落地保障方面,通过工具、数据、组织保证等方式来保障规范落地及持续运营。
2、其次是完善架构基建
在稳定性方面:建设可测试性、可观测性能力,尽量把问题暴露在测试阶段,并保证线上出了问题可查看、可报警、可排查,补齐了服务的稳定性保障方面工具层的短板。
在研发效率方面:沉淀架构基建和架构规范,为以后架构升级打下基础。
3、最后是服务架构升级
通过存量业务梳理,解决存量业务中的稳定性风险;通过架构升级,推动服务领域化及架构规范化,降低认知复杂度,全面提升所有B端业务架构能力。
三、研发规范建设
通过以下三个层面建设了长期有生命力的规范保障体系,首先建设了完善的研发流程规范和故障定级规范,然后基于规范完善了流水线,从工具层面保证了规范的落地;最后做了培训和周会等制度,从培训和组织层面保障稳定性持续提升。

1、规范建设
建设了覆盖研发全流程的规范,这里不再详细展开。

2、规范保障机制
(1)流水线建设
基于公司的KDev流水线,从工具层面保证了规范的执行,举个例子:规范规定禁止直接在master分支提交代码,口头约束、宣讲等方式都不能做到100%遵守,最有效的方式是从Git工具上禁止提交,做到了严格根据规范卡控。流水线建设所做工作主要有:
| 分类 | 流水线步骤 | 关键点 | 进展&收益 |
|---|---|---|---|
| 代码格式 | 静态代码规范卡控 | 定义了B端的静态代码规则 | 适配B端新代码规范场景,避免了类误用的情况 |
| 权限卡控 | master分支权限卡控 | 去除了除TL外的RD权限 | 防止没有代码review就推动到master |
| 代码评审 | CodeReview卡控 | 强化了代码评审规则,具体如下:1. 需要核准的人数 >= 2 2. 需解决所有评论3. 请求创建者禁止核准合并请求4. 代码提交者禁止核准合并请求5. MR更新时需重新进行核准6. 小组TL必须核准通过 | 避免了代码评审走形式问题,提升了代码评审质量 |
(2)组织建设
以上的规范和工具最终落地还是需要组织建设来保证落地。组织建设方面做的工作主要有:
a. 定期组织宣讲培训:提升RD的稳定性意识;目前已组织规范宣讲、架构规范宣讲、故障定级规范宣讲等;
b. 通过周会持续跟进规范和稳定性数据:目前已经将稳定性指标数据列为团队的OKR,每周周会Review数据并并跟进异常数据;
c. 日常技术评审和CheckList规范跟进:将技术方案评审和CheckList文档作为团队规范,日常需求迭代过程中,B端架构和稳定性治理委员会持续跟进把控技术方案和上线质量等;
四、B端架构基建建设
B端在研发时基建能力有所欠缺,由于B端业务相比C端复杂度更高,在原有C端的技术栈上开发影响开发效率。

为此我们做了以下几方面的工作:
1、B端工具建设
基于B端的业务特点,引入了三个提升研发效率的工具:
(1)lombok
引入原因:
提升研发效率,代码更简洁:不用手动生成set\get等方法
lombok依赖包只是编译器生效,不会带到线上,不会导致maven依赖传递
行为可预知:制定规范,只使用行为可预知的注解
(2)MybatisPlus
C端原来的技术栈是基于JdbcTemplate,每个SQL都需要手写SQL,在C端场景下更注重性能,但是B端更重视研发效率和建模。经过多种方案的对比,最终选择了MybatisPlus。
引入原因:
基于代码生成器,节省Model类、Dao类的开发工作
节省简单SQL还需要手动拼写的工作
疑惑解答:
性能比jdbcTemplate差:没有对C端高并发读DB的接口,研发效率的考虑比性能优先级更高
生成大量垃圾代码,比如Example、XML等:MyBatisPlus不会生成大量无用代码,只会生成一个简洁的文件,只有类定义
污染Dao层外的代码,比如Wrapper会把数据库字段传递到Service层,方法:定义规范,Wrapper等数据操作放到Dao层
生成代码不符合公司代码规范,还需要修改:自定义代码生成器解决
同时在引入MybatisPlus之后,我们做了技术栈适配的工作,包括:
代码生成器适配公司的checkstyle和目录结构
适配公司的分库分表组件等
(3)MapStruct
是什么:一个类似于BeanUtils的对象转换工具
引入原因:
性能:自动生成代码,性能比各类BeanUtils的反射形式提升一个数量级
不会maven依赖传递:引入jar包只在编译期间有效
节省工作量:节省各类DTO字段转换工作,而且可以反转
2、架构规范建设
(1)分层&目录规范
核心思想:简洁,目标:不用翻大量代码,知道哪块代码放到什么位置
建设思路是参考了DDD的分层规范,同时适配研发同学的习惯,形成了B端团队的规范
分模块:
对外发布层:包含api层和runner层
聚合层(apiService层):承接接口层请求,组装domain层业务组装
领域层:核心业务逻辑层,可根据场景分多个service, 核心业务逻辑层,即:service、entity、dao层等
基础层: 包含 外部依赖(aclService)、基础包utils、constant静态配置、config 配置等
sdk层:对外发布的protobuffer定义等
分目录:
a. infra层规范

aclservice 封装外部RPC接口
common 配置pref打点的配置 和其他通用配置
config 仓库级别的全局配置,比如线程池等
constant 数据源配置,之前的kotlin配置代码
exception 异常定义、错误码定义
mq mq的配置
b. domain层规范

doc: 主要是PlantUML流程图文件
schema: MySQL和ES的定义文件及变更文件
config: domain粒度的配置文件,比如MybatisPlus配置
convertor: mapstruct 模型转换文件
dto:http请求、http返回值模型、其他传输模型
entity: MySQL表对应的实体对象
factory:创建工厂类
repository: 处于dao和service中间的一层,事务都放到这一层,聚合处理多个dao表的操作
valobj:entity实体类中的data对象
(2)脚手架
建设了适配B端架构规范的脚手架
之前使用的是C端脚手架,生成的模版代码如下:

新的脚手架生成的模版,主要体现领域模块和目录分层规范,示例如下:

(3)B端框架建设
B端框架是在C端框架的基础上演进而来,主要做了以下几方面的增强:
Http接口统一异常拦截
Http接口统一返回结构
Http和Rpc接口的统一错误码定义
可测试性、可观测性等能力集成
3、可测试性能力建设
B端可测试性能力的痛点:
认证体系多:有三套用户体系:面向外部合作商用户的、面向运营的、面向C端用户
可测试性能力缺失:之前测试都是先用账号登录staging环境,直接在浏览器借助前端页面测试,或者获取Cookie再使用Postman测试,Cookie有有效期,不能直接使用Postman之类的工具调试,导致整个调试链路复杂。
对下游依赖高:在下游没给出SDK或下游服务出错的情况下,没有办法继续自测,影响测试效率。
建设思路:
(1)建设了测试环境Mock工具,覆盖了MCN、C端用户、运营三套登录系统,在staging环境,可通过HTTP header模拟用户操作,且禁止线上环境Mock调用。
(2)流水线集成sandbox:这样服务部署就即可以通过sandbox mock下游的调用,在跨团队合作开发时,下游没准备好或出问题了也可以自测,提升了开发联调效率。
4、可观测性能力建设
目前团队采用的技术栈在问题排查方面有以下痛点:
日志:日志本地磁盘保存,服务重新部署后日志丢失
链路追踪:配置不规范,部分服务上下游Trace没有打通,导致排查问题复杂
打点:打点没有规范,建设报表每个都需要手动配
异常打点: 异常打点没有和Trace打通,出了异常排查复杂
借鉴业绩可观测的思路,从以下三方面建设了可观测性的能力:Logging、Metrics、Tracing。

目前落地的是日志能力,B端的日志特点是日志量小,但是要求存储时长长,我们做了以下几方面的工作:
打印所有操作的http请求的参数和返回值
基于方法注解打印方法调用入参和返回值
日志支持自定义业务字段(比如orderId、userId、活动ID等)的搜索
五、架构升级
架构升级的顶层规划是先划分整体视角的架构图,划分清楚各个业务的领域边界,建设B端团队基于领域建设的架构图。然后以此架构图来规划各团队的职责划分、Git仓库、领域模块。
具体执行层面分成两大块:
(1)新业务:直接按照领域架构图和以上沉淀的规范和工具建设新的服务
(2)旧业务升级:采用小步快跑的方式,逐步迭代业务架构
六、总结
以上介绍了一些普适性的架构升级思路,整体是基于团队的现状和诉求来驱动架构升级,B端团队在架构升级过程中,以稳定性和研发效能为主线,先从研发规范入手,保证了增量变更带来的稳定性风险,然后从架构基建和规范方面为架构升级打下基础,最后从业务领域划分入手,逐步升级B端的架构。
除此之外,我们还做了一些研发效能度量体系建设、B端基础服务(通用上传下载服务、通用审核服务等)建设等工作,未来我们会聚焦业务架构,沉淀业务的基础能力,以技术驱动持续为业务赋能。
本文链接:B端架构升级之路
作者简介:木小丰,快手架构师,专注分享软件研发实践、架构思考。欢迎关注公众号:Java研发
更多精彩文章:
B端架构升级之路的更多相关文章
- 1年内4次架构调整,谈Nice的服务端架构变迁之路
Nice 本身是一款照片分享社区类型的应用,在分享照片和生活态度的同时可以在照片上贴上如品牌.地点.兴趣等tag. Nice从2013.10月份上线App Store到目前每天2亿PV,服务端架构经过 ...
- CODING 代码托管架构升级之路
本文为 CODING 创始团队成员王振威在『CODING 技术小馆:上海站』的演讲实录. CODING 技术小馆,是由国内专业的一站式软件服务平台 CODING 主办的一系列技术沙龙.将邀请数位业内知 ...
- XView 架构升级之路
作者:京东零售 胡本奎 一 背景 1 是什么 XView是一个透明的塑料袋(容器),基于通用的webview框架改造而来,通常用于大促弹窗等营销场景,展现形式如下图: 2 痛点 在实际的开发使用中XV ...
- 从服务端架构设计角度,深入理解大型APP架构升级
随着智能设备普及和移动互联网发展,移动端应用逐渐成为用户新入口,重要性越来越突出.但企业一般是先有PC端应用,再推APP,APP 1.0版的功能大多从现有PC应用平移过来,没有针对移动自身特点考虑AP ...
- 资深P7架构师详解淘宝服务端高并发分布式架构演进之路
1. 概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. ...
- 服务端高并发分布式架构演进之路 转载,原文地址:https://segmentfault.com/a/1190000018626163
1. 概述 本文以淘宝作为例子,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. 特 ...
- 美团点评基于MGR的CMDB高可用架构搭建之路【转】
王志朋 美团点评DBA 曾在京东金融担任DBA,目前就职于美团点评,主要负责金融业务线数据库及基础组件数据库的运维. MySQL Group Replication(以下简称MGR),于5.7.17版 ...
- QPS从0到4000请求每秒,谈达达后台架构演化之路(转载)
https://blog.csdn.net/czbing308722240/article/details/52350219 QPS从0到4000请求每秒,谈达达后台架构演化之路 达达是全国领先的 ...
- 从游击队到正规军:马蜂窝旅游网的IM系统架构演进之路
本文引用自马蜂窝公众号,由马蜂窝技术团队原创分享. 一.引言 今天,越来越多的用户被马蜂窝持续积累的笔记.攻略.嗡嗡等优质的分享内容所吸引,在这里激发了去旅行的热情,同时也拉动了马蜂窝交易的增长.在帮 ...
- 阿里云云开发平台助力风变科技Serverless架构升级实战
阿里云云开发平台助力风变科技Serverless架构升级实战 背景 风变科技 一个希望通过技术去推动下一代基础教育的组织.旗下产品包括第一代的熊猫书院(读书类产品).第二代的熊猫小课(泛学科综合学习平 ...
随机推荐
- docker使用 mysql8
# docker pull mysql:8 # mkdir -p /mysql/{datadir,etc/mysql} # cat >/mysql/etc/mysql/my.cnf <&l ...
- Spring Boot+Thymeleaf+MyBatis--推荐一个后端练手极佳的商城项目
项目整体架构 newbee-mall ├── src/main/java └── ltd.newbee.mall ├── common // 存放相关的常量配置及枚举类 ├── config // 存 ...
- Jmeter Jsonpath 语法你了解多少?
- immutable 不可改变的 mut ≈ to move = to change - 单词学习
immutable im-不,非 + mut-改变 + -able. im 通 in able 有能力的 重点是 mut 的含义是 to change t 就是to mu 就是 change (*拉丁 ...
- PV的回收策略、访问策略和状态
PersistentVolume(PV)的回收策略.访问策略和状态是Kubernetes存储管理中的重要概念. 回收策略 Retain:当PV的回收策略设置为Retain时,即使对应的Persiste ...
- MyEclipse设置自动提醒(补全)功能
1. 打开MyEclipse,然后"window"→"Preferences" 2. 选择"java",展开,"Editor&qu ...
- 什么会导致JAVA应用程序的CPU使用率飙升
问题 无限循环的while会导致CPU使用率飙升吗? 经常使用Young GC会导致CPU占用率飙升吗? 具有大量线程的应用程序的CPU使用率是否较高? CPU使用率高的应用程序的线程数是多少? 处于 ...
- 360Linux 运维工程师面试真题
360Linux 运维工程师面试真题 首先我们来看下 360Linux 运维工程师招聘岗位要求: [岗位定义]运维工程师 [岗位薪资]15K-25K [基本要求]北京 / 经验不限 / 本科及以上 / ...
- openApi generator总是生成类名为 defaultApi
生成器可以开启 useTags 设置,开启之后会根据 api 文档中的 tags 生成前缀类名,因此,要不生成 defaultApi 需要以下操作: 1.openApi 文档中每个 url 必须要有 ...
- 记录--五个有用的iframe踩坑问题,快收藏!
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 你不会还不知道iframe不能嵌入百度首页吧?为了丰富用户体验,我们常常会将其他网站的内容嵌入到自己的网页中.然而,随之而来的是一个常见的 ...