近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单体(Monolithic
)软件架构面临着越来越多的挑战,已逐渐无法适应互联网时代对软件的要求。在这一背景下,微服务架构模式(Microservice Architecture Pattern
)逐渐流行,它强调将单一业务功能开发成微服务的形式,每个微服务运行在一个进程中;采用HTTP等通用协议和轻量级API实现微服务之间的协作与通信。这些微服务可以使用不同的开发语言以及不同数据存储技术,能够通过自动化部署工具独立发布,并保持最低限制的集中式管理。
请围绕“论微服务架构及其应用”论题,依次从以下三个方面进行论述。
- 概要叙述你参与管理和开发的、采用微服务架构的软件开发项目及在其中所担任的主要工作。
- 与单体架构相比较,微服务架构有哪些特点?请列举至少4个特点并进行说明。
- 结合你参与管理和开发的软件开发项目,描述该软件的架构,说明该架构是如何采用微服务架构模式的,并说明在采用微服务架构后,在软件开发过程中遇到的实际问题和解决方案。
试题出自试卷《2016年下半年系统架构设计师考试论文真题》
摘要
2018年1月,我所在的部门因公司业务发展需要,承担了公司的实时消息平台的研发工作。该平台提供了即时通讯、消息推送、社交圈等功能,满足C2C(用户对用户)、C2B(用户对商家)、B2C(商家对用户)的沟通需求,同时为公司内其它业务子系统间消息流转提供支持。该项目于2018年6月开始投产运行,但经过一段时间的运行后,单体架构的1.0版本系统无法适配业务的高速迭代,模块间很容易互相影响,版本发布成本非常高。因此,2018年9月,公司任命我为该项目的系统架构师兼开发负责人,负责项目的架构评审、改造设计及实现。本文结合作者的实践,以消息平台为例,讨论微服务架构及其应用,包括微服务的基本概念及特点,如何从单块架构迁移到微服务架构,以及在实现微服务架构的过程中遇到的问题及其解决方案等。
正文
随着移动互联网技术的迅猛发展,我所在的公司的在各业务子系统的开发过程中发现,用户、商户、客服之间进行沟通的需求越来越大,各业务子系统间进行消息流转的需求愈加频繁,且使用起来十分繁琐不便。为此,公司于2018年1月开始研发设计通用的实时消息平台(以下简称为“系统“)。该系统致力于为公司内各业务产品线提供基础通用的消息服务,降低公司内各业务子系统间进行信息交互的复杂度,满足C2C(用户对用户)、C2B(用户对商家)、B2C(商家对用户)的沟通需求。该系统为C端用户提供了私聊、群聊、密聊、聊天室、漂流瓶等多形式多场景的即时通讯功能,同时,该系统还支持公司内各业务子系统间进行消息流转,如B端商家通过该系统可以定向地为用户实时推送各种业务消息,如订单消息、活动促销消息等。
该项目于2018年6月开始上线运行,由于V1.0版本开发过程中存在明显的赶工现象,模块间的解耦设计没有做到位,整体修改成本比较大。另一方面,随着时间的推移,系统的并发业务量也越来越大,业务对于系统的可靠性、高并发等要求也越来越高。单体架构的V1.0版本无法进行动态扩展,难以满足业务的高速迭代需求。因此,2018年9月,公司任命我为该项目的系统架构师兼开发负责人,主持项目的架构评审,改造设计及实现。根据项目的当前情况以及业务需求,经过研发团队的探讨,我决定采用微服务架构来对项目进行改造。
微服务,顾名思义,就是将原应用程序拆分成一个个细粒度的服务,服务单独部署,服务之间通过标准的API接口进行相互通信。与单体架构相比较,微服务架构具有以下特点:
(1)通过服务实现组件化。由于单个微服务实现简单,能够聚焦于一个指定的业务功能或业务需求,每个服务对外提供统一的轻量级REST接口,实现组件化。
(2)功能明确,易于理解。微服务更容易被开发人员理解、修改和维护,这样小团队能够更关注自己的工作成果,降低沟通成本。
(3)围绕业务功能构件开发团队。采用微服务架构,围绕业务功能来构件开发团队,这样更符合企业的分工与组织结构,便于管理,避免出现一个开发团队负责维护多个系统服务的情况。
(4)支持多种开发语言与多种平台。不同的微服务能使用不同的语言进行开发,运行在不同的操作系统平台上,服务之间通过标准的REST接口和统一的轻量级JSON数据格式进行交互与协作。
(5)离散化数据管理。在微服务架构中,无法创建或维护统一的数据模型或结构,全局数据模型将在不同的系统之间有所区别,需要进行数据模型的离散化管理。
(6)基础设施自动化。微服务强调以灵活的方式集成自动部署,通过CI持续集成工具实现基础设施自动化,所以一般微服务都离不开DevOps。
在决定采用微服务架构之后,第一步要进行的是服务划分。这是一个持续演化的过程,一方面小步快跑、有节奏地对老系统进行服务化拆分,拆分的原则是高内聚低耦合以及保持服务的粗粒度;另外一方面,现有的技术团队当时比较缺乏微服务的实践经验,还需要一定的时间去适应一套新的技术架构。综合这两个因素,我首先选择了一个最简单的群组管理模块来实现微服务,并新建了一个单独的Git分支,进行独立的代码管理,而不是在原有系统分支上进行克隆改造,避免受到原有代码的影响。
第二步是组建微服务团队。高效的微服务团队需要是一个全栈的团队,跨职能的团队,应该包含整个项目周期的所有技能,前后端开发、UI设计、测试、构建部署、上线与运维都是必须技能。也就是说,微服务团队除了熟练的业务逻辑开发之外,还需要有DevOps能力、服务的快速构建、良好的团队文化等等。所以在这一步,我从其他团队中调配了一名熟悉DevOps工程师过来,搭建Jenkins,集成Gitlab,Sonarqube,实现代码的自检、应用的自动化构建和自动化部署。另外,也从原有开发团队抽出相应的前后端开发人员、UI以及测试人员,建立一个独立于原系统的开发团队,即实现了一个团队维护两套系统到两个团队维护两个系统的转变。
第三步是技术栈选型。原项目使用的是Java技术体系的SpringMVC架构,鉴于开发效率、团队开发人员的语言熟悉度、部署方便等因素,最终我改用Go语言进行重写,选择Go-micro微服务框架。运行时支撑服务选型方面,服务注册和配置中心选择使用在 Kubernates 经过大规模生产验证的 Etcd;服务网关选择的是Gin框架。服务监控方面,主要包括日志监控,调用链监控,Metrics 监控,健康检查和告警通知等产品。日志监控采用ELK(Elasticsearch+Logstash+Kibana),调用链监控业内比较流行的Jaeger。服务容错方面,采用Hystrix,把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix 的 Command 之内,封装后自动具备容错能力。
第四步是改造实现。首先针对原来的群组管理模块进行分析整理,抽取一些可以复用的设计,达到资源的最大利用。由于群组管理模块相对比较独立,与其他模块的耦合依赖较少,所以对原系统的改造也比较少。最终,经过两个星期的改造,群组管理模块的所有功能成功迁移到微服务架构中。
完成了第一个微服务的迁移之后,我利用Nginx进行灰度发布,不断地进行迭代演化,逐渐提高微服务的整体占比,最终,消息平台V2.0于2019年1月份成功完成了微服务架构的迁移,原系统的所有服务都有序地整合到对应的微服务中,整个团队也成功实现了微服务转型。
结尾
在整个微服务团队的齐心协力之下,原有的单体系统逐步被改造成了微服务架构,2019年1月,消息平台V2.0正式上线运行,至今已稳定运行了接近2年时间,改造后的系统相比V1.0更灵活、更加可扩展,能快速响应业务方的需求迭代演化,达到了项目的预期目标,获得了领导和同事的认可。但在微服务实践中,我们也遇到些问题,一是运维开销及成本增加,因为每个微服务需独立运行,这将导致资源开销大;第二个问题是难以可视化及全面测试,在动态环境下服务间的交互会产生非常微妙的行为。因此,首先服务划分应尽量合理,控制好“粒度”,不要划分得太细太多;其次,微服务可通过监控发现生产环境的异常,进而快速回滚,弥补可测性不足的问题。这些是我今后在微服务实践中需要注意的问题,我也将在后续的工作实践中不断地学习总结,提高自身素质和能力,带领技术团队为公司提供更高质量的技术服务,为业务保驾护航。