记:一次大型单体应用拆分成微服务

Posted cc299

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记:一次大型单体应用拆分成微服务相关的知识,希望对你有一定的参考价值。

拆分对象简介:

公司的一款工作计划管理SaaS软件,2013年上线,单体架构。起初仅任务管理功能,发展到后来加上了账号身份权限、Feed流、日周月报、项目管理、计划管理、OKR、消息中心、打赏、贴标签、评价等等。常用租户数量1W+

目前的问题:

1. 目前是3个团队共同维护,经常一个团队改点东西,需要三个团队测试同时回归测试,测试同学苦不堪言

2. 代码量巨大,构建一次至少20分钟,降低开发部署效率

3. 作为公司主站,经常因为业务特性升级而发版,造成生产环境不稳定,导致用户投诉

拆分面临的挑战:

1. 稳定!稳定!稳定!这是公司门户,而且ToB软件客户都是付了费的大佬,一旦主站不可访问导致客户投诉,直接就是P1问题,轻则考评降级,重则卷铺盖走人,不是开玩笑的

2. 由于代码时间长,中间不知经历了多少手,代码内部调用混乱、设计各有特色。

3. 此产品中很多服务作为其他产品的基础服务,拆分时要保证这些服务仍能正常运行,不能把其他产品搞挂了

4. 产品需要迭代进行,新特性不能停下来

5. 原来的数据存储是基于SQLServer的,公司要求底层基础服务统一迁移到ElasticSearch+Cassandra上

简单说,你以为微服务化是这样

技术图片

 

其实是这样:

 

 技术图片

过程大体经历了如下阶段:

1. 代码规范化、接口隔离(持续了2个月)

即把原来单一结构中,跨领域调用的地方,全部用接口隔离开,使各领域业务代码内聚

2. 代码拆分,微服务化(持续了2个月)

在第一步的基础上,把各领域代码迁移出来,领域间调用由接口改为微服务。

这个过程中,我们使用了KONG网管进行接口路由。原因有两点:

    1. 由于各服务独立成站点,各自拥有不同域名,导致前端或其他业务线需要把原来调老域名下接口的改为新域名。而前端、其他业务线资源很难协调,只能把老域名DNS解析到KONG上,然后再由KONG根据路由规则把请求转到不同服务站点上;

    2. 由于我们的URL上带有租户ID,因此可以利用KONG上的规则,进行灰度测试。把符合条件的租户,转到新站点上,大部分租户仍然使用原服务,保持稳定。

3. 数据库拆分(持续1个月)

切换DAO层、平移数据。

这一步要注意的是,使用ElasticSearch代替SQLServer查询时,由于ElasticSearch自身缓存刷到硬盘需要1秒延迟,许多原本写完立刻搜的场景需要规避,这是ES自身近实时特性决定的。最简单的方法是Sleep1秒,也可以使用分布式缓存(Redis)做一层镜像。

 

后记:

整个过程耗时接近半年,迁移过程中的压力是巨大的,特别熬人,可以说是如履薄冰。但迁移完微服务后,各个小组聚焦在自身业务上,可以独立上线,主站也稳定了,相互间调用支持熔断限流,调用链监控也加上,慢接口一目了然,可以说皆大欢喜。

以上是关于记:一次大型单体应用拆分成微服务的主要内容,如果未能解决你的问题,请参考以下文章

将单体应用拆分为微服务时如何定义 API 网关 URL

SpringCloudSpring Cloud Alibaba 之 Seata 分布式事务中间件(三十五)

SpringCloudSpring Cloud Alibaba 之 Seata 分布式事务中间件(三十五)

用微服务?

将单体应用拆分为微服务

微服务全流程分析