早些时间,由于公司业务快速发展,系统也进行了架构升级,由单体应用拆分成微服务架构,本文主要和大家分享拆分的过程中的思考,希望可以给没做过微服务开发,或者是一直做微服务开发,没有经历过单应用系统的同学一些启发
一、初始:市场验证阶段
首先先简单介绍一下业务,我们的系统是一个传统的电商系统,在早期进行市场探索的时候,对系统更多是功能层面的要求,一个电商系统最基本要有商家端、运营端、用户端;每一端对应不同的功能,比如商家端要支持商家发布商品,绑定银行卡账户;运营端需要运营同学配置一些活动;用户端针对消费者,需要实现推荐、搜索、下单、支付、履约等功能,于是开始的系统架构是这样的:
可以看到此时系统是有分层的:
- api层对应不同端的http服务
- service层是一个jar包,也是主要的逻辑层
在早期功能较少的情况下,单体应用的表现是很出色的:
- 开发简单,改动项目较少
- 部署简单,只需要打对应端的war包即可
- 很少出现网络抖动引发的问题,排查问题也比较方便
公司的项目很快的通过了市场验证,研发团队的规模也从几十人到了上百人;正当公司准备大刀阔斧对系统进行升级改版时,单体应用的问题也逐渐的凸显出来
二、发展:单体架构之痛
为什么人多了,活干的却比之前少了?
2.1 编译、部署困难
随着代码量的不断增长,打出来的war包有几个G大,代码编译一次20-30min;即使只改动了1行代码,也要花费大量的时间去编译、打包系统才能进行测试;1天甚至有1半的时间,都在打包、部署项目。
2.2 分支管理混乱
单体应用代码本身按照功能,交由不同团队维护。各个团队通常通过创建不同包的方法,去划分边界,减少代码冲突,但是最终的代码都会合并到master分支,导致冲突时有发生,甚至出现过和丢其他团队代码的情况。更别说一旦有功能需要回退,情况就会变得更复杂。
2.3 发布困难
单体应用的所有代码,都在一个war包里,各个团队的需求又有轻重缓急,发布的时间点难以统一,经常是一天内多次发布,其中如果有某次发布需要回退,那所有团队的代码都会随之回退,这个时候就需要所有团队去评估,代码是否可以回退。通常情况是每天创建一个发布表格,各个团队将发布的功能,是否可以回退填写到表格中,固定时间由专门的同学统一拉群发布。
2.4 数据库连接数成为瓶颈
单体应用承接较高流量时,需要将服务部署在一个大规模的服务器集群上,当这些服务器连接数据库时,就会给数据库造成较大的压力,严重时可能会耗尽连接数
2.5 bug影响全局
由于“鸡蛋被放到了同一个篮子里”,一旦出现类似于内存泄露,OOM的问题,就会影响全局;即使不出现问题,场景之间也会有相互影响,例如秒杀活动开始时,机器的CPU会飙高,非秒杀活动的这部分流量,也会受影响,导致RT升高
2.6 资源管理困难
单体应用部署在一个服务器集群上,会造成一些资源的浪费,例如需要为一些高流量的场景,保持较多的服务器,或者使用更高配置的服务器,服务器资源得不到充分利用。
三、迭代:微服务架构演进
由于单体应用给开发、运维带来的种种问题。并且可以预见到业务在短期内还会有较快增长,现有系统没办法很好的去支撑业务,于是团队开始了微服务架构演进之路。
3.1 业务分离
微服务架构,核心其实在于业务域的划分与微服务运维能力,前者可以保障系统边界,在系统演进的过程中,可以沉淀出领域的通用化能力,以及平台能力,后续可以更好地支撑业务发展。后者可以保障服务稳定性,微服务系统由于是不同服务器通过网络进行交互,传输数据,相比单体应用更加复杂,排查问题也就更加困难,需要有一套完备的rpc监控,traceId等辅助开发人员定位问题。
电商系统按照功能可以划分为商家、商品、交易、营销、履约等业务域。业务域下又会划分子域,例如履约域下会有订单域和结算域。
3.2 B/C端分离
电商系统按照用户,可以分为针对消费者的C端服务,以及针对商家的B端服务,B/C端服务需要分别搭建系统。C端服务通常读多写少,主要通过缓存来提升系统性能,需要更多的服务器资源。B端服务往往逻辑更加复杂,QPS更低,但是对系统数据一致性要求很高。B/C端分离后,一旦其中一条链路出现问题,另一条链路的影响也会相对较低
3.3 资源分离
这里主要指的是 数据库、缓存、MQ等,每一个领域需要独立进行部署,维护,只与领域内的机器建立链接,从而实现数据层面的管控,降低发生故障时的影响范围,也可以节约数据库连接数。
3.4 域内系统划分
一般业务系统,通常为数据密集型,领域内需要根据对数据的处理方式,拆分不同服务,例如:
- C端实时接口服务
- B端实时接口服务
- 离线任务服务,通常是定时任务,可能会涉及到扫描数据表
- 数据流服务,例如:当核心实体数据变更后,通过数据流通知其他业务域
- 异步链路服务,通常是MQ的consumer 除此之外,还需要提供SDK封装一些数据处理逻辑,调用rpc的接口类等等。
这些服务并不是每个业务域都存在,应该按照自身的业务特性去决定是否维护服务,或者是是否需要其他服务,例如一些重依赖缓存的场景,会有自己单独的缓存清理服务等。
四、思考:微服务是银弹吗?
微服务在解决单体应用问题的同时,也引入了一些其他问题,例如:
- 对运维要求更高
- 定位问题可能需要跨服务定位,增加了定位问题的难度
- 网络抖动会引发服务器之间的数据传输失败,要处理好逆向流程,需要对异常做精细化处理等等。
总结:
因此是否升级微服务架构,需要根据系统规模来判断,中小系统可能单体应用效果更好。
后续博主也会分享大型网站开发相关的文章,希望小伙伴们帮忙点点关注,感谢