经验教训:微服务设计时的五条宝贵经验

news2024/11/28 17:55:35

微服务架构的新挑战

在著名软件著作《人月神话》中提到,软件世界没有“银弹”,这句话当然适用于架构领域,随着从单体架构过渡到微服务架构,因为将原有系统打散,给系统增加了许多不稳定因素。

image-20230609102803122

单体架构向微服务架构转变

下面我从网络、性能、运维成本、组织架构与集成测试五个方面分别进行阐述。

第一点,跨进程通信带来的新问题。 以往单体应用是在单机中进行进程内通信,通信稳定性相当好。但是打散为分布式系统后,变为进程间通信,往往这个过程还伴随着跨设备的网络访问,架构师在设计时必须考虑上下游系统因为网络因素无法通信的情况,要假设网络是不可靠的,并设计微服务在网络异常时也能进行符合预期的异常处理。以支付模块为例,用户支付成功后系统自动调用短信服务向用户手机发送“订单支付成功”的消息,此时架构师就必须假设短信服务在服务或者网络不可用时不会影响到订单业务的正常执行。

image-20230609102818132

微服务间跨进程RESTful调用

第二点,较高的响应延迟。 相比传统单体架构进程内通信,跨进程、跨网络的微服务通信在网络传输与消息序列化带来的延迟是不可被忽略的,尤其是在五个以上微服务间消息调用时,网络延迟对于实时系统的影响是很大的。早些年我和军事院校合作了一个雷达仿真训练的系统,因为要模拟“导弹打飞机”的场景,在计算飞行轨道时1毫秒的响应增加都可以会影响到最终的结果,显然这类系统采用分布式设计就不再合适。

image-20230609102838503

雷达指挥训练系统流程

第三点,运维成本会直线上升。 早期单体应用因为结构简单,规模也较小,发版时通常面对几台服务器部署几个Jar/War文件就可以了。同时,应用的交付周期也是以周甚至月为单位,此时硬件设备成本与运维人员技术要求都比较低,采用手动部署即可满足要求。而对于微服务架构而言,每一个服务都是可独立运行、独立部署、独立维护的业务单元,再加上互联网时代用户需求的不断变化以及市场的不稳定因素,运维人员每天面对成百上千台服务器发布几十次已是家常便饭,传统手动部署显然已经无法满足互联网的快速变化。

image-20230609102850310

京东 JDOS 自动化运维架构图

第四点,组织架构层面的调整。 微服务不但是一种架构风格,同样也是一种软件组织模型,以往软件公司会以职能划分研发、测试、运维部门进行独立管理考核,而在微服务的实施过程中,是以业务模块进行团队划分,每一个团队是内聚的,要求可以独立完成从调研到发版的全流程,尽量减少对外界的依赖。如何将传统的职能团队调整为按业务划分的研发团队,同样是对管理者的巨大挑战,要知道人的思想比架构更难改变。

image-20230609102909580

独立的全生命周期研发团队

第五点,服务间的集成测试变得举步维艰。 传统单体架构集成测试是将不同的模块按业务流程进行组合,在进程内验证每一种可能性下其模块间协作是否符合预期即可。但对于微服务而言,系统被拆解为很多独立运行的单元,服务间采用接口进行网络通信。要获取准确的测试结果,必须搭建完整的微服务环境,光这一项就需要花费大量的人力物力。同时,因为微服务是跨网络通信,网络延迟、超时、带宽、数据量等因素都将影响最终结果,测试结果易产生偏差。

微服务最佳实践

刚刚我们总结了引入微服务架构的一些新挑战,下面我将结合自己多年的微服务落地经验,总结出五点微服务架构最佳实践,希望能对你日后的工作提供帮助。

第一点,微服务的划分原则

将已有系统拆分为多个微服务,本就没有统一的标准。举个例子,一个初创电商公司,要开发一套电商系统,将“促销活动”单独剥离出来作为“促销服务”是没有问题的。但是如果在“淘宝”“京东”这种体量的电商平台,“促销服务”就显得粒度太粗了。可以继续拆解为“价格服务”“优惠券服务”“京豆服务”等更细粒度的小服务,每个服务有专门团队负责维护。

image-20230609102933198

京东商城的微服务业务划分

因此,在微服务拆分过程中,我们通常会从业务场景、团队能力、组织架构等多种因素综合考虑,这特别考验架构师的业务能力。一般来说,我们总结出几点通用原则:

  • 单一职责原则。 每一个微服务只做好一件事,体现出“高内聚、低耦合”,尽量减少对外界环境的依赖。比如,在公司创业之初,完全可将订单与仓储服务进行合并。因为订单与仓储在业务与数据上紧密相关,如果强行拆分会导致出现跨进程通信带来的数据一致性难题。随着业务的发展,仓储的业务职责扩展,派生出许多与订单无紧密联系的功能,到时再将其剥离形成独立的“仓储服务”。

  • 服务依赖原则。 避免服务间的循环引用,在设计时就要对服务进行分级,区分核心服务与非核心服务。比如订单服务与短信服务,显然短信服务是非核心服务,服务间调用要遵循“核心服务”到“非核心服务”的方向,不允许出现反向调用。同时,对于核心服务要做好保护,避免非核心服务出现问题影响核心服务的正常运行。

  • Two Pizza Team原则。 就是说让团队保持在两个比萨能让队员吃饱的小规模的概念。团队要小到让每个成员都能做出显著的贡献,并且相互依赖,有共同目标,以及统一的成功标准。一个微服务团队应涵盖从设计到发布运维的完整生命周期,使团队内部便可以解决大部分任务,从人数上4~6人是比较理想的规模。

第二点,为每一个微服务模块明确使命。

这里推荐一套标准的微服务叙述模板,集中体现“只做好一件事”的原则。

模板
XX 微服务用来
在出现痛点场景的情况下
解决现有的 XX 问题
从而达到了 XXX 的效果
体现了微服务的价值
示例
商品检索微服务用来
在商品数据全量多维度组合查询的情况下
解决了 MySQL 数据库全表扫描查询慢的问题
从而让查询响应降低到 50ms 以下
有效提升了用户体验

通过这种描述,服务的职责与边界就十分明确,团队便以此为目标确认职责。

在实施过程中因为我们是以解决问题为目标,切分时可能会比较细碎。经过漫长时间沉淀,系统中出现了类似于“商品检索服务”“订单检索服务”“商铺检索服务”等多个小服务,这时可以对这些服务形成聚合生成新的“通用检索服务”,以此来控制微服务的整体规模。反之,对于庞大的服务,可以考虑拆分为多个小服务进行细粒度的管理。总之,拆与合是伴随着公司业务的演进而变化的,一切以解决问题为准。

第三点,微服务确保独立的数据存储。

数据是任何系统最重要的资产。以往单体应用通常会选择 MySQL 这种关系型数据库作为数据的唯一存储,这样做的好处是涉及多表操作时,利用数据库自带的事务机制便可最大程度保证数据完整性。但这样做却存在诸多问题,以下图为例,不同的微服务对数据存储的需求也是不同的,订单服务需要 MySQL 数据保存订单与订单明细;新闻服务需要Elasticsearch提供全文检索支持;朋友圈需要图数据库表达现实世界人际关系;文件存储服务则需要分布式文件系统。如果将所有数据都揉在 MySQL 中使用会变得十分蹩脚,好的做法是为每一个微服务提供符合自身业务特性的数据库。图片7.png

独立的数据存储

但理想很丰满现实很骨感,在分库后涉及跨库操作会变的难以处理。比如,订单依赖会员数据,原本单库处理时一条 SQL 语句便可实现。

SELECT order.* , member.* FROM order,member WHERE order.member_id = member.member_id

但在微服务架构下,因为数据库绝不允许其他团队访问,关联查询只能变为 API 调用形式,程序实现层面比单库复杂不少。

image-20230609103047527

通过 RESTful 通信实现数据关联

与之类似,如果涉及多表写入时一致性问题更复杂。

BEGIN ;
写入表A;
写入表B;
COMMIT;

在拆分为服务后,数据被分散到多库,为保证异构多库的数据一致性是所有分布式应用的巨大挑战,至今没有完美的解决方案,这块内容我在后面课程单独做一个专题进行讲解。

第四点,服务间通信优先采用聚合器模式。

在微服务间通信时存在两种消息传递模式:链式模式聚合器模式。下图所展示的是链式模式,请求按业务流程在各个服务间流转,最终处理完成返回客户端。

image-20230609103058524

链式模式

因为请求是按业务流程传递,很容易能被开发人员理解,链式模式成为最常用的服务间通信模式。但链式模式采用串联模式,调用的整体成功率等于单个服务成功率的乘积,假设每个服务可靠性为 90%,一个业务在 4 个服务执行后的最终成功率只有 90%*90%*90%*90%≈66%,有将近一半的请求会处理失败,这是无法接受的。此外,链式模式因默认采用同步方式传输,在服务处理完成前应用会一直处于阻塞状态,当调用链较长时,系统整体性能会严重下滑。

聚合器模式则是通过服务作为入口,组装其他服务的调用。以下图为例,因为“订单流程服务”是将其他服务进行聚合操作,所以称其为聚合器模式。以“订单流程服务”为例,将“订单”“支付”“库存”服务进行聚合,一个服务实现了下单、支付、减库存的完整流程。

image-20230609103129747

聚合器模式

采用聚合器模式后,业务流程与编排集中在“订单流程服务”中,可对整体业务进行有效编排,支付与扣库存可以并行调用,可以有效提高系统的性能。

第五点,不要强行“微服务”化。

在以前公司任职时因为业务需要,要开发一个工单系统让售后人员在线为客户提供售后服务,但当时因为公司产品已经非常成熟,每天产生的工单只有几十笔,如果做成单体应用配合 Nginx 反向代理,从存储到应用便能满足需求。此任务分配给一位“年轻”的架构师,可能是为了证明实力,他采用了全套微服务技术来“炫技”,并在会议上侃侃而谈。结果老板反问他“你这么设计有必要么,为一个工单系统投入超过10台服务器成本你考虑了吗?” ,当时那场景别提多尴尬了。

其实在我看来,微服务也不过是一种方案,没必要盲从。它也没有违背架构的基本规律:架构是解决当前需求和痛点而演进的。在满足需要的前提下,选择合适的而不是选择最好的,合理降低成本才是好架构师该考虑的事情。以上微服务的经验都是我在实际工作中总结归纳出来的,如有不足的地方欢迎同学们在评论中给予补充。

微服务架构的适用场景

本节最后一部分,我总结了适合微服务使用场景,首先咱们梳理下适合做微服务的场景:

  • 新规划的大型业务系统, 这肯定是最适合引入微服务架构的情况了, 微服务强调“高内聚,低耦合”,每一个团队负责一个服务,这就意味着从根本上和传统的整体性应用有本质不同,从规划阶段采用微服务架构是再好不过的。

  • 敏捷的小团队系统,公司在大型项目微服务实践前,往往这类边缘化的小项目会起到“试验田”的作用, 引入快速迭代、持续交付等模式,积累适合本公司特点的微服务实践经验,再将这些经验扩大到其他大型项目中。

  • 历史的大型留存业务系统,之前多年我一直在金融软件领域工作,在银行内部许多系统已经使用超过10年时间,成百上千个模块错综复杂维护愈发困难,无论架构、框架乃至技术人员都需要更新迭代,但都不可能一次大动手术,这时微服务的“微”就体现出来,重构时可以将某一个部分剥离为微服务独立运行,确保无误后再继续剥离出下一个服务,通过抽丝剥茧一般的剥离,逐步将原有大系统剥离为若干子服务,虽然过程十分痛苦,但这是必须做的事情。

下面咱们再来列举几个不适合引入微服务的场景:

  • 微型项目,前面提到的工单系统,系统压力很小,需求变化也不大,利用单体架构便可以很好解决,使用分布式架构反而增加了架构复杂度,让系统更容易不稳定。

  • 对数据响应要求高的系统,就像前面文中提到的“导弹打飞机”的科研项目,对实时性要求极高,那显然是不合适的。

总结

针对引入微服务架构后带来的诸多新问题进行了分析,之后给出了多条微服务架构最佳实践,最后总结了微服务架构的使用场景。

这里给你留一道思考题:微服务架构作为一种设计风格,必须要依托具体的技术与开发框架才可以实施落地,那你能列举出具体包含哪些技术吗?

资料获取👇 最后面就是领取暗号,公众号回复即可!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【服务器数据恢复】断电导致RAID无法找到存储设备的数据恢复案例

服务器数据恢复环境: HP EVA存储,6块SAS硬盘组建的raid5磁盘阵列。上层操作系统是WINDOWS SERVER。该存储为公司内部文件服务器使用。 服务器故障&分析: 在遭遇两次意外断电后,设备重启时raid提示“无法找到存储设备”。管理员…

值得推荐收藏的 9个免费PDF转PPT的方法

随着现在工作和学习越来越多涉及到电子文件,PDF格式已经成为了一种非常重要的文件格式。但有时候需要将PDF文件转换为PPT格式,因为PPT格式更适合用于演示和公开演讲等场合。而转换PDF文件到PPT格式则需要使用专用工具。以下是9个免费的PDF转PPT的方法介绍…

蓝牙耳机都能打电话吗,分享几款通话效果不错的骨传导耳机

骨传导耳机的兴起是近几年来才出现的新概念,骨传导耳机也是近几年来才开始流行起来,在我看来骨传导耳机的兴起是科技进步的产物。随着蓝牙耳机技术和设备的发展,蓝牙耳机也越来越普及,但是也给用户带来了很多困扰。而骨传导耳机就…

好用的电容笔有哪些推荐?性价比高的触控笔

电容笔的选购对新手来说难度很大,看到网友们都在讨论电容笔什么牌子的好用,电容笔怎么挑选?小编今天也来详细解答这个问题,盘点四款好用的平价电容笔,如果你想知道性价比高电容笔推荐哪些,那这篇文章一定不…

什么是 Vue 的片段(Fragment)?如何使用片段?

什么是 Vue 的片段(Fragment)?如何使用片段? 在 Vue 2.6.0 版本中,新增了一个特性:片段(Fragment)。片段是一种特殊的组件,可以让开发者在不增加额外节点的情况下渲染多…

2023年第二届计算与人工智能国际会议(ISCAI 2023)

会议简介 Brief Introduction 2023年第二届计算与人工智能国际会议(ISCAI 2023) 会议时间:2023年10月13 -15日 召开地点:中国上海 大会官网:www.iscai.org 2023年第二届计算与人工智能国际会议(ISCAI 2023)将围绕“计算与人工智能”的最新研究…

ETC人车关系查询-ETC人车关系查询api接口

接口地址: https://登录后显示/api/189/363(支持:http/https)) 接口页面:https://www.wapi.cn/api_detail/189/363.html 网站地址:https://www.wapi.cn 接口简介:核验指定人员/企业是否是指定车辆的 ETC 开户人、车辆所有人或 E…

【c/c++】属于程序员的浪漫,基于easyx.h图形库实现3D Heart

文章目录 😏专栏导读🤖文章导读🙀一、easyX图形库基本介绍?1、easyX的原理:2、easyX的安装🙀3D Heat源码描述 😳3D Heat效果展示总结 😏专栏导读 👻作者简介:…

ssm+java汽车销售分析与管理系统

此次设计一款汽车销售分析与管理系统,能够对当前销售的车辆的日销售、季度销售以及年度销售进行统计分析、对于车辆的入库出库进行了准确的信息录入。对于销售人员的销售情况进行登记和统计,能够对整个店面的财务情况、盈利情况进行统计。同时对于以上数…

精选|Dubbo异步化实践

1 背景 从Apach Dubbo的官网了解到从 2.7.0 版本开始,Dubbo 的所有异步编程接口开始以CompletableFuture为基础,Dubbo接口异步化能够极大地提高接口性能,降低接口依赖调用之间的阻塞,同时了解到我们公司大部分应用使用的是同步rp…

微信小程序 地图map组件 SDK 并 实现导航

说明 本文使用uniapp使用map组件作为示例 效果预览 主要实现: 地图上搜索关键字地址对地址设置标记点位置授权被拒后,重新触发授权的处理逻辑实现获取当前位置,计算目标地址与当前位置的距离触发对选中的信息展示弹窗实现开始导航操作 需要源…

无人机航拍高度与地面采样距离

无人机航拍高度与地面采样距离 1.无人机航拍高度与地面采样距离的关系 为搞清无人机航拍高度与地面采样距离的关系,首先需要了解像素与像元之间的细小差别(个人理解)。像素偏重于图片描述,也就是常说的一张图片像素是多少。像元…

谷粒商城学习笔记(一):分布式基础概念

分布式基础概念 1. 微服务2. 集群&分布式&节点3. 远程调用4. 负载均衡5. 服务注册/发现&注册中心6. 配置中心7. 服务熔断&服务降级8. API网关 1. 微服务 微服务架构风格,就是把一个单体架构按照业务拆分成多个服务模块,每个模块之间独立…

C标准库——字符串函数反汇编分析

1、前置概念补充 test:逻辑与,如果是1,zf就是1,如果是0,zf就是0 可以还原成等价的高级语言,理解代码逻辑,但是不一定是源代码 大写的A:41,小写a:61 asci…

manacher——马拉车算法(图文详解)

文章目录 简要介绍实际应用算法详解 简要介绍 马拉车算法,Manacher‘s Algorithm 是用来查找一个字符串的最长回文子串的线性方法,是一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性O(N)。 实际应用 刷…

ChatGPT让沟通更智能、更便捷

ChatGpt是最近引起强烈关注的一种技术,它可以实现聊天机器人,为使用者解决复杂的信息获取和学习任务。但他也不仅仅是一个聊天机器人,它是一种基于深度学习算法的自然语言生成模型,由OpenAI公司开发。它可以模拟人类的对话方式&am…

AICG - Stable Diffusion 学习思考踩坑实录(待续补充)

关于模型 如果模型中没有各种角度的脚和手,无论你再怎么费劲心思,AI 都画不出来,目前C 站也没有什么好脚的例子,正面脚背面脚,但是没有侧面脚,脚这块还是很欠缺,希望未来有大牛能训练出来美脚 …

Python头歌合集(题集附解)

目录 一、Python初识-基本语法 第1关:Hello Python! 第2关:我想看世界 第3关:学好Python 第4关:根据圆的半径计算周长和面积 第5关:货币转换 二、turtle简单绘图 第1关:英寸与厘米转换 第2关&#xff1…

【MySQL数据库 | 第十篇】DCL操作

目录 🤔 前言: 🤔DCL介绍: 🤔1.DCL管理用户: 1.查询用户: 图示: 2.创建用户 示例1: 运行结果:​ 示例2: 运行结果:​ 3.修改…

基于html+css的图展示116

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…