APP下载

滴滴出行架构大神分享:大型微服务框架设计实践

消息来源:baojiabao.com 作者: 发布时间:2024-04-28

报价宝综合消息滴滴出行架构大神分享:大型微服务框架设计实践

大纲

• 发现问题:服务开发过程中的痛点

• 以史鉴今:从服务框架的演进历程中找到规律

• 大道至简:大型微服务框架的设计要点

• 精雕细琢:框架关键实现细节

复杂业务开发过程中的痛点

痛点

• 时间紧、任务多、团队大、业务增⻓快,如何还能保证架构稳定可靠?

• 研发水平参差不其、项木压力自顾不暇,如何保证质量基线不被突破?

• 公司有各种⼯具平台、 SDK、最佳实践,如何尽可能的在业务中使用?

•用什么“框架”可以解决问题?

从服务框架的演进历程中找到规律

让我们先来看下服务框架的进化史

标志性的服务框架

Web 服务框架: MVC 架构

• ASP.Net(since 2002):传统 C/S 开发模式在 Web 上的应⽤

• Ruby on Rails(since 2005): MVC 框架的巅峰, “约定⼤于配置”

• Web 服务框架: SaaS 与 RESTful

• Sinatra(since 2007):纯路由框架,诸多框架的灵感源泉

• 微服务框架: RPC 服务

• Thrift(since 2007):开源 IDL-based 框架的⿐祖

• 微服务架构:容器化与 FaaS

• Serverless(since 2015):基于云端计算平台,回归框架本质

• Istio(since 2018):专注于解决网络问题、

服务框架的演进趋势

服务框架正在演变成新的“操作系统”

• 学习曲线: Exponential Rise(渐进式) → Sigmoid(阶跃式)

• 风格:配置 → 约定 → DSL → 容器化

• 业务程式码与框架程式码的关系: Is-a → Has-a → Duck-typing

• 工具链: IDE → 程式码⽣成器 → 编译器

大型微服务框架的设计要点

站在全域性视⻆观察微服务架构

大型微服务框架的设计目标

框架即一款面向开发人员的效率产品,基于公司的基础设施量身定制

• 目标使用者:来不不同背景、具有基本业务研发能⼒的开发者

• 设计要点:让开发人员专注于业务开发本身,无需关注滴滴各种基础设施底层细节

• 设计原则:直观、简洁、智慧、个性化

• 预期收益:提升⼈效,降低维护成本;提升整体架构稳定性和可伸缩性;简化技术升级难度

大型微服务框架的设计要点

完全遮蔽业务无关的通用技术细节

• 功能:服务治理、虚拟化、水平扩容、问题定位、效能压测、系统监控、相容遗留系统……

• 工具链:专案模板、程式码生成器、文件生成器、释出打包指令码……

• 设计⻛格: Interceptors、组合模式、依赖注入……

• 让不可靠的调⽤变得可靠

• RPC 呼叫 ≈ 函式呼叫

• 访问基础服务 ≈ 访问本地储存

• 服务拆分/合并 ≈ 类拆分/合并

框架关键实现细节

业务实践

业务背景:复杂的业务流程,快速增涨与迭代,异构服务架构,跨国多机房部署

• 核心能力

• 隔离层封装:各种储存、伫列、平台服务封装

• 透明支援各种运维基础设施:构建、释出、多机房配置、 metrics

• 提供效率和测试⼯具:⽇志采集、问题⾃动跟踪、全链路压测、 mock、接⼝测试

• 应⽤层协议隔离:⽀持 thrift/http 协议 interceptor

• 工具链:模板、程式码⽣成器、依赖管理、版本管理、释出指令码

站在巨人肩膀上:滴滴基础平台建设现状

• Odin:运维平台,提供 metrics 上报、多维度监控、报警、服务树等功能

• 把脉:日志平台,提供日志采集通道、基于 traceid 的全链路⽇志查询能⼒

• DiSF:服务注册平台,提供高可用的服务名字服务、管理服务分组

• RDS:提供高可用、透明水平扩充套件的 MySQL 丛集,支援资料总线、分身等能力

• DDMQ:低延迟高可用的讯息伫列服务,单机 TPS 吞吐超过百万,支援延时讯息

• Fusion:基于 rocksdb 的高效能高可用分散式持久化储存方案,完全相容 Redis 协议

• 弹性云:基于 k8s,高效、可伸缩的丛集管理平台,服务自动容错,基础设施免运维

整体架构

实现要点:框架与业务正交

实现思路

• 传统框架的 MVC、 middleware、 AOP、执行流程……都不存在也不需要

• 框架是一个执行环境,由一堆不关联的基础库组成高度可扩充套件,业务可独立于框架执行

如何实现

• 提供工具链,用于生成最初的项⽬模板并通过程式码生成器实现类似 AOP 的效果

• 基于 Go interface 的 duck-typing 特性和执行时反射,动态生成业务路由

收益

• 业务开发⽆需关注框架本身,

• 框架本身的升级可以做到完全透明,方便所有服务统一框架版本

框架的启动逻辑

实现要点:隔离层遮蔽业务与底层的联络

如何实现

• 为所有基础服务(mysql/redis/mq/es/...)定义 interface,业务只允许呼叫 interface 的方法

• 基于 SPI 设计思路,提供基础服务的工厂,动态例项化对应 interface

收益

• 可透明的升级服务驱动,快速在大量服务中实现共性逻辑或者修复共性问题

• 透明的管理基础服务的资源(长连线、 mysql cursor 等),避免出现资源泄露

• 统⼀控制重试、超时、服务发现、故障摘除逻辑,业务⽆感知且不易出错,提升整体稳定性

• 对所有基础服务提供了 mock 能力,可以实现 AOP 能力

案例: Redis 界面设计

实现要点:协议劫持

如何实现

• HTTP 协议:包装 http.Handler,用责任链模式处理 http.Request 和 http.ResponseWriter

• RPC 协议:劫持协议序列化流程,用FSM(有限状态机)来跟踪序列化过程并适时修改资料

收益

• 将业务资料和服务框架资料充分隔离,避免互相⼲扰

• 实现界面热补丁和 in/out 资料录制与重放,方便测试

• 可透明的增强服务能力,为实现跨服务边界的 context 打好基础

使用FSM 劫持 thrift protocol

FSM 实现思路

• 利用 Go interface 特性,实现一个 interfaceproxy,代理并劫持部分感兴趣的界面

• 维护一个 FSM 状态机,当 protocol read/write走到感兴趣的地⽅时候篡改 read/write 资料

实现要点:跨服务边界的 context

如何实现

• 实现符合 context.Context 界面的自定义 context,支援序列化与反序列化,支援超时控制

• 结合协议劫持,透明的从服务框架资料中提取必要资讯进行反序列化,并在所有 RPC 呼叫前

透明的将最新 context 序列化并放在服务框架资料中传输给下游

• 需要重新实现一个基于时间片轮转的低精度 time.Timer,提升并发效率并避免 timer 泄露

收益

• 可透明的在服务间传递上下文资讯,从而实现流量染色、呼叫跟踪、防雪崩等功能

低精度 timer 实现原理

实现要点:防雪崩

如何实现

• 通过跨服务边界的 context 来传递上游超时预期,并不断记录各个环节耗时

• 一旦框架发现自己的可用时间已经耗尽,主动终止后续 rpc 调⽤并快速返回,防止请求积压

收益

• 从根本上避免请求堆积造成的雪崩

跨服务边界的超时时间控制

超时资讯如何跨服务边界传递

• 超时时间由最上游设定,框架捕捉到超时资讯并将时间记录在 trace 里透明的传播到下游每一个服务节点

• 每个节点从接收到请求开始后计时,自动计算自己消耗的时间并计算当前呼叫链路总耗时

• 当链路总耗时超过超时时间,自动 fail-fast,快速返回失败资讯

• 利⽤ Go context deadline 只会缩短不会提前的特性,方便的用 context 管理超时

• 避免服务器之间的时钟差异影响计时,始终使用时间差来记录号是,而不使用绝对 deadline

业务收益

支撑规模

• 涉及开发人员近 100 人,上线 70+ 服务,国内外双机房部署

• 可支撑百万级日订单规模、万级并发长连线

业务收益

• 零成本:透明接⼊公司运维、释出、日志、压测等平台,支援服务注册发现、弹性伸缩等能力

• 零事故:从未出现因为单点故障造成的全域性稳定性事故

• 高质量:快速实现全链路压测常态化,透明实现多环境部署、单测、整合测试等

• 易维护:透明升级各种 driver,简化程式码依赖管理过程

未来计划

提升开发者体验

• 命令列工具,用于整合各种工具

• 进一步与滴滴线上线下环境整合

• 整合更多的公司服务和框架

• 配置管理中⼼化

• 开源?

文章来源:滴滴出行 R lab 杜欢

开发这么多年也收集了一套架构技术文件!

里面的知识点有:高并发、分散式、高效能、spring、mybatis、微服务等非常适合开发1-5年的Java开发者查阅;现在免费送给各位!

关注+转发后私信我【架构资料】即可免费获取!

2019-09-16 09:54:00

相关文章