45天架构变迁实战,网易美学平滑微服务化靠什么?

社区编辑2018-05-17 18:06

微服务化是业务爆发后保证敏捷开发和部署的必然选择,但服务拆分和应用迁移涉及多项挑战。本文介绍网易美学的微服务实践过程和经验积累,包括技术选择、服务拆分以及应用平滑迁移的思考等,以飨读者。

背景介绍

网易美学于2016年12月正式上线,是以产品和技术为核心,以丰富的美妆产品库、用户使用合辑心得为主要内容载体的社区型产品。和绝大多数初创团队技术架构选型一样,为了快速上线,网易美学在一开始选择了单应用模式,所有的功能都打包放在一个war包里,基本没有外部依赖,应用部署在一个Tomcat容器里,包含了client、web、运营后台等所有的逻辑,这种状况一直持续到2016年12月,重构就在这个“大杂烩”的背景下开始。

单应用模式的网易美学


单应用比较适合小型的项目,优点总结如下:

(1)开发简单直接,可以集中控制;

(2)功能都在一个应用里面,没有分布式管理的开销(分布式事务、跨域性能、数据一致性);

(3)一体化的MVC,结构简单。

 

但是它的缺点也非常明显,新美业务开始膨胀后,这一架构受到越来越多的限制:

(1)所有开发都在一个应用改代码,导致开发效率低;

(2)构建时间较长,任何小的需求变动,都要整体编译打包部署;

(3)业务之间相互影响,修改一个模块的功能,可能影响毫无关联的另一个模块;

(4)稳定性不高,强依赖应用服务器和数据库的处理能力。

 

针对这些问题,新美在设计上采用了微服务架构,对单应用按照业务模块进行有效拆分,实现敏捷的开发和部署。

准备工作

(一)服务化目的

对于新美而言,要摆脱单应用的限制,服务化要达到4个目的:①业务细分; ②独立治理 ;③服务复用 ;④数据分离。


(二)技术准备

服务化技术体系包括分布式数据存储、服务间通信和消息中间件、服务注册和服务发现、API网关、部署容器、系统监控等六个部分,新美对应的技术选择如下:

(1)DDB+MySQL+Redis

(2)Kafka

(3)Zookeeper+Dubbo

(4)Spring Boot

(5)Tomcat

(6)JavaAgent


(三)服务规范制定

(1)服务协议层(定义服务接口、数据传输对象、异常处理机制);

(2)服务实现层,可以是数据库的CRUD,也可以是第三方系统的网络调用;

(3)服务依赖层,是组装各个服务,实现具体的产品业务逻辑;

(4)避免跨层调用。


服务化实施过程

(一)业务建模

这一步是服务化的基础,需要拆分多少子服务,服务间的依赖关系,都需要通过业务建模表示清楚。

 

新美是以美妆社区为业务载体的应用,针对女性化妆产品,用户可以产生大量的内容,进而产生各种社交行为。


(二)服务如何提供

在新美微服务架构中,每一个服务都有多个拷贝,用来做负载均衡,一个服务随时可能下线(发布时候),也可能应对临时访问压力来增加新的服务节点(线上活动预案),这涉及到服务发现的问题,新美通过Zookeeper作为服务注册信息的分布式管理,通过心跳检测维持长连接,实时更新服务信息。


(三)客户端如何调用服务

原先单应用的时候,服务都是本地的,UI可以直接调用,按照服务化拆分后,服务分散在一个个独立的Java虚拟机中,后台有多个服务,难道客户端就要记住多个服务地址吗?这不符合服务化拆分的目的,我们在服务提供者和客户端(app、web、wap)之间建立了多个业务gateway,用于提供统一的服务调用入口,让微服务对使用者透明,同时聚合后台的服务,实现统一的管理和维护。


(四)服务之间如何通信

到目前为止,服务都已经分散到独立的JVM里面了,单应用场景的各种相互调用在微服务后已经无法满足了。

 

因为服务提供层需要遵守“避免跨层调用”这一准则,服务之间的同步调用就被禁止了。

但是业务上需要解决类似于“用户注册后,发送系统通知”这样的问题,要处理这种场景,我们使用了异步消息调用来解决服务之间直接调用的问题,这也间接引入了分布式事务、幂等处理和最终一致性的难题。


使用异步消息,既能降低调用服务之间的耦合,又能成为调用之间的缓冲,保证消息积压不会冲垮调用方。

(五)服务降级方案

服务降级和服务治理,主要是为了解决某几个服务挂了之后系统如何应对的问题,新美目前还在建设中。

 

目前的比较成熟的应对方案包括:

(1)重试机制

(2)流量限制

(3)客户端降级(客户端本地代码实现,保证核心功能)

服务化平滑上线

前面大量讨论了服务化如何准备,如何实施,但真正的难题却是如何做好老应用平稳迁移到服务化应用,而不导致线上故障。


这里按照笔者多年重构的经验,提出一些核心的注意事项,涉及到和QA(质量保障)及运维团队的密切配合。

服务提供层做好单元测试,新老应用执行同样的用例,确保都能通过,这样上线切换的服务提供者基本能够保证没有问题。但服务调用和本地调用还有不一样的地方,那就是要考虑服务调用异常的处理、序列化的错误、调用超时的错误,这几个场景也需要在单测过程中写单独的用例来保证。

客户端调用API做集成测试和全量回归,这一部分主要工作在QA团队,需要在平时的业务开发过程中做好这部分的积累,新美QA平时做的这部分工作增加了我们服务化切换成功的信心。

上线预案一定要准备充分,主要包括数据迁移失败如何快速回退,服务化验证错误如何快速切换到老应用。

独立申请测试环境,将线上数据导入到测试库,多做几次线上模拟切换操作。

最好做灰度切换和发布验证,让一部分用户先使用新的应用,验证OK后再全量切换,比如新美按照办公网络和外部网络来划分用户群体。


新美服务化总结

整体来说,新美服务化是一个大动作,我们赶在2017年春节前后业务相对空闲的时期,做了比较彻底的架构调整,时间持续一个半月。由于事先准备充分,我们整体切换比较平滑,不涉及到停机发布,做到了用户无感知,并沉淀出的一些通用解决方案:

(1)业务建模DDD

(2)分布式部署架构


(3)分布式事务最终一致性


作者丨李元洪  网易美学架构师

网易云原创投稿,未经许可,谢绝转载