老司机的微服务架构实现,照亮你的人生 | 朱攀

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 微服务系统本质上是一个分布式系统,而分布式系统就有其固有的复杂性,对测试,部署甚至团队的组织结构都会带来很大挑战。有了这些微服务架构的基础设施,能有效帮我们解决并规避一些问题,但我们仍然不能低估采用微服务架构带来的复杂性。微服务架构不是银弹,更不是免费的午餐,实施微服务改造是要付出代价的。

编者按:前2月,向朱攀兄弟约稿,畅聊甚欢,引为知己。今刊发以飨读者!

微服务为当今群雄混战局面,从dubbo问世数载,然业界尚未有完整打包结局方案,前有小剑之《老司机带你玩PPmoney微服务》,德比软件作为前驱,集数年研究与实战,搭建平台,填埋深坑,则业界之幸!


适逢1024程序员节,一并祝各位程序猿/媛节日快乐,早日步入老司机行列


前言

微服务概念被提出来后,短时间内就成了当前互联⽹圈的⼀个技术热点,有很多互联⽹公司计划或正在进⾏微服务化改造,那么,实施微服务我们应该怎么开始呢?需要哪些基础设施来⽀持呢?我所在的公司德⽐软件从 2009 年就开始采⽤⾯向服务架构( SOA) 来重新实现数据对接平台,我们积累了丰富的⾯相服务架构的经验,⽽微服务架构是⾯向服务架构思想的⼀种实现,只是服务职责更单⼀,粒度更⼩,过程更⾃动化。我们在多年的服务化架构实践过程中,已经不⾃觉的将服务的粒度细化了。本⽂想分享德⽐软件在实施微服务架构过程中积累的⼀些基础设施以及这些基础解决的痛点问题,希望对⼤家有所帮助和启发。

德比软件数据对接平台总体架构


数据对接平台的架构⼤体上分三个层次,最外⾯是 API 层,由 API Gateway 和各业务的 API 服务组成,中间层是服务层,平台的⼤部分的功能在这层实现,服务之间通过依赖或组合,可以组成功能更强的服务,最底层是存储层服务,由缓存层和存储层组成。
数据对接平台采⽤微服务架构,为了⽀撑这个架构,我们提供了必要的基础设施来保障上层各个服务和应⽤的可⽤性。

德比软件微服务架构基础设施


基础设施全景图


如图所示,我将我们的基础设施分为了⼋⼤部分,分别是服务框架、基础服务、 API ⽹关、⾃动化、服务降级、监控报警、⽇志处理和调⽤链追踪。其中服务框架、基础服务、 API ⽹关和服务降级是为了提⾼服务的连续⼯作时间;⾃动化为了简化开发和部署过程;监控报警、⽇志处理和调⽤链追踪是为了快速发现问题,定位问题并解决问题。

API 网关 DGateway

API ⽹关是微服务架构中⼀个不可或缺的部分。 API ⽹关是对外提供的服务,是系统的⼊⼝,所有的外部系统接⼊系统都需要通过 API ⽹关, DGateway 提供安全认证、流控、路由、 API 版本管理等功能。流控维度分⽤户类型、⽤户来源、 IP、业务 API 等,保护服务或资源不被滥⽤或攻击。
DGateway 基于开源软件 Tyk 做了⼆次开发。

服务框架

服务框架分两部分,高可用的 RPC(Derbysoft-RPC)和服务依赖管理。


高可用 RPC

RPC 是微服务架构最重要的基础组件 ,⼀个鲁棒的 RPC 能有效降低实施微服务架构的成本,RPC 封装了远程调⽤的复杂细节,让服务使⽤⽅感觉像调⽤本地⽅法⼀样调⽤远程⽅法,服务提供⽅感觉像实现本地接⼝⼀样来实现服务。 DerbySoft-RPC 分为 Client 和 Server 两部分。

Client 主要有以下功能:

  1. 客户端故障检测,识别并标示太慢或崩溃了的服务器器;

  2. 熔断机制,如果发现服务超时比例过限,启动熔断,客户端快速失败返回,减轻服务端的压力,定时允许部分请求通过,根据请求返回的健康程度来决定是否恢复熔断;

  3. 负载均衡策略,通过记录到每个节点的未完成请求数来决定下一个请求发到哪里;

  4. 容错机制,对某些错误自动重试,比如连接的服务节点不可用的时候可以自动将请求再次发送到其他节点,可定义重试次数;

  5. 序列化和反序列化,选择序列化工具最重要的考量点有:性能,多语言支持、序列化后的消息大小、是否向前兼容等。我们尝试过各种序列化工具,Protocol Buffer在性能和空间占用上都表现优异,是我们用的最多的序列列化工具;

  6. 敏感数据加密,比如信用卡等敏敏感信息,需要在 Client 端加密传输。

  7. 超时管理,可设定每个请求的超时时间。

Server 部分相对简单,主要提供超时管理,序列化和反序列化,敏感信息解密,队列管理、线程管理等功能。

刚才提到序列化⼯具选择的时候需要考虑是否⽀持多语⾔,这个很重要, RPC 最好能多语⾔实现,这样能让技术团队突破编程语⾔限制,技术栈更丰富灵活。在这个上⾯我们是被坑过的,公司早期的时候,⼤概是 2009 年,当时因为业务量不⼤,当时主要⽤ Java,第⼀个 RPC 版本为了⽅便我们采⽤了 Java 序列化机制,导致后⾯想换编程语⾔的时候⼤受限制,为此我们做了第⼆版RPC,将序列化机制换掉,为了兼容第⼀个版本,我们采⽤ Java 的字节序⼀直到现在。⽬前我们的DerbySoft-RPC 是第三版了,实现了 Golang、 Scala 和 Java 三个版本。原则上我们不限制服务的实现语⾔,只要能按要求实现服务接⼝并满⾜性能要求就⾏。微服务化后有个好处就是根本不担⼼你⽤⼩众编程语⾔,如果每个服务的粒度⾜够⼩,最坏的情况就是如果没⼈能维护这个⼩众语⾔的服务,花点时间⽤熟悉的语⾔重写了。

服务依赖管理

微服务化之后,系统⾯临的⼀个突出问题是服务虽⼩,但是数量极多,如果这些服务全部在⼀个可⽤区内,服务之间的依赖还⽐较好管理,可以做服务⾃动注册和发现来实现依赖管理,但是如果服务分布在很多可⽤区域,尤其是跨国跨地区的可⽤区之间的依赖和调⽤,管理起来就⽐较麻烦。
另外,跨可⽤区服务之间的调⽤还需要考虑通讯安全的问题,我们每个服务开不同的特殊端⼝,如果服务跨区域调⽤,访问权限配置也是⼀件麻烦的事情。

下面是众多服务的依赖图示例


上⾯的服务依赖是不是很乱?我们的服务节点分布在全球 14 个可⽤区⾥,⼤部分在 AWS 上,⼩部分在⾃建的私有云⾥,可⽤区之间的服务有复杂的依赖关系。为了解决这种情况下服务之间的依赖调⽤问题、 API 安全问题和服务的⾼可⽤问题,我们设计开发了路由服务,解耦服务的调⽤者和提供者,简化⽹络拓扑图,简化服务器的安全配置。引⼊路由之后,服务之间的依赖关系简化为如下图所示:

所有的服务只和路由通讯,服务之间不再相互依赖,每个服务只需要依赖并维护⾃⼰所在的可⽤区的路由节点,路由会找到调⽤的服务⽬的地,绝⼤部分情况下,它在本区域内就能找到相应的服务,不需要跨区,这取决于服务的部署情况,关键的服务为了提⾼响应速度,每个可⽤区都需要部署,这种情况除⾮本可⽤区的服务挂了,否则不会出现跨区访问;有些服务不是那么重要,可能只会在某个或某⼏个可⽤区部署,这时候就也可能会出现服务跨可⽤区调⽤。同时也解决了 API 访问安全问题:每个可⽤区建⽴⼀个 VPC,所有的服务都在 VPC 内, VPC 内的 API 调⽤可忽略安全验证,跨 VPC 路由节点之间⽤安全组来限制 IP ⽩名单访问,只允许路由节点可以跨可⽤区访问其    他 VPC 内的路由节点,服务访问路由或者路由访问服务都必须在同⼀个 VPC ⽤内⽹地址访问。

基础服务


基础服务分四部分,分别是配置中心,安全数据服务,数据存储服务,订单服务。基础服务大多和存储有关,提供高性能高可用的服务。

配置中心
配置中⼼是⾼可⽤的配置数据存储服务,⼏乎所有的服务都依赖配置中⼼,配置中⼼主要解决基础数据和配置数据的单点依赖问题,更好的⽀持各个服务的⽔平扩展和迁移。配置中⼼分服务端和客户端,服务端提供⾼可⽤的配置数据存储服务,可以在服务端配置主键、索引字段、唯⼀约束,每个字段的类型约束等,功能类似数据库,开放全量和变量的同步接⼝;客户端同步全量或变量数据,根据服务端的配置,在内存中建数据索引,缓存数据,并在本地⽂件中持久化缓存的备份。
⼀个依赖配置中⼼的服务,启动的时候,会先查找本地⽂件中有没有配置数据的缓存,如果有,从⽂件中加载配置数据到内存中,启动服务,接着调⽤变量接⼝对⽐本地数据和配置中⼼的数据是否是同⼀版本,如果数据有变化,则更新数据到本地缓存。如果本地⽂件中没有配置数据的缓存,则先调⽤⼀次全量接⼝缓存所有配置数据到本地缓存。最坏的情况是配置中⼼的所有节点都挂掉,也不影响各个依赖它的服务现有节点的正常⼯作。
因为每个服务都会缓存依赖的配置数据,所以对配置中⼼的性能要求不是太⾼,我们⽤ AWSRDS 解决配置数据存储的⾼可⽤问题, AWS RDS 是⼀个托管关系数据库服务。

安全数据服务

⾼可⽤的安全数据服务,提供数据加密和解密服务,定时清理过期的数据,解决敏感数据的安全临时存储和传输问题,⽐如银⾏卡和信⽤卡信息的临时存储和传输。需要传输敏感信息的时候,在数据传输⽅调⽤数据加密服务的加密接⼝并明确信息有效时间,加密服务会将信息加密后存储,并返回⼀个全局唯⼀ ID,数据传输⽅发送这个唯⼀ ID 给数据接收⽅,如果数据接收⽅收到这个 ID
之后,调⽤数据解密接⼝,加密服务会根据 ID 找到相应的数据,返回解密之后的数据。

数据存储服务

DStorage ⾼可⽤的酒店动态数据存储服务,解决酒店海量动态数据存储问题,提供⾼性能的数据存取接⼝,提供变量数据的同步接⼝。根据性能和容量需求,⽤户可选的存储引擎有: Redis,Codis, Ardb, DynamoDB 等。 DStorage ⽀持多可⽤区部署,通过变化发现服务实现多可⽤区的数据同步,保证数据最终⼀致性。
DContent ⾼可⽤的酒店静态数据缓存服务,解决酒店海量静态数据的缓存问题。底层⽀持的存储引擎: Ardb、 Redis 等。 DContent ⽀持⼀主多从多可⽤区部署,也⽀持多主多可⽤区部署,保证数据最终⼀致性。
AWS S3,⾼可⽤的⽂件存储服务,存储⽂件数据,如:图⽚,视频,⽇志⽂件,备份数据等。

订单服务

订单服务是因为订单数据⽐较特殊,所以单独将订单相关功能作为独⽴服务。订单服务聚合所有系统节点的订单信息,让订单⽐较容易追溯,提供⾼可⽤的订单存储和查询服务,解决订单数据的单点存储问题,更好的⽀持其他依赖订单数据的系统的⽔平扩展和迁移。订单服务对可⽤性要求极⾼,底层存储依赖 AWS RDS ,在全球每个可能⽤到订单服务的可⽤区,部署订单服务集群。

服务降级

根据业务要求对每个服务及其依赖的资源,按重要程度进行分级,限制每个依赖服务的超时时间,定义各级服务的 SLA指标,对强依赖的基础服务或资源实行更高的 SLA标准,根据 SLA指标制定容错方案。

制定服务自动降级策略略,设置服务开关,关键时刻弃车保帅,对弱依赖的服务进行降级,比如日志服务是会被降级的,保障重要的服务不受影响。

对超大数据或流量用户进行隔离,在隔离的环境给这部分用户提供独立的服务,避免影响其他的正常用户服务。

自动化

微服务化后,服务的数量很多,为了节约开发成本,必须尽可能的自动化完成一些有固定步骤的工作,如测试自动化和部署自动化。

微服务化后,服务的数量很多,为了节约开发成本,必须尽可能的⾃动化完成⼀些有固定步骤的⼯作,如测试⾃动化和部署⾃动化。
(1)测试⾃动化
单元测试⾃动化,我们⽬前要求单元测试覆盖率要求⼤于90%,通过 Jenkins 整合 Sonar,每次提交代码后⾃动跑单元测试, Sonar ⾃动给出代码评分,测试覆盖率不够或代码不达标,则单元测试失败;
性能测试⾃动化、平台化,我们开发了⾃动化测试平台 DTesting,关键服务的每次变更,需要在平台上跑性能测试,并⽣成性能测试报告,对⽐历史的性能测试数据;
功能测试⾃动化、平台化,每个应⽤都有完整的功能测试⽤例和脚本,可⾃动化回归功能测试
(2)部署⾃动化
我们引⼊了 Docker,减少⼈为部署时的误操作。

日志处理


⽇志处理我们分为两部分,⼀部分是实时⽇志,另⼀部分是冷⽇志。所有应⽤的⽇志都需要写⼊ Kafka 和⽂件, Kafka 中有所有实时⽇志,会被 DLog 系统及时消费处理,但是实时⽇志保留时间不⻓,⼀般保留⼀个⽉。写⼊⽂件的所有⽇志会被定时备份到AWS S3 上永久保留,如果需要⼀个⽉前甚⾄更久以前的系统⽇志,可以在 DLog 系统选择需要的⽇志范围, DLog 会将符合条件的⽇志从 S3 上下载并重新建⽇志索引。⽇志主要是为监控提供基础源数据,为定位问题提供依据。

调用链追踪

随着服务的粒度越来越⼩,系统的服务变得越来越多,不同的服务可能由不同的团队实现,⼀个服务的实现可能会依赖⼏个甚⾄⼗⼏个服务,出现问题后,如何快速准确的定位故障呢?如何追踪业务的处理顺序和结果?业内已经有了⼀些实践和解决⽅案, Google Dapper 是 Google 研发的分布式跟踪系统,并发表论⽂阐述了分布式跟踪系统的理论基础,给分布式跟踪的实现提供了⾮
常好的参考示范。对于 Java 编写的服务,我们采⽤ Twitter Zipkin 来做调⽤链跟踪, Zipkin 是Google Dapper 系统的开源实现,采⽤ Scala 编写;⽽对于 Golang 实现的服务,我们⽬前还没有好的⽅案,做的还⽐较粗糙。⼀个好的调⽤链追踪系统,能为定位和排查故障提供强⼒的⽀持,对于微服务架构,调⽤链追踪是必备的基础设施。

服务健康状态


很多情况下,解决故障可能很快,难点在于发现故障和定位故障,这需要我们的系统有全⽅位的监控和报警能⼒。基于业务和技术对可⽤性的需求,我们开发了服务健康状态监控和报警系统,从业务层,服务层,硬件基础设施层分别进⾏监控和报警。

报警
报警系统定义所有报警种类,报警级别,处理流程,提供报警接⼊机制,各个层次的监控都可以通过⾃定义报警引擎接⼊报警系统来触发报警。 7 * 24 ⼩时服务监控团队会根据各个报警的处理流程,依次联系最⾼优先级的处理⼈来处理故障,如果在规定时间没有处理完,系统会根据报警的种类和级别⾃动升级报警响应级别,提⾼处理优先级来保障重要的报警能得到及时处理。

监控
监控分为基础设施层,服务层和业务层监控三⼤类。
1. 硬件基础设施层监控的内容包括:操作系统、内存、 CPU、⽹络流量和状态、连接数等,基础设施层的监控我们⽤ Zabbix 来做,通过 Zabbix 的 API 将数据整合进我们的监控系统 DMonitor。
2. 服务层监控包括基础组件监控、基础服务监控、常规服务监控和外部接⼝调⽤监控。其中基础组件监控包括 Etcd、 AWS RDS、 Redis、 Docker、 Kafka 等基础组件的使⽤情况监控;基础服务监控包括配置中⼼服务、认证服务、安全存储服务、路由服务、 API Gateway 等关键服务的监控;
常规服务监控是指监控所有的⼀般服务的状态;外部接⼝调⽤监控是指分析系统依赖的外部的访问情况,包括访问量、错误信息、超时状况等,为快速定位问题提供依据。
3. 业务层监控是指从业务⻆度出发,收集和分析业务层的访问量,根据各个业务的历史数据和已知的影响因素,预测现在和未来的业务情况,定义监控报警⽬标。⽐如:在最近半个⼩时内某个业务的请求量⼩于预期值;在最近 1 个⼩时内对某个客户的API调⽤次数超过预期值;在最近 3 个⼩时内某酒店的订单量显著下降等。由于业务层的监控⽐较复杂,我们把业务层的监控独⽴出了⼀
个⼦系统,业务层监控报警的决策来源历史数据和未来可能影响的因⼦,我们对历史海量的数据进⾏汇总加⼯和分析,从各个维度给出报警的预期值。
服务层监控和业务层的监控都离不开各个应⽤的⽀持,有些监控⽬标会对应⽤的实现有侵⼊性,⽐如需要写业务⽇志,各个应⽤根据监控的⽬标来设计和实现,为业务层监控提供必要的技术⽀持,因此,从系统架构层⾯⼀开始就需要考虑业务的可⽤性需求。

有了服务健康状态监控和报警系统,辅以调⽤链追踪系统和⽇志处理系统,我们发现和定位故障的时间就⽐较可控了,绝⼤部分故障可以很快定位原因,为修复故障提供了有⼒的保障。

发布管理

最后我想说说发布管理,虽然它不属于基础设施,但是它太重要了,对服务的高可用影响很大。基础设置都做到位了就万事大吉了吗?不,还差一口气,还需要确保最后一公里万无一失,那就是服务的发布管理,最后一公里主要规划以下三点。

(1)容量规划,通过测试报告评估应用的类型,是IO密集型、CPU密集型还是混合型?根据应用的类型,申请合理的硬件资源;单台节点最大处理能力是多少?线上有多少容量正在被使用?集群的最大处理能力是多少?这些在发布前都需要合理的评估和测试。

(2)冗余规划,需要考虑异地多可用区部署,服务实例不小于 N+2 部署,服务实例硬件配置需相同,避免大小不一部署实例。为什么是 N+2 而不不是 N+1 呢?为了防止在服务更新的时候同时又挂掉一个服务节点,而发布失败是高概率事件。

(3)发布控制,线下充分测试,能在线下做的测试绝不不能放线上做。刚才说了,发布失败是高概率事件,所以发布必须要支持回滚,必须拒绝一切没有回滚方案的更新,嗯,是必须拒绝。

写在最后

微服务系统本质上是一个分布式系统,而分布式系统就有其固有的复杂性,对测试,部署甚至团队的组织结构都会带来很大挑战。有了这些微服务架构的基础设施,能有效帮我们解决并规避一些问题,但我们仍然不能低估采用微服务架构带来的复杂性。微服务架构不是银弹,更不是免费的午餐,实施微服务改造是要付出代价的,根据业务的需求选择合适的架构,不要为了微服务而微服务。


本文转载自微信公众号 中生代技术 freshmanTechnology

目录
相关文章
|
13天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
12天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
12天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
29 1
服务架构的演进:从单体到微服务的探索之旅
|
10天前
|
消息中间件 监控 安全
后端架构演进:从单体到微服务####
在数字化转型的浪潮中,企业应用的后端架构经历了从传统单体架构到现代微服务架构的深刻变革。本文探讨了这一演进过程的背景、驱动力、关键技术及面临的挑战,揭示了如何通过微服务化实现系统的高可用性、扩展性和敏捷开发,同时指出了转型过程中需克服的服务拆分、数据管理、通信机制等难题,为读者提供了一个全面理解后端架构演变路径的视角。 ####
27 8
|
11天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
38 5
|
12天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
31 5
|
12天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
13天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
13天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
13天前
|
安全 持续交付 Docker
微服务架构和 Docker 容器化部署的优点是什么?
微服务架构和 Docker 容器化部署的优点是什么?
下一篇
无影云桌面