大流量下美团账号系统技术架构的设计与优化
如果无法正常显示,请先停止浏览器的去广告插件。
1. 大流量下美团账号系统技术架构的设计与优化
演讲人: 美团技术专家——杨宇晨
美团平台事业部
1 1
2. 个人介绍
教育经历
2013年 - 2017年
哈尔滨工程大学
工作履历
2017年至今
美团
美团成长经历
2017 至 2018
2018 至今
美团平台
美团内容
用户账号组
2
3. 账号系统介绍
单体服务之痛
步步为营的性能优化
系统稳定性的超前建设
技术架构的未来展望
3
4. 二、账号系统(用户中心)简介
C端
内部
服务层
数据层
PC 小程序 H5 Android iOS
到家 优选 金融 到店 ……
登录注册 绑定手机 业务融合 周边服务 成长值
用户信息 密码管理 会话管理 客服接入 ……
美团用户信息
点评用户信息
4
5. 二、账号系统(用户中心)简介
C端
服务范围
面向全公司 C 端业务提供用户账号公共服务
流量
集群日常 240万+ QPS
服务层
服务对象
集团内近千个前后端服务
内部组成
数据层
接口量
60+ 服务
数百个 HTTP 及 RPC 接口
5
6. 账号系统介绍
单体服务之痛
步步为营的性能优化
系统稳定性的超前建设
技术架构的未来展望
6
7. 单体服务之痛
单体项目代码层面问题
500+对外接口
API 层
•
•
•
•
•
A 登录方式存在 8个 同构接口
B 登录方式存在 4个 同构接口
C 核心逻辑存在 5个 同功能接口
为 多个 对接方提供了同功能的不同接口
……
400+Java类
Service业务逻辑共享代码包
DAL 层
•
•
•
•
•
代码耦合严重
30+ 个 Java 类存在循环调用
全包代码量超 5 万行
核心逻辑 Java 类平均代码量超过 1000 行
超过 20 个方法被重复定义超过 2 次
……
n多张表与m多个缓存集群
• 所有 Service 逻辑 及 API 逻辑均与 DB 模型
耦合
• 多个 DB 表结构与操作逻辑被 15 个服务共享
• 3个 核心缓存模型被服务间共享,存在序列化
异常风险
• ……
7
8. 单体服务之痛
单体项目服务层面问题
核心服务资源使用情况
350
❗ 单体服务占用 200+ 台 8 核 8G 机器,
流量却仅占 10%
300
❗ 完整发布单体服务服务需要 3.5 小时
❗ 单体服务资源利用率仅约 13%
250
200
150
100
巨型单体应用不可取
50
0
单体服务
核心读服务1
机器数
利用率百分比
核心读服务2
流量(比例)
8
9. 单体服务之痛
DDD 战术模式的应用
展现层
应用服务层
整合接口
公共组
件
重构重写
Service
领域层
基础设施层
API
隔离持久层数据结构
DAL
代码复用
公共服
务
9
10. 单体服务之痛
DDD 战略模式的应用
✅ 按领域拆分服务
✅ 核心服务读写分离
✅ 服务设计优先以事件驱动
单体服务功能
A业务融合
信息查询
登录注册
B业务融合
信息管理
运营支持
会话管理
会话校验
……
领域拆分
微服务化
登录注册领域
第三方领域
身份凭证领域
HTTP服务 三方服务A 校验服务
RPC服务 三方服务B 管理服务
用户信息领域
融合领域
信息管理 融合查询
信息查询 融合管理
读写模型同步 新业务适配
运营支持
管理后台
内部工具服务
业务公共服务
Ticket管理
Binlog处理
日志中控
10
11. 单体服务之痛
基于 Groovy 的动态代码分发平台
微服务
管理后台
查看版本分布
本地缓存
动态配置代码
动态代码中控服务
周期性请求数据
周期性上报版本
GroovyClassLoader
动态代码SDK
根据版本乐观锁决定是否加载或覆盖代码
KV
DB
11
12. 单体服务之痛
CQRS 架构的抉择
写流量
写流量
读多写少
读流量
读逻辑性能要求高
读流量
0
10
20
30
40
50
60
70
80
0
100
200
比例
300
400
500
600
TP9999最低要求(ms)
折衷选择 CQS
2021.1.1 15:00:00.000 注册
1. 应用层读写分离
2. 持久层保持聚合
读写模型需毫秒级完全一致
C端用户
业务方服务
CQRS
写服务
<50ms
查询服务
一致性要求高
2021.1.1 15:00:00.050 查询
12
13. 单体服务之痛
缓存的强一致性保证机制
内部服务
写入
查询
持久化
数据管理服务
异步同步Binlog
Binlog分发服务
主动同步
关系型数据库
Binlog下发
异步同步Binlog
外部服务
查询
数据查询服务
异步同步
读写模型同步服务
13
14. 账号系统介绍
单体服务之痛
步步为营的性能优化
系统稳定性的超前建设
技术架构的未来展望
14
15. 步步为营的性能优化
性能问题的排查方案与挑战
秒级分析
对照实验
❗️一二三方库依赖繁杂 ❗️Agent分析工具影响性能
✅使用控制变量法对可疑路
径进行对照试验并分析结果 ✅对系统指标异步采样获取
秒级数据
高频压测
15
16. 步步为营的性能优化
单机容量增
加50%
Hystrix 与线程池隔离模式的性能问题
现象
原因
复现排查
解决
execute get
queue toFuture
execute
阅读源码
get
TimerTi-
cker
toObservable
性能分析
Timer唤醒机
制
❌ CPU 与 load 居高不下
❌ 单机 7000 QPS 后瞬间崩溃
Worker
ThreadPool
Worker
ThreadPool
✅ 使用 Rhino 替换 Hystrix
✅ 非异步链路改用信号量隔离
16
17. 步步为营的性能优化
单机容量增
加60%
双缓存实现方式导致的性能问题
现象
原因
解决
Thrift Worker
Thrift Worker
双缓存并发请求
含双缓存组件的业务:
❌ Load 持续高位
❌ Thrift worker 吞吐降低
复现排查
Wait&Notify
Observe
Lock
subscribe
阅读源码
Late&Busy
Redis
Client
Tair
Client
toObservable
Timer
❌ 8000 QPS 后随机崩溃
Worker
ThreadPool
Wasted
性能分析
Redis
ThreadPool
Tair
ThreadPool
Redis&Tair
ThreadPool
17
18. 步步为营的性能优化
依赖报错服
务无影响
Log4j 对异常类处理有误造成的性能问题
现象
原因
解决
Logger
Log4j
实际加载路径
正确加载路径
分析源码
复现排查
AppClassLoader
DelegatingClassLoader
栈过滤工具
过滤生成类
❌ 大量线程 Block
❌ CPU 瞬间打满
JVM优化生成类
createMemento
18
19. 步步为营的性能优化
加解密及哈希功能的三方库锁竞争问题
现象
原因
解决
Mac & MessageDigest
Worker线程调用
多线
程并
发请
求
复现排查
❌ CPU 使用逐步增高
java.security.Provider
无锁
调用
分析源码
ThreadLocal缓存
Mac & MessageDigest
❌ 高 QPS 下出现线程Block
CPU占用
下降10%
阻塞
于全
局锁
Provider
仅新
线程
首次
请求
阻塞
19
20. 账号系统介绍
单体服务之痛
步步为营的性能优化
深化系统稳定性建设
技术架构的未来展望
20
21. 深化稳定性建设——稳定性问题的三个分类
事前
压测、故障演练 和 限流 是评估自身性能和稳定性水平的重要手段。
事中
故障发生时刻对问题的应对能力,核心为 架构缺陷填补 和 故障恢复能力 的超前建设。
事后
对有损故障进行 快速补偿 减少损失,归纳复盘总结经验。
21
22. 深化稳定性建设——总体背景
写接口压测困难
200+ 写接口的 Quake 数据构造难
置信度低
内部存储逻辑和链路复杂,无法直接
录制流量,而构造的流量可到达的逻
辑分支往往不到 70%
流量上涨迅猛
登录注册领域
第三方领域
身份凭证领域
HTTP服务 三方服务A Token校验
RPC服务 三方服务B Token管理
运营支持
Admin
Tools
融合领域
用户信息领域
融合查询 信息管理
融合管理 信息查询
新业务适配 读写模型同步
Binlog处理 日志中控
2020 年 QPS 大幅度上涨秒杀活动
频繁
TP 耗时及可用性要求严格
业务方对 5ms 或 0.01% 以内的瞬
时可用性恶化也十分敏感
业务公共服务
Ticket管理
数据层
MySQL
Cellar
Squirrel
MySQL 容量有限
集群的扩展和缓存容灾依赖 MySQL,
但数据库本身的容量和连接数存在天
花板,只能满足约 50% 的流量需求
22
23. 深化稳定性建设——总体目标
对整体架构的性能和稳定性问题进行周期化摸底
全链路压测
故障演练
应用服务层
增强应用层对大流量的应对能力
快速扩容
流量隔离
PaaS 层
增强 PaaS 层故障处理能力
持久层高可用
由
压
测
系
统
提
供
验
证
能
力
支
持
补偿机制强化
23
24. 深化稳定性建设——用户中心全链路压测面临的问题
200+ 写(含读)接口
30+ 依赖请求顺序的写接口
5~10 条链路内部逻辑 = 1000 ~ 2000 种元数据需构造
150+ 种相关元数据
= 4500+ 请求顺序排列组合需构造
PM 今天提了新需求,
数据构造要从头再来?
一位 RD 同学 007 地以 5min/条 的速度构造
仍需 14 天才可完成
施压阶段
构造流量难以手动执行
❌ 上下游 mock 不全面导致预期链路没走完
❌ 影子表里的数据没导全导致接口直接报错了
❌ 只准备了几千条数据,还没调整到预期流量阈值压测就结束了
24
25. 深化稳定性建设——全链路压测能力建设解决思路
问题
解决思路
方法
步骤
写流量难以手
动构造 支持写流量录
制和回放 构造的流量可
信度存疑 对压测流量进
行校验 流量可用性验证
上下游 Mock
繁琐且易出错 录制流量时保
留上下游响应 借助 Quake 施压
录制流量时保
留持久层响应 以压测数据中记录
的外部响应进行自
动Mock
影子表数据难
以保证完整
录制真实流量的入
参、上下游响应及
持久层响应
25
26. 深化稳定性建设——事前建设:全链路压测与故障演练的实现
Quake平台
用户
施压
影子 DB
访问
流量回放
Servlet
应用逻辑
故障注入
流量录制
服务间调用
Monkey平台
真实流量 + 数据校验 ≈ 90%准确度
流量录制
流量处理
SDK
数据上传
流量存储服务
流量校验服务
数据下发
流量回放
流量录制
ORM(Mybatis)
流量回放
真实入参 + mock出参 = 0请求构造
NoSQL 存
储集群
DB 持久层
26
27. 深化稳定性建设——用户中心流量管理面临的问题
历史上的登录注册突发流量请求情况
秒级突发流量达日常峰值的 60 倍
Jetty线程池
Nginx
扩容时按并发度交付,导致扩容的机器立刻被打挂
常规扩容手段无法应对极端流量
Thread1 Thread2 Thread3
Thread4 Thread5 Thread6
Thread7 Thread8 ThreadN
线程池及 TCP 队列瞬间打满,应用层限流实际无效
常规限流手段在极端流量下无法隔离不同流量间的影响
27
28. 深化稳定性建设——事中建设:快速扩容与流量隔离
自动化整体扩容、整体交付 + 核心调用方应用层物理隔离 = 突发流量可管可控
监测
流量负载监测系统
建立扩容专用隔离集群
应用层流量隔离系统
中心及常驻流量
隔离集群
整体交付
执行扩容
整体扩容完成
中心
一次性扩一个小集群,机器全部 Ready 再开启流量
BG2
隔离集群00 小流量业务A
隔离集群01 核心BG A
隔离集群02 活动流量
隔离集群Retry
弹性缩扩容系统
BG1
…
其他小流量业务
秒杀流量
重试流量
……
按流量、业务属性和耗时敏感度对调用方分级并实行物理隔离
28
29. 深化稳定性建设——持久层存在的潜在风险
请求量与 DB 容量比例关系
DB连接数及串行建连总耗时
14000
12000
2.5n 万QPS
10000
8000
6000
n万QPS极限容量
缓存
DB
4000
2000
0
正常状态
扩容状态
DB连接数(个)
❗ 缓存击穿
❗ 缓存降级
DB 集群被击垮
极限扩容
DB连接建立耗时合计(分钟)
❌ 极限扩容时连接数影响 DB 稳定性
❌ 发布时连接初始化拖长扩容时间
29
30. 深化稳定性建设——事中建设:持久层高可用
核心读服务
稳定机器
异构备用数据源接管 DB 容量外流量
KV 缓存层
流量低于阈值
DB
ORM 动
态代理
SDK
缓存被击穿或降级
时仍99.99%可用
流量高于阈值
基于Cellar的
异构数据源
写入备用数据
一致性校验
主备数据一致
性保障服务
Binlog同步数据
Binlog延迟消费
30
31. 深化稳定性建设——事中建设:持久层高可用
DB 击穿防护 + DB 连接数优化 = 持久层可用性与容灾能力提升
核心读服务
扩容机器
稳定机器
KV 缓存层
缓存正常时 DB 连接
80%为 IDLE 状态
建立 DB 代理服务
低损耗的 Thrift 连接
高损耗的 DB 连接
5*n~20*n >= 3500个连接
DB
5*n~20*n >= 1000个连接
DB 代理服务
少量 DB 连接即可支撑扩容机器请求
5*10~20*10 = 50 ~ 200个连接
应用层大量扩容时
无需瞬间创建大量
DB 连接
31
32. 深化稳定性建设——DB 主从切换带来的问题
需用户重试
主维度写入
Master
MHA Manager
辅维度异步写入
1min
应用服务
主辅维度数据不一致
简易 MQ 异步补偿机制
Slave1
Slave2
❗️ 补偿队列的执行情况需要人工介入
❗️ 手动操作补偿开关造成不一致时间延长
❗️ 主辅维度数据无法确定是否已最终一致
目标:建立一套完善的
自动化补偿机制
32
33. 深化稳定性建设——事后建设:DB 补偿机制强化
主从切换
写入
旧主
新主
应用服务
核心读服务A
辅维度补偿
MQ
核心读服务B
登录注册服务
收
集
信息管理服务
核心读服务C
……
分
析
✅ DB 切换期间 0 研发人力投入
✅ DB 辅维度补偿 0 延迟
✅ DB 主辅维度 100% 最终一致
DB切换稳定性保障服务
补偿
DB监控报警聚合服务
DB数据校验服务
RD
33
34. 账号系统介绍
单体服务之痛
步步为营的性能优化
系统稳定性的超前建设
技术架构的未来展望
34
35. 未来展望——完全异步化
IO密集型的同步模型性能和吞吐量难以进一步优化
解析入参
获取关键数
据A
解析
入参B
获取和处
理内部数
据
获取和处理关
键数据B
根据判断
逻辑情况
返回错误
读服务同步处理链路
线程资源高占用
负载高
整体吞吐量低 极限容量未压榨
尽CPU算力
容量低 资源浪费
35
36. 未来展望——完全异步化
采用回调实现读逻辑的全链路异步化
异步上下文
解析入参
获取关键
数据A
解析入参
B
获取和处
理内部数
据
获取和处
理关键数
据B
根据判断
逻辑情况
返回错误
读服务异步处理链路
线程资源浪费
负载高
整体吞吐量高 极限容量已压榨
尽CPU算力
容量高 高资源利用率
代码可读性极差
回调地狱
36
37. 未来展望——完全异步化
将异步方案改进为采用 Kotlin 协程
回调Complete
回调Complete
回调Complete
await
await
回调Complete
回调Complete
await
await
await
异步上下文
解析入参
获取关键数
据A
解析
入参B
获取和处理关
键数据B
获取和处
理核心内
部数据
根据判断
逻辑情况
返回错误
读服务协程同步处理链路
线程资源占用低
协程开销极小
整体吞吐量高 极限容量已压榨
尽CPU算力 可读性与同步实
现差异不大
容量高 高资源利用率 语言级async/await支持
37
38. 38
39. 招聘&活水:后端研发工程师
邮箱:yangyuchen03@meituan.com
me@easonyang.com
更多技术干货
欢迎关注“美团技术团队”
39