您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > QQ高效团队开发实践:开源毫秒服务引擎的设计与实现
开源毫秒服务引擎的设计与实现QQ团队开发运营实践毫秒思路目录毫秒亮点QQ后台团队演进毫秒功能毫秒思路目录毫秒亮点QQ后台团队演进毫秒功能QQ后台团队演进黄金时代对美好的追求让我们创造了毫秒青铜时代约50人的开发团队,开发运营高度依赖开发和运维白银时代约200人的开发团队,重点服务集中化,开发运营流程规范化模块B的一个实例模块A的一个实例后端模块B基于Tag-Length-Value的二进制协议模块B路由Agent定期获取模块B路由配置更新青铜时代模块A多进程异步框架获取后端B的可用实例模块B路由配置中心名字发现和路由服务每个后端模块提供自己的AgentAgent标准化:目录/配置/共享内存id冲突各个Agent容错能力不一当模块需要调用10+个后端模块时开发/运维集体跳起来了模块A多进程异步框架模块B0路由Agent模块B1路由Agent...模块Bn路由Agent模块A的一台服务器Tag-Length-Value协议根据Tag进行扩展,如获取用户的简单资料请求:dwQQ+wTagNum+wTag1+…+wTagN回包:wTagNum+(wTag1+wLen1+sValue1)+…+(wTagN+wLenN+sValueN)没有IDL化,无法自动生成打解包代码重复代码无法体现程序员的“价值”各种奇葩的bugTag-Length-Value协议charbuf[64]={0};char*p=buf;PACK_PUT_UINT32(p,dwQQ);p+=4;PACK_PUT_UINT16(p,Tags.size());p+=2;for(autoit=Tags.begin();it!=Tags.end();it++){PACK_PUT_UINT16(p,*it);p+=2;}structUserBasicInfo{std::stringsNick;uint16_twFaceId;uint32_tdwBirthDate;};…for(uint16_ti=0;iwTagNum;i++){PACK_GET_TLV(&tlv,p);switch(tlv.tag){//依据Tag反填UserBasicInfo里的字段}}请求根据Tag进行扩展,如获取用户的简单资料请求:dwQQ+wTagNum+wTag1+…+wTagN回包:wTagNum+(wTag1+wLen1+sValue1)+…+(wTagN+wLenN+sValueN)回包异步IO发送//新建一个上下文,用户自行放入更多信息Context*ctx=newContext();//生成唯一seqctx-seq=gen_seq();//后端模块B请求打包,填入seqPackModuleB(ctx-seq,req_str);//通过AgentAPI获取后端模块B的地址GetAddr(ModuleB_ID,&(ctx.srvaddr));//框架异步发包APIAsyncSend(ModuleB_ID,ctx,req_str);回包继续处理//框架异步回包处理流程intHandleResponse(Context*ctx,intiID,void*pPkg,intiPkgLen){if(iID==ModuleB_ID){UnPackModuleB(pPkg,iPkgLen);//逻辑继续处理...}DelContext(ctx);}//框架异步超时处理流程intHandleTimeout(Context*ctx,intiID){}当一个业务逻辑需要调用10+个后端模块时,代码复杂度成几何倍数上升!优点缺点名字发现服务和路由服务服务容错可运维性差;Agent容错能力参差不齐TLV协议可扩展强重复编码异步IO远程调用高性能随业务流程复杂度增加,代码可读性和可维护性随成倍数下降监控和告警业务定制上报;短信和邮件告警监控点、告警点设置依赖开发意识;告警多运维累日志有本地和远程日志;有染色能力定位问题效率低服务路径/命名/配置/工具/文档等没有统一标准开发自由发挥J运维低效青铜时代反思集中化服务白银时代模块A多进程协程框架后端模块BProtobuf协议名字发现和路由Agent模块A的一个实例定期更新后端服务的路由配置获取后端服务的可用实例名字发现和路由服务发布管理统一监控统一日志业务树后端服务扩缩容更新路由模块B的一个实例白银时代反思RPC!RPC!RPC!标准化开发运营体系积重难返集中化服务后端模块BProtobufRPC协议定期更新后端服务的路由配置获取后端服务的可用实例名字发现和路由服务发布管理统一监控统一日志业务树后端服务扩缩容更新路由集中化控制台黄金时代模块A多进程协程RPC框架名字发现和路由Agent模块A的一个实例模块B的一个实例毫秒思路目录毫秒亮点QQ后台团队演进毫秒功能毫秒的设计思路标准化开发运营集中化管理立体化引擎自由与相互伤害过度自由==相互伤害?模块提供独立的名字发现服务路由agent公共逻辑没有抽象或组件化服务目录、配置、工具、文档没有统一标准关键的监控/日志项上报依赖开发意识从控制台下载业务开发代码实现具体业务逻辑毫秒标准化开发rpcGetList(GetListRequest)returns(GetListResponse);制定IDL协议intCMainLogicServiceMsg::GetList(constGetListRequest*request,GetListResponse*response){/***TODO业务逻辑实现,request/response为业务业务定义的protobuf协议格式*业务可使用框架自带的监控系统ATTR_REPORT(test),详见monitor.h*业务可使用框架自带的日志系统NGLOG_DEBUG(test),详见srpc_log.h*/return0;}毫秒标准化开发–RPC调用intCMainLogicServiceMsg::GetList(constGetListRequest*request,GetListResponse*response){::crawl::GetListRequestreq;::crawl::GetListResponseresp;req.set_type(request-type());//后端模块请求包//后端模块返回包//后端模块请求包设置intret=CallMethod(VOA.Crawl,/*后端模块路由名字*/crawl.CrawlService.GetList,/*RPC函数名*/req,resp,/*请求包和返回包反填*/20000,PORT_TYPE_TCP);/*超时时间和网络类型*///ret非0为后端模块收包异常;为0进行后续业务逻辑//…return0;}毫秒标准化部署上传新的业务插件版本制定发布计划进行发布页面展示发布结果#服务标准化部署根目录#C++服务,一级业务名||`--MainLogic|--bin#二级业务名#框架、工具及业务插件路径||`--lib#框架依赖库及业务外部代码库/资源文件#配置文件路径#日志路径#PHP服务,一级业务名||--etc|`--log|--VOA_php|`--MainLogic||--bin|||||--lib`--php#PHP插件路径||--etc|`--log`--agent#集中化服务Agent路径业务服务路径示例/msec|--VOA_cpp集中化管理配置管理协议管理(IDL)外部代码库/资源文件业务版本容量管理服务IP列表扩容/缩容管理发布管理发布版本管理及一键回滚发布列表运营层面业务层面监控集中业务监控单机监控机器基础监控日志集中日志上报立体化引擎立体化引擎–毫秒RPC调用CallMethod(VOA.Crawl,crawl.CrawlService.GetList,req,resp,20000,PORT_TYPE_TCP);通过名字发现和路由服务获取可用实例,并自动容错通过协程发起网络请求,获得和异步调用接近的性能监控上报:请求量,失败率,超时率,平均时延,请求时延区间抽样日志上报,用于展示服务调用关系链RPC调用流程毫秒思路目录毫秒亮点QQ后台团队演进毫秒功能毫秒服务引擎架构名字发现和路由服务远程命令数据传输服务集中化服务管理页面远程agentC++/Java/PHP毫秒开发框架路由agent开发&运维Rediscluster数据服务#1Rediscluster数据服务#2...Rediscluster数据服务#NWeb运维管理服务基于rediscluster的k-v集群监控agent日志agent其中一台业务实例监控服务日志服务集中化控制台毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志intCMainLogicServiceMsg::GetTitles(constGetTitlesRequest*request,GetTitlesResponse*response){::crawl::GetTitlesRequestreq;::crawl::GetTitlesResponseresp;req.set_type(request-type());intret=CallMethod(VOA.Crawl,crawl.CrawlService.GetMP3List,req,resp,20000,PORT_TYPE_TCP);//ret非0为后端模块收包异常;为0进行后续业务逻辑,组response包返回response.set_msg(resp-msg());return0;}毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志毫秒服务引擎展示1.创建新模块,定义IDL2.获取开发代码3.开发并生成插件4.上传插件及外部代码库/资源文件5.制定发布计划6.观察监控和日志毫秒思路目录毫秒亮点QQ后台团队演进毫秒功能毫秒服务引擎亮点• 高性能协程RPC框架• 服务容错• 过载保护• 调用链框图• 多开发语言• KV管理平台高性能协程–微线程框架• 微线程状态机初始化可运行运行中等待• 上下文管理部分寄存器(calleesave)、调用栈,私有栈帧• 事件调度EpollI/O事件驱动无抢占,无优先级结束服务容错模块A模块B实例B1IDC1模块B实例B3IDC3模块B实例B2IDC2模块A轮询调用模块B:如果没有容错:成功率降至66.7%网络中断或实例异常模块A模块B实例B1IDC1模块B实例B3IDC3模块B实例B2IDC2模块A轮询调用模块B:如果实施了容错:成功率维持99.9%+网络中断或实例异常请求上涨50%,那么模块B如果要做到IDC容灾,需要冗余50%实例服务容错策略• 快速屏蔽实例• 通过探测包缓慢增加权重,恢复屏蔽实例• 后端容量计算及过载保护从socket接收缓冲区接收用户请求进行本地逻辑处理发送请求到后端模块B,等待后端模块B返回接收后端模块B的应答应答前端用户,回到步骤1处理下一个请求模块A的处理流程前端用户过载介绍什么是过载?为什么要保护?系统接收缓冲区业务处理逻辑模块B系统发送缓冲区模块A超时时间1s超时时间100ms峰值请求量30/s平均时延20ms过载场景前端用户业务处理逻辑模块B系统接收缓冲区系统发送缓冲区模块A超时超时时间1s超时时间100ms峰值请求量
本文标题:QQ高效团队开发实践:开源毫秒服务引擎的设计与实现
链接地址:https://www.777doc.com/doc-1580074 .html