基于线程池、消息队列和epoll模型实现并发服务器架构

引言

并发是什么?企业在进行产品开发过程当中为何须要考虑这个问题?想象一下天猫的双11和京东的618活动,一秒的点击量就有几十万甚至上百万,这么多请求一会儿涌入到服务器,服务器须要对这么多的请求逐个进行消化掉,假如服务器一秒的处理能力就几万,那么剩下的不能及时获得处理的这些请求做何处理?总不能让用户界面一直等着,所以消息队列应运而生,全部的请求都统一放入消息队列,工做线程从消息队列不断的消费,消息队列至关于一个缓冲区,可达到解藕、异步和削峰的目的。html

Kafka、ActiveMQ、RabbitMQ和RockerMQ都是消息队列的典型,每一种都有其自身的优点和劣势。本文我用本身编写的Buffer类模拟消息队列,若是是企业级须要上线的应用,通常都是基于业界已有的MQ框架上开发。git

需求原型

  1. N个Client从标准输入接收数据,而后接二连三的发送到Server端;
  2. Server端接收来自每一个Client的数据,将数据中的小写字母所有转换成大写字母,其余字符保持不变,最后把转换结果发送给对应的Client。

需求分解

  1. 拿到需求,第一步要作的就是分析需求并选择合适的设计架构,考虑到Server须要和Client进行通讯,Client来自四面八方,端对端通讯天然选择TCP,所以Server端须要可以监听新的链接请求和已有链接的业务请求;
  2. 又因为Server须要响应多个Client的业务请求,咱们但愿把业务处理交给Server端的工做线程(消费者)来作;
  3. 同时还须要一个IO线程负责监听Socket描述符,当IO线程监听到已有链接的业务请求时,当即把请求内容封装成一个任务推入消息队列尾;
  4. IO线程与工做线程互斥访问消息队列,固然工做线程消费一个任务或者IO线程添加一个任务都须要通知对方,也就是同步;
  5. 工做线程处理完毕后,把处理结果交给IO线程,由IO线程负责把结果发送给对应的Client,也就是IO线程与工做线程的分离,这里工做线程通知IO线程的方式我用eventfd来实现;
  6. 咱们但愿引入Log4cpp记录服务端的日志,并可以保存到文件中;
  7. 分析完这些,一个总体架构和大致的样子在脑海中就已经造成了,接着就须要编写设计文档和画流程图、类图和时序图了。

详细设计文档

1.UML静态类图:github

2.UML动态时序图:编程

效果

1.如图,开了三个Client,运行结果正确:bash

2.Server端经过Log4cpp把日志写到文件中:服务器

源码获取

https://github.com/icoty/cs_threadpool_epoll_mq网络

目录结构

.
├── client                   // 客户端Demo
│   ├── Client.cc
│   ├── Client.exe
│   ├── client.sh    // 进入该目录下启动Client Demo: sh client.sh
│   ├── Log4func.cc // 引入日志模块从新疯转
│   ├── Log4func.h
│   └── Makefile     // 编译方式:make
├── conf
│   └── my.conf // IP,Port配置文件, 从这里进行修改
├── include // 头文件
│   ├── Configuration.hpp // 配置文件,单例类,my.conf的内存化
│   ├── FileName.hpp // 全局定义,Configuration会用到
│   ├── log // 日志模块头文件
│   │   └── Log4func.hpp
│   ├── net // 网络框架模块头文件
│   │   ├── EpollPoller.hpp
│   │   ├── InetAddress.hpp
│   │   ├── Socket.hpp
│   │   ├── SockIO.hpp
│   │   ├── TcpConnection.hpp
│   │   └── TcpServer.hpp
│   ├── String2Upper.hpp // 工做线程转换成大写实际走的这里面的接口
│   ├── String2UpperServer.hpp // Server端的整个工厂
│   └── threadpool // 线程池、锁、条件变量和消息队列的封装
│       ├── Buffer.hpp
│       ├── Condition.hpp
│       ├── MutexLock.hpp
│       ├── Noncopyable.hpp
│       ├── Pthread.hpp
│       ├── Task.hpp
│       └── Threadpool.hpp
├── log // Server端的日志经过Log4cpp记录到这个文件中
│   └── log4test.log
├── Makefile // 编译方式:make
├── README.md 
├── server // server端Demo
│   ├── server.exe
│   └── server.sh // 进入该目录下启动Server Demo:sh server.sh
└── src // 源文件
    ├── Configuration.cpp
    ├── log
    │   └── Log4func.cpp
    ├── main.cpp
    ├── net
    │   ├── EpollPoller.cpp
    │   ├── InetAddress.cpp
    │   ├── Socket.cpp
    │   ├── SockIO.cpp
    │   ├── TcpConnection.cpp
    │   └── TcpServer.cpp
    ├── String2Upper.cpp
    ├── String2UpperServer.cpp
    └── threadpool
    ├── Buffer.cpp
    ├── Condition.cpp
    ├── MutexLock.cpp // MutexLockGuard封装
    ├── Pthread.cpp
    └── Threadpool.cpp

参考文献

[1] UNIX环境高级编程第3版
[2] cpp reference
[3] UML时序图
[4] Log4cpp官网下载
[5] Log4cpp安装架构

相关文章
相关标签/搜索