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

大纲

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

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

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

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

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

痛点

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

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

• 公司有各种⼯具平台、 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开发者查阅;现在免费送给各位!

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335