近万服务实例稳定运行 0 故障,携程微服务架构是如何落地的?

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 本文整理自作者于 2020 年云原生微服务大会上的分享《携程微服务框架实践及思考》,主要介绍了从携程自研框架遇到的问题,转到落地 Dubbo 微服务框架,携程是如何实践的,以及实践过程中遇到的问题;未来转型 service mesh 的道路上,dubbo 协议存在的问题,我们需要怎么样的协议层以及微服务 SDK 的定位。

头图.png

作者 | 顾海洋  携程框架架构研发部技术专家

导读:本文整理自作者于 2020 年云原生微服务大会上的分享《携程微服务框架实践及思考》,主要介绍了从携程自研框架遇到的问题,转到落地 Dubbo 微服务框架,携程是如何实践的,以及实践过程中遇到的问题;未来转型 service mesh 的道路上,dubbo 协议存在的问题,我们需要怎么样的协议层以及微服务 SDK 的定位。

阿里巴巴云原生公众号后台回复 818 即可获取直播回看地址和大会 PPT 合集。参与文末互动,还有机会得《携程架构实践》一书!

携程从 .Net 技术栈的时代就已经开始微服务领域的探索,转入 Java  技术栈之后,更是经历了自研微服务框架,到现在高性能的 dubbo,目前我们正在 Service Mesh 的道路上探索,希望能够实现微服务框架的全面标准化、以及云原生。

过去(自研服务框架)

携程从 .Net 技术栈开始,最开始是基于 ESB 总线,虽然解决了内网服务调用的治理问题,但是集中式的服务架构,经常会出现单个服务把整个总线拖垮的情况,进而导致全网瘫痪的现象。基于注册中心的 SOA 服务架构,通过分布式的服务调用,解决了单点故障带来的巨大影响。目前,携程主要是以 Java 技术栈为主,考虑到兼容历史 .Net 技术栈,所以现在的框架以自研为主,但是对比开源的高性能服务框架,自研的框架可能又存在下述提到的几个问题。

1.png

现在(CDubbo 服务框架)

CDubbo 名字里的 C 代表携程的治理,Dubbo 代表阿里开源的 Dubbo SDK。纵观过去两年的实践和探索,从 2018 年 4 月的第一个版本落地,到现在的近万服务实例,我们大致可以总结为下面的几个主要里程碑。

2.png

1. 注册发现

注册发现是分布式服务框架的核心要素,为了支持现有的服务互通,所以需要接入携程的注册中心。

服务注册支持健康检测扩展机制,业务可以根据业务场景自定义健康检测扩展,例如当依赖的数据库不可用时不再对外提供服务。服务端通过 5s 一次的心跳保持服务的可用性,当连续 N 次没有发送心跳时就会自动通知客户端。

客户端发起对服务的订阅,通过推拉结合的模式,保证节点在客户端的最终一致性。通过 Dubbo 的扩展机制,实现了自定义的路由策略,比如根据方法名指定路由策略,以及根据请求参数决定不同的路由策略,同时也能够支持就近访问,优先访问本机房的服务。

3.jpg

2. 监控 - CAT

对微服务来说,没有了监控就好比瞎子一样,什么也不清楚。CAT 提供了分布式链路追踪的能力,可以提供很好的报表,以及场景化的问题分析。

有时,需要了解服务总的请求量以及单机的请求分布和 QPS,或者还要知道服务的执行耗时及 99 线。CAT 的聚合报表可以帮助我们更好的了解服务的健康状况。

4.png

对于超时,可能需要知道哪个阶段变慢,客户端还是服务端,序列化阶段还是服务执行过程太慢。对于异常报错,可以看到哪个过程出现的异常,同时会打印异常堆栈信息,帮助问题的定位。

5.png

3. 监控-Metrics

框架人员需要了解公司服务的宏观情况,比如各机房都有哪些服务,哪些服务使用了 protobuf 序列化格式,哪些服务使用了 SOA 协议等,以及平均执行耗时等情况。业务同事可能也想知道自己服务具体情况,比如有哪些调用方,线程池是否已经跑满了。

通过接入携程的 Dashboard,可以提供全局的总量、错误量、线程池统计信息,也可以根据机房、协议、序列化格式等聚合数据。还能够自定义告警规则,在问题发生时能够尽早的介入。

6.png

4. 动态配置

对业务同事来说,有可能会存在依赖的服务突然变慢导致客户端超时的情况。框架人员可能需要在机房故障时,需要全局调整 check 为 false,以解决 A B 服务循环依赖谁都无法启动的问题。动态配置提供了配置热生效的能力,不需要为了一个配置重新发布,成本很高。

服务端的多个方法,可能执行耗时也会有所不同,通过多级别的参数配置,可以设置服务默认超时为 1s,单独为执行较慢的方法设置独立的超时时间为 5s。

服务 Owner 可能更清楚自己服务的耗时,通过服务端对客户端的参数设置,不需要每个调用方都设置一次超时,设置的时间也会更合理一些。为了避免配置出错带来的损失,我们提供了友好的可视化界面。

7.png

5. SOA 协议及互通

为了支持现有客户端迁移到 CDubbo,需要考虑支持现有的 SOA 协议。除了要确保兼容 HTTP 1.1 协议不变,其次要保证跟客户端的序列化器一致。

CDubbo 会通过 Tomcat 端口接收 SOA 协议的请求,利用现有的序列化器执行请求对象的转换,并保证 Dubbo 内部调用和 Filter 链路的一致性,确保业务逻辑的统一,也就是业务代码不需要改动,就可以启动两个协议。

8.png

6. 测试平台

对于私有的二进制协议来说,没有现成的 Postman 等工具可以使用。有时,开发人员需要在本地验证测试环境的服务,也可能要验证本地启动的服务端,每个开发人员都构造一个客户端显得成本比较高。

通过 VI(github 开源叫 coreStone),以及利用 Dubbo 2.7.3 提供的元数据中心和泛化调用能力,我们实现了类似 postman 的调用工具。不但可以支持直连,也能够支持本地测试,同时还可以支持 protobuf 序列化格式。关于 protobuf 序列化的测试方案,已经贡献到 dubbo 社区,感兴趣的同学可以自行了解。

9.png

7. 升级 Dubbo 2.7.3

关于 Dubbo 2.7.3 的详细升级历程,可以参考:https://www.infoq.cn/article/kOxdaV3y9fMZ0Bzs0jb2

现在回顾下升级的最终结果如何。目前,携程 99% 的服务已经跑在 dubbo 2.7.3 之上,迄今为止 0 故障,只有一些不兼容的小问题,对于不兼容的问题也是确保了编译时提前暴露,运行时没有任何问题。

在发布后,也陆续的出现了一些小的问题,比如预热能力不生效,异常情况下不会回调 onError 等问题,支持服务端异步的 Trace 埋点等,这些问题已经在开源版本彻底修复了。

8. Threadless

业务同事反馈,需要把线程控制在理想的范围之内。但是,dubbo 的线程数量太多,一方面是服务级独享线程池,当调用方依赖了 10 个服务,每个服务的 QPS 为 1,lantency 可能只有 10ms 的情况下,由于每个服务独立线程池,至少也需要 10 个线程了。如果多服务共享一个线程池,由于客户端默认是 Cached 的线程池模式,那么在这个场景下可能只要 1 个线程就足够了。另一方面,对同步服务来说,dubbo 2.7.5 的 threadless 可以省去 DubboClientHandler 线程,Netty IO 线程直接把响应交给业务线程,从而节省了一次线程切换。

通过实践,业务线程数量有了很大程度的下降,在高 QPS 以及依赖服务数量较多的情况下,甚至可以下降 60-70%。

10.png

9. CDubbo 服务体系

现有 CDubbo 的服务体系,同时支持 Dubbo 和 SOA 协议,对于 Dubbo 客户端能够支持 TCP 协议的传输,对于现有的 SOA 客户端,能够兼容现有的 SOA 协议。

同时,也能够支持内网和外网 gateway 的请求,保证了多协议的配置统一,以及兼容了 SOA 的序列化格式。

11.jpg

10. 性能表现

从协议层面来看,Dubbo 协议的响应较 SOA 协议有所提升,平均耗时从之前的 1ms 降低到了 0.3ms 左右,当然具体提升也要根据服务的报文及请求量有所差异。

12.png

可能有些人会觉得几毫秒的性能提升不足以挂齿,但是性能的稳定性对服务来说会很重要。我们观察了服务流量突增 3-4 倍的情况下,客户端还能保持 0 异常。长连接的多路复用,提供了很好的抗冲击能力。

13.png

11. 扩展性

微服务框架跟业务代码耦合比较重,框架人员主要是用 20% 的时间解决业务 80% 的需求,另外 20% 的需求却需要 80% 时间的问题,更适合留给业务自己去解决,能够提供这个能力的唯有扩展性,dubbo 无论横向和纵向的扩展能力都很好。

通过实践,发现业务的确在各个层级都有自己的扩展。例如:业务扩展了 Router 层,支持自己的路由规则,扩展了负载均衡策略,机票同事甚至扩展了 Transport 层换成了适合自己的传输协议。

14.png

12. 生态

好的生态,可以降低开发成本,例如利用现有的开源 dubbo admin,dubbo go 等组件。另外,也可以降低业务的学习成本,在其他公司学习的 dubbo 框架,到了携程还可以接着用,不需要重新学习私有的服务框架。技术支持也比较少,很多业务同事甚至比我们还熟悉 dubbo 框架。

15.png

13. Dubbo 协议现有问题 & Dubbo 3.0 规划

除了前面提到的 Dubbo 框架得到业界广泛认可的优点,在我们实践的过程中,也发现了现有的 Dubbo 2.x 版本协议存在的一些不足,比如在云原生大背景下,协议对网关不够友好,缺乏移动端的轻量级 SDK 等。据我们与 Dubbo 官方维护团队的深度交流,这些点也都是当前 Dubbo 3.0 在重点突破的方向,如下一代协议、应用级服务发现、云原生基础设施支持等,携程作为 Dubbo 深度用户也将持续的参与到 Dubbo 3.0 的建设与落地过程中。

16.png

未来(Service Mesh)

网上关于 Service Mesh 的意义讲了很多,众说纷纭,个人认为可能最主要还是以下几点。

  • 标准化意味着更低的成本,比如研发成本低,学习成本也比较低,其他公司学习的微服务框架,到携程还可以继续用,省去了学习和踩坑的成本;
  • 进程解耦,框架同学可能比较感兴趣,中间件无法独立升级的问题一直困扰着框架研发同学,在这个问题上,envoy 可以独立升级也是值得期待的;
  • 通过下沉,复用了云基础设施的一些能力,一方面,能够更好的支持多语言,业务根据自己的场景选择合适的语言,另一方面,通过下沉也能够让 SDK 更简单,减少Jar依赖的兼容性问题;
  • 因为更加标准以及下沉,能够带来更好的云部署能力,业务出海时可以根据实际情况部署需要的组件,不再依赖框架全家桶了。

17.png

1. Service Mesh SDK

下图是 Istio 官网提供的 Service Mesh 架构图,如果说 Istio 解决了控制平面的标准化,envoy 或者 sofa-mosn 解决了数据平面的标准化,那么对于 SDK 来说,是否需要有个标准化的组件,或者是否存在适合我们的标准的 SDK 呢?

对于部分中小公司,没有自己的中间件团队,可能会选择商业版 SDK。但是,对于携程这样的规模,对扩展性要求很强,同时已经存在上千 dubbo 服务的公司来说,我们可能更期待 3.0 的标准协议。

18.png

2. 现有协议不适合下沉

现有的 SOA 协议可能不太适合作为标准协议,基于 Http 1.1 的文本协议,跟 TCP 协议相比,建连带来的成本,很大程度上会导致长尾,影响服务的稳定性。

19.png

Dubbo 协议由于对网关不太友好,同时存在着跨语言和协议穿透性等问题,envoy 本身也可以理解为单机网关代理,所以也不太适合作为标准协议。

其次,存在的跨语言和协议穿透性问题,阿里刘军同学有过分享,感兴趣的同学可以参考:https://www.infoq.cn/article/y5HC2JjtAvMWYILmVILU

3. 新协议

既然现有的协议都不太适合,是否可以考虑云原生的标准协议 gRPC。没错,从协议层面来看,这个选择没有问题,但是 gRPC 跟 proto 强绑定的问题,需要携程现有的几千个服务重写业务逻辑代码,这个成本可是无法被接受的。

我们对于新的协议的期待,应该是能够基于 POJO 对象,同时还要符合 gRPC 协议规范。一方面,能够很好的利用云原生的基础能力。另一方面,对于小众语言,也可以利用现有的 gRPC 框架实现与主流 SDK 的互通。

20.jpg

对于新的 SDK,不但要有标准的传输协议,同时考虑到服务框架与业务的紧密耦合,扩展性也是要保留的主要的特性,还需要考虑 API 的标准化,利用统一的监控组件。

4. 总结

现在,我们实现了 SDK 的部分标准化。未来,我们一定会在云原生的道路上走的更快,更稳,更标准。

21.png

有奖互动

9 月 4 日 11:00 前在阿里巴巴公众号留言区写下你关于微服务架构的思考或问题,点赞前 5 名即可获得《携程架构实践》图书一本

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

相关文章
|
23小时前
|
存储 NoSQL MongoDB
【MongoDB 专栏】MongoDB 与微服务架构的结合
【5月更文挑战第11天】微服务架构流行趋势下,选择合适的数据库至关重要。MongoDB作为非关系型数据库,与微服务有天然契合度。其灵活的文档模型、水平扩展性、高性能及局部事务支持,满足微服务对数据模型多样性、高可用性、快速读写的需求。实践中,需注意数据划分、索引优化、监控调优和版本控制。未来,MongoDB在微服务中的应用将更广泛,新技术将提升其在微服务架构中的价值。
【MongoDB 专栏】MongoDB 与微服务架构的结合
|
1天前
|
算法 计算机视觉 网络架构
CVPR 202:擅长处理复杂场景和语言表达,清华&博世提出全新实例分割网络架构MagNet
【5月更文挑战第10天】在CVPR 2024会议上,清华大学与博世团队推出MagNet,一种针对复杂场景和语言表达的实例分割网络。MagNet通过Mask Grounding辅助任务强化视觉-语言对应,缩小模态差距,并结合跨模态对齐损失与模块,提升RIS任务的准确性。在RefCOCO、RefCOCO+和G-Ref基准上取得显著优势,但对罕见表达和复杂场景的处理仍有待优化。[论文链接](https://arxiv.org/abs/2312.12198)
10 5
|
1天前
|
监控 数据库 开发者
构建高效可靠的微服务架构:策略与实践
【5月更文挑战第11天】在当今软件开发的世界中,微服务架构已经成为构建可扩展、灵活且容错的系统的首选方法。本文深入探讨了设计、部署和维护微服务系统时面临的挑战,并提出了一系列实用的策略和最佳实践。我们将从服务的划分原则出发,讨论如何确保每个微服务的自治性,以及如何通过容器化和编排技术实现服务的高效运行。文章还将涉及监控、日志记录和故障恢复的策略,旨在帮助开发人员构建一个既高效又可靠的微服务环境。
|
1天前
|
Kubernetes API 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第11天】 在现代软件开发的快速演变中,微服务架构已成为企业追求敏捷性、可扩展性和技术多样性的关键解决方案。本文旨在探讨如何构建高效的微服务架构,并分析其对后端开发的影响。我们将通过一系列最佳实践和策略,展示如何优化服务的独立性、弹性和性能,同时确保系统的整体稳定性和安全性。文章还将介绍容器化、API网关、服务发现和分布式追踪等关键技术的应用,为后端开发者提供一份全面的微服务实施指南。
|
1天前
|
设计模式 监控 API
构建高效的微服务架构:后端开发的新范式
【5月更文挑战第11天】 在当今的软件开发领域,微服务架构已经成为一种流行的设计模式。它通过将应用程序分解为一组小型、松散耦合的服务来提供高度可扩展和灵活的解决方案。本文将探讨如何构建一个高效的微服务架构,包括选择合适的技术栈、设计原则以及应对常见挑战的策略。我们将深入讨论如何确保系统的可维护性、可靠性和性能,同时考虑到安全性和监控的需求。
|
2天前
|
监控 持续交付 Docker
使用Docker进行微服务架构的最佳实践
【5月更文挑战第10天】本文探讨了使用Docker实施微服务架构的最佳实践。首先,理解微服务架构是拆分小型独立服务的模式,借助Docker实现快速部署、高可移植性和环境一致性。Docker的优势在于服务扩展、容器编排、自动化构建与部署。最佳实践包括:定义清晰服务边界,使用Dockerfile和Docker Compose自动化构建,利用Docker Swarm或Kubernetes编排,实施服务发现和负载均衡,监控与日志记录,以及持续集成和持续部署。Docker虽重要,但需与其他技术结合以确保系统整体稳定性。
|
2天前
|
存储 监控 API
构建高效微服务架构:后端开发的现代实践
【5月更文挑战第9天】 在本文中,我们将深入探讨如何在后端开发中构建一个高效的微服务架构。通过分析不同的设计模式和最佳实践,我们将展示如何提升系统的可扩展性、弹性和维护性。我们还将讨论微服务架构在处理复杂业务逻辑和高并发场景下的优势。最后,我们将分享一些实用的工具和技术,以帮助开发者实现这一目标。
|
4天前
|
API 持续交付 开发者
构建高效微服务架构:后端开发的新视角
【5月更文挑战第8天】 随着现代软件开发的演变,微服务架构已经成为了企业追求敏捷、可扩展和灵活部署的重要解决方案。本文将深入探讨如何构建一个高效的微服务架构,包括关键的设计原则、技术栈选择以及持续集成与部署的最佳实践。我们还将讨论微服务带来的挑战,如数据一致性、服务发现和网络延迟,并提出相应的解决策略。通过本文,后端开发者将获得构建和维护微服务系统所需的深度知识,并了解如何在不断变化的技术环境中保持系统的健壮性和可维护性。
37 8
|
2天前
|
缓存 负载均衡 API
微服务架构下的API网关性能优化实践
【5月更文挑战第10天】在微服务架构中,API网关作为前端和后端服务之间的关键枢纽,其性能直接影响到整个系统的响应速度和稳定性。本文将探讨在高并发场景下,如何通过缓存策略、负载均衡、异步处理等技术手段对API网关进行性能优化,以确保用户体验和服务的可靠性。
|
2天前
|
监控 持续交付 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第10天】在现代软件开发领域,微服务架构已经成为一种流行的设计模式,它通过将大型应用程序拆分为一组小型、独立和松散耦合的服务来提供更高的可伸缩性和灵活性。本文深入探讨了微服务架构的设计理念、实施步骤以及面临的挑战,并提出了一套实用的策略和最佳实践,帮助后端开发者构建和维护高效的微服务系统。