当前位置 博文首页 > 好习惯成就伟大:libevent 多线程实现高并发

    好习惯成就伟大:libevent 多线程实现高并发

    作者:[db:作者] 时间:2021-07-09 18:55

    当你看到这篇文章时,想必你对libevent已经有了足够的了解,笔者在此就不多做描述了,直接进入正题。


    1.起因

    最近在做Redis中间件,目标实现集群管理、分布式数据处理、高性能。由于在某些情况下,单个节点的Redis性能可能无法满足需求,并且单个机器的内存大小是受限制的。如果采用中间件的方式管理多个Redis实例,不仅可以避免单点机器内存不够用的情况,也能使性能得到大幅提升。经过Redis中间件数据分片后,各个Redis实例可以同时处理读写请求,所以比单线程的Redis实例要快很多。在这里,中间件起到数据转发及管理的功能,特别是数据转发这一块,对中间件的处理能力要求比较高,在高并发情况下也能保证数据正常处理,不能影响业务使用。


    2.实现

    要实现高性能的服务端网络程序,基本上是异步处理网络IO+多线程。关于异步处理网络IO,网络上现成的库有很多,如果你喜欢动手,自己封装也行。不过我还是建议大家使用已经造好的、成熟稳定的轮子。在这里我比较推荐使用libevent,这个库相对来说比较成熟,使用起来也简单。


    3.架构图

    在这个架构模型中,我们开启了N个线程,每个线程中包含一个event_base对象,他们都是在自己的线程中工作。何时派发工作给这些工作线程,则由一个专门的AcceptThread线程来完成。这个线程负责接受客户端的连接,接受成功后会将该连接分配给工作线程。在这里我们采用均衡分配的方式,让每个线程处理的连接数是趋于相等的。


    4.代码流程

    首先要让libevent支持多线程,需要加上一段代码,这段代码只需要执行一次

    #ifdef WIN32
    ? ? ? ? evthread_use_windows_threads();
    #else
    ? ? ? ? evthread_use_pthreads();
    #endif


    第一步:创建一个WorkThread线程池,每个线程对象中包含一个event_base对象,由于没有事件的话event_dispatch函数会退出,我们可以在里面注册一个永久的定时器事件,这样每个工作进程就不会退出。这个时候的状态是:等待外部给这个工作线程添加事件。


    第二步:主线程监听端口,接受客户端连接。每到来一个连接就形成一个ConnectContext的结构,然后分配到一个工作线程去完成读写操作。这个过程不需要我们去加锁,libevent内部已经完成了这个操作。我们只需要在AcceptThread中派发任务给工作线程就可以了。


    第三步:没了,按照这个架构,大部分代码就是写处理数据的代码了。
    ————————————————
    版权声明:本文为CSDN博主「被遗忘de角落」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/loydia/article/details/78683558

    cs