单体到微服务架构的涅槃重生之路?
在技术演进的历史长河中,单体架构曾是众多项目的起点,但随着业务需求日益复杂,微服务架构凭借其灵活性和可扩展性逐渐成为新宠。行业内对此有着激烈的讨论,尤其是互联网大厂和行业技术大佬们对微服务架构的看法颇具影响力。
亚马逊的 CTO Werner Vogels 就曾强调过微服务架构对企业快速迭代的重要性,他认为,构建小型、松散耦合的服务能够提高系统的可靠性和效率。谷歌也倾向于使用微服务架构,这对于他们快速部署新功能和实现全球规模的服务至关重要。
此外,技术界的权威如 Martin Fowler 也对微服务架构持肯定态度,他在多篇文章中详细阐述了微服务架构的优势和实施策略,强调了它在现代软件开发中的适用性。
这些讨论让企业更清楚地认识到,微服务架构能显著增强系统稳定和并发处理能力。尽管存在服务治理和分布式事务等挑战,但互联网大厂的成功案例和技术大佬们的深入分析,都为其他企业转型微服务架构提供了宝贵的经验和信心。
当然,单体架构与微服务架构的辩论不止触及技术的表层,更关乎对未来业务模式和运营效率的深远考量。对于企业而言,选择适合自己的架构,才是重要的。
1 单体架构与微服务架构
1.1 什么是单体架构
单体架构(Monolithic Architecture)是一种将所有功能打包在一个容器中一起运行的一种架构,一个实例中集成了一个系统的所有功能。通过负载均衡软件/设备实现多实例调用。
1、优点
部署简单:由于是完整的结构体,可以直接部署在一个服务器上;
代码统一:组建密集集成,源码通用,代码组织一致;
研发成本低:单一服务和业务聚合,减少人力成本;
技术简单:只需要知道简单的技术栈,即可研发。
2、缺点
维护困难:随着业务量的增加,服务逐步复杂,由于组件高度耦合,开发人员实现业务功能的同时大概率会影响到其它功能;
系统启动慢:业务多、代码模块多,启动周期漫长;
伸缩性差:不能针对业务模块单独扩容,需要对整体服务进行扩容;
故障风险大:单体服务的某个组件出现问题,会导致整个服务不能用;
技术栈僵化:随着新技术迭代出现,单体服务技术风险更大。技术僵化在原地,时间越长,技术漏洞将越来越难以修复。
1.2 什么是微服务架构
微服务架构是一种架构概念,它强调将应用程序的功能分解为多个小的服务,这些服务可以独立开发、管理和部署,每个服务运行在自己的进程中,并通过轻量级的通信机制如 REST API 进行交互。微服务架构的核心在于解耦,它通过减少服务之间的依赖和耦合,提高了系统的灵活性和可扩展性。
1、优点
业务容易实现:服务职责单一,业务逻辑单一,代码量少,便于代码管理和迭代开发;
服务独立:每个服务都采用独立的技术栈进行开发,使得部署更新可以针对单个服务进行,从而降低整体风险并提高系统的灵活性和可维护性;
可扩展性:微服务架构允许根据业务需求灵活地增减资源应对负载变化。单个应用变更时,只需要重新部署,保持服务颗粒度隔离,即可确保系统即使发生局部故障也可继续运行;
技术栈灵活:每个服务可以有独立的技术栈,每个服务都可以独立更新对应的技术栈,从而不断升级技术栈提高服务质量。
2、缺点
复杂度增加:微服务架构可将一个系统拆分为多个独立的服务,这增加了额外的复杂度。例如,需管理分布式数据的一致性,且需处理服务间的通讯问题;
成本高:服务越多,运维要求越高,投入资源越多,成本越高。
通过上述内容,我们对单体架构和微服务架构的概念及两者之间的差异有了一个整体的了解。接下来,我们将探讨如何在实际项目实践中将单体项目拆分为微服务架构。
2 充电桩拆分前项目剖析
我们已经掌握了单体架构与微服务架构的差异,接下来我们将在最新的充电桩项目中实际操作,将传统的单体应用进行拆分,实施微服务架构。
在开始一个项目时,首先需要对项目进行定位,明确其架构类型,并评估其是否能够支持高并发、高性能和高可用性,同时考虑它是否能适应未来的业务发展需求。
充电桩项目是一个外采项目,它是一个十分典型的单体项目,服务有状态而且手动单机部署,且服务不能高并发、高可用与高性能。现有架构只能满足当时的现有设备,在未来 10 倍业务量倍增下,现有的架构明显不能满足这些需求。
为了应对未来三年 10 倍业务量倍增的挑战,并确保服务的高并发、高性能和高可用性,微服务的可扩展性高、服务高独立、职责单一,并且技术栈灵活,便于升级与维护。因此,微服务架构成为了首/选。
在选择未来架构后,首先需要考虑从单体架构迁移到微服务架构过程中可能遇到的以下障碍:
技术栈较老旧:无法更新到最/新/技术栈,无法适配 spring cloud/云原生微服务架构;
服务有状态:服务访问负载固定 IP Hash 访问指定一台机器,可以用性十分差;
前后端不分离:前端代码和后端代码紧密耦合,不易重用。页面响应慢,用户体验差,不易维护;
可维护性差:代码耦合模块,修改一个模块会导致其他模块发生意想不到的变化,从而增加了维护成本;
可扩展性差:模块之间过于依赖,不容易扩展功能;
可重用性差:高耦合的模块不容易在其他系统中重用;
可测试性差:测试一个模块需要依赖其他模块,增加测试难度;
部署架构不灵活:需要手动部署,停机时间长,且可用性差。
要实现充电桩项目微服务化,就必须解决以上阻碍。
3 充电桩拆分微服务架构步骤
3.1 单体服务实现无状态
单体服务实现无状态
我们为什么要将服务去状态?服务有状态对系统会造成哪些影响?我们先来分析一下服务有状态有哪些缺点:
1、状态管理问题:每个服务实例可能需要维护自己的状态,这会导致大量的内存占用和管理成本;
2、扩展性问题:有状态服务不易于进行水平扩展,因为扩展实例时,它们将失去之前的状态,并且需要合理地管理状态迁移;
3、高可用性问题:如果服务实例失败,有状态服务可能需要额外的机制来保证状态的高可用性;
4、数据一致性问题:在分布式系统中,多个实例同时访问和修改同一状态时,可能会出现数据一致性问题;
5、性能问题:有状态服务可能需要更多资源来处理本地的状态,这可能会影响性能。
从上述单体服务有状态缺陷性分析,我们可以看出,服务有状态是实现服务高并发、高性能和高可用目标的障碍。因此,接下来,我们将重点探讨服务无状态的分析和设计。
3.2 充电桩单体服务有状态架构图
当用户 A 的 IP 固定哈希到主机 A 后,那么它后面的流量都会一直流向主机 A,而不会流向主机 B。用户 A 的所有请求校验信息都存储在 session 中,用户 B 同理。这样一来,如果有某台服务器发生故障,那么所有依赖该服务器的用户都会无法访问资源,降低了系统的可用性。具体见下图所示:
与服务有状态相比,服务无状态的主要优势在于它们能够轻松地实现高可伸缩性和高可用性。无状态服务不需要保存会话状态,因此不会成为系统的瓶颈。当请求分布在多个无状态服务实例之间时,每个实例只需处理它接收到的请求,不需要共享任何内部状态。
3.3 无状态实现步骤
无状态是指一个系统或者组件不存储关于先前交互的信息或者状态。
微服务架构设计中的一个核心原则就是服务无状态化。微服务处理每个请求时不会依赖于会话信息或者状态,无需考虑之前的交互逻辑。服务无状态的目的是简化请求处理、服务部署、服务伸缩、服务容错、资源优化或者服务状态恢复和同步等。
如何实现无状态?其实现步骤如下:
1、状态分离:将状态从服务中分离出来,并将其存储在外部系统中,如数据库或分布式缓存,服务脱离状态管理。
2、网络请求管理状态:通过请求(API 请求参数、http 请求头及 cookie 等)传递状态信息,以保证请求执行所需要的参数。
3、使用消息队列:将请求封装到消息队列,通过消息队列通讯实现服务无状态化。
综合来说,服务无状态化是实现高可用、可伸缩和易于管理的分布式系统的关键因素。
3.4 充电桩单体服务无状态架构图
在无状态时,用户 A 和用户 B 可以正常地通过 Webview 进行访问。由于系统设计中包括对两台轮服务器的轮询机制,即使其中一台服务器出现故障,请求可以被另一台服务器处理,保障了系统的正常运行和高可用性。具体见下图所示:
3.5 电桩单体服务前后端分离无状态架构图
在无状态实现完成后,可以逐步将 JSP 页面迁移到 Vue 前端服务中,并通过 Nginx 实现转发。具体见下图所示:
3.6 充电桩微服务前后端完全分离态架构图
4 充电桩项目实践拆分
4.1 单体架构充电桩项目架构
从上图的架构图可以看出,所有的服务都依赖于 center 服务。center 是一个功能混杂的服务,没有具体的功能划分。一旦 center 服务故障,将导致整个服务无法正常工作。
4.2 单体架构拆分步骤
断开 gateway tcp 和 gateway ssl 对 center 的直接依赖,所有的调用应该通过 MQ 来实现。
center 主要提供三个功能:小程序访问功能、主营数据消费功能及设备消费的功能。为了提高系统性能和降低故障分析,可以将 center 功能拆分为主数据 kafka 消费、设备服务与小程序服务这三个模块。
将 webview/管理系统单独拆分为微服务,解除其对 center 的依赖。
将 frontview/管理系统单独拆分为微服务,解除其对 center 的依赖。
我们从单体架构开始,逐步将其核心功能模块转化为微服务架构。具体而言,是在保留 center 的三大功能——小程序访问、主营数据消费以及设备消费功能的基础上,我们将网关、webview 和 frontview 从对 center 的依赖中解耦,使它们演变为独立的微服务架构。
通过这种转变,center 避免了直接处理服务调用,实现了与其他服务的完全分离。这导致 center 不再直接管理流量的进出,从而显著减少了系统的复杂性及可能的故障源,增强了系统的维护性和可靠性。
4.3 微服务架构领域划分
在拆分服务边界和职责之前,通常会设置一些基础服务,包括用户服务、工单服务、订单服务、支付服务、任务调度服务、设备服务及数据总线消费微服。基于这些基础服务,我们进一步定义了上层服务,如公众号服务、小程序服务与后台管理系统服务等。最后,为了支持第三方业务整合,我们还提供了第三方业务支撑服务,以实现与外部系统的无缝对接和数据交换。
5 总结
在将单体架构拆分成微服务架构的过程中,我们从这两种架构的基本概念出发,详尽探讨了拆分过程中可能遇到的障碍及具体的拆分步骤,并分享了充电桩项目实践经验。对此,我们总结出以下关键点:
将单体架构拆分成微服务架构的核心是服务无状态、前后端逐步分离和流量切分;
解耦单体服务到职责单一的多元服务是服务“三高”(高并发、高性能和高可用)可用的关键;
技术栈的不断迭代升级是维持微服务架构活力的血液,分布式数据管理和监控是维持微服务架构监控的保障,而统一规范的 RPC 通信协议则是微服务调度通信的质量基准。
本文作者:
王志坚:碧桂园服务 JAVA 开发专家
指导人:
毛卓:碧桂园服务技术总监
刘刚:碧桂园服务架构师
版权声明: 本文为 InfoQ 作者【智在碧得】的原创文章。
原文链接:【http://xie.infoq.cn/article/52140dbed86eb2b874d7936b1】。文章转载请联系作者。
评论