微信的技术实现——libco协程设计及实现.docx

微信的技术实现——libco协程设计及实现.docx

  1. 1、本文档共9页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
东南大学多媒体技术 PAGE 9 微信的技术实现——libco协程设计及实现 牧马城市 引言 1.1 libco概述 libco是微信后台大规模使用的C/C++协程库,2013年至今稳定运行在微信后台的数万台机器上,使得微信后端服务能同时支持大量请求,被誉为微信服务器稳定性的基石。libco在2013年的时候作为腾讯六大开源项目首次开源。 ??libco首先能解决CPU利用率与IO利用率不平衡,比用多线程解决IO阻塞CPU问题更高效。因为用户态协程切换比线程切换性能高:线程切换保存恢复的数据更多,需要用户态和内核态切换。其次libco又避免了异步调用和回调分离导致的代码结构破碎。 ??libco采用epoll多路复用使得一个线程处理多个socket连接,采用钩子函数hook住socket族函数,采用时间轮盘处理等待超时事件,采用协程栈保存、恢复每个协程上下文环境。 1.2 libco产生背景 早期微信后台因为业务需求复杂多变、产品要求快速迭代等需求,大部分模块都采用了半同步半异步模型。接入层为异步模型,业务逻辑层则是同步的多进程或多线程模型,业务逻辑的并发能力只有几十到几百。随着微信业务的增长,系统规模变得越来越庞大,每个模块很容易受到后端服务/网络抖动的影响。 为了提升微信后台的并发能力,一般的做法是把现网的所有服务改成异步模型。这种做法工程量巨大,从框架到业务逻辑代码均需要做一次彻底的改造,耗时耗力而且风险巨大。于是微信开发人员开始考虑使用协程。 但使用协程会面临以下挑战: 业界协程在C/C++环境下没有大规模应用的经验; 如何控制协程调度; 如何处理同步风格的API调用,如Socket、mysqlclient等; 如何处理已有全局变量、线程私有变量的使用。 最终微信开发人员通过libco解决了上述的所有问题,实现了对业务逻辑非侵入的异步化改造。使用了libco对微信后台上百个模块进行了协程异步化改造,改造过程中业务逻辑代码基本无修改。至今,微信后台绝大部分服务都已是多进程或多线程协程模型,并发能力相比之前有了质的提升,而libco也成为了微信后台框架的基石。 1.3 协程与线程优缺点对比 协程不能并发,看起来用处不大。在一些耗时操作的时候,例如网络请求,有段时间需要等待请求回来,这种等待其实就是一种CPU资源的浪费。这时候如果有协程,我们可以在等待的时候,在代码里面切换一下,去执行其他操作,等那个请求回来了,我们再切回去执行那个返回的结果,可以更有效率地利用时间。如果是在多线程里面,一个线程的请求没回来,我们可能用一个thread_yield,或者wait的方法,让这个线程休眠,但这样中间就会有一次线程切换,会浪费一些消耗,而协程切换就不会有这个影响,因为在操作系统看来,这全部都是在一个线程里面去完成的。所以这也是协程的最大的优势:协程切换开销远小于线程,进程切换。 设计思想 2.1技术架构 libco在框架分为三层,分别是接口层、系统函数Hook层以及事件驱动层。 2.2协程切换 线程切换缺点 切换代价大(保存恢复上下文、线程调度); 占用资源多 ??线程往往需要对公共数据加锁,锁会导致线程调度。因为用户的线程是在用户态执行,而线程调度和管理是在内核态实现,所以线程调度需要从用户态转到内核态,再从内核态转到用户态。切到内核态时需要保存用户态上下文,再切到用户态时,需要恢复用户态上下文,而线程的用户态上下文比协程上下文大得多。另外线程调度也需要耗时。 ??线程栈默认为1M大于协程栈128K,另外线程还需要各种struct存一些状态,实测每个pthread_create创建的线程大约占8M左右内存,因此线程占用资源也远比协程多。 2.3协程控制 2.3.1 epoll多路复用IO模型 常见的同步调用是同步阻塞模型,异步调用是异步IO模型,而协程控制使用epoll多路复用IO模型。现在以read为例说明以下三种IO模型的区别,read分为两个阶段:一,等待数据;二,将数据从kernel拷贝到用户线程。 ??同步调用read使用同步阻塞IO,kernel等待数据到达,再将数据拷贝到用户线程,这两个阶段用户线程都被阻塞。异步调用read使用异步IO模型,用户线程调用read后,立刻可以去做其它事, kernel等待数据准备完成,然后将数据拷贝到用户内存,都完成后,kernel通知用户read完成,然后用户线程直接使用数据,两个阶段用户线程都不被阻塞。而协程调用read使用多路复用IO模型,用户线程调用read后,第一阶段也不会被阻塞,但第二个阶段会被阻塞,epoll多路复用IO模型可以在一个线程管理多个socket。 同步调用在两个阶段都会阻塞用户线程,因此效率低。虽然可以为每个连接都开个线程,但连接数多时,线程太多导

您可能关注的文档

文档评论(0)

牧马城市 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档