协程在天猫交易中的实践 田麦协程在天猫交易中的实践• 背景 • 出现的问题 • 解决思路 • 实现方案 • 遇到的挑战 • 效果和反思 背景 — 服务器处理请求模型RPC ClientRPC ClientIO线程IO线程服务提供者容器业务代码二方包RPC ServerRPC ServerRPC ServerRPC ServerRPC ServerRPC 服务 提供者HTTP请求RPC请求背景 — 天猫交易系统特点• 大量外部系统接入 • IO密集,大量RPC调用 • IO调用毫秒级rt • 业务逻辑复杂,但自身计算量不大 出现的问题• 随着外部系统不断接入,系统rt呈线性增长,用户体验变差 • 随着用户的业务数据量的增大,系统rt快速增长– 购物车中商品量 • 上下文切换多,CPU有效利用率低(无法量化) – Perf、dstat测量上下文切换次数 – Lmbench3测量上下文切换时间 解决思路 — 减小RT• 并行处理请求 – 划分出可并行执行的业务单元 – 并行执行没有相互依赖的业务单元 • 并行的粒度 – RPC调用级 – 业务单元级 解决思路 — 减小RT• 并行处理请求 – 划分出可并行执行的业务单元 – 并行执行没有相互依赖的业务单元 • 并行的粒度 – RPC调用级 – 业务单元级 解决思路 — 减少CS• 大量协程,少量工作线程,请求和线程解耦 – Callback/协程框架(akka、node.js)/协程语言(scala、erlang、golang) — 源码级 – 保存和恢复上下文 — 字节码级别(kilim) • 异步IO – 阻塞、非阻塞、同步、异步 – RPC框架的异步支持 解决思路 — 减少CS执行CS等待IO响应CS执行CS等待IO响应CS执行……同步,线程执行序列执行CS等待IO响应CS执行CS等待IO响应CS执行……执行执行执行执行执行……异步,协程/线程执行序列解决思路 — 整体方案业务代码RPC Client服务提供者容器RPC 服务 提供者二方包RPC ClientRPC ServerRPC ServerRPC ServerRPC ServerRPC Server业务工作线程业务工作线程业务工作线程业务工作线程容器工作线程容器工作线程容器工作线程容器工作线程RPC 工作线程远程调用请求HTTP请求RPC 请求IO线程远程调用请求IO线程TTTTTTTTTTTTTT实现方案 — 整体架构 异步+并行化框架异步Web框架并行引擎异步化远程调用代理任务队列工作线程队列WaiDng Task QueueRunning Thread Queue调度器(Scheduler)消息传递通道(Mailbox)任务上下文(Fiber)远程方法回调接口Runnable Task QueueWaiDng Thread Queue异步+并行化支撑框架异步Servlet异步HSF异步TairMINA/NeMy并行化 DSLJava NIO分析验证ASM运行监控代码织入调用分析异步识别实现方案 — 具体实现一• 应用服务器Tomcat7,异步Servlet支持 • Web层异步化 – 异步Servlet(容器支持)、异步Filter – Web框架异步支持,渲染、跳转、错误处理 • RPC框架异步化 – 客户端和服务端是否都要异步化? • IO调用驱动协程调度 实现方案— 具体实现二• 协程管理(Kilim支持) – 任务上下文的备份、恢复(线程栈帧) – 任务调度、线程调度 • Kilim框架与应用的整合 • RPC接口的自动识别和调用链条的织入 • DSL,业务单元并行化编排 • 并行引擎,管理并行任务 遇到的挑战• 泛滥的ThreadLocal,数据是请求级还是线程级?应用层还是框架层? • 线程和锁之间纠缠不清的关系 • 数据依赖识别,并行执行单元划分 • 并行执行情况下,数据并发访问问题 • 开发环境、测试环境、线上环境的一致性 效果和反思• 效果跟应用特点有关 • 异步化后CPU占用稍微有所增加 • 并行化后RT根据应用特点缩减幅度不同,CPU随RT减少而增长 • 多线程并行vs协程并行 – 系统特点 – 两种方案改造成本