用 acl::master_aio 类编写高并发非阻塞服务器程序
? ? ? 在文章《使用 acl::master_threads 类编写多进程多线程服务器程序》和《使用 acl::master_proc 类编写多进程服务器程序》中分别讲述了如何编写 LINUX 平台下阻塞式服务器程序的多线程和多进程方式。虽然这两种模式都可以处理并发任务,并且效率也不低,但是毕竟线程和进程资源是操作系统的宝贵资源,如果要支持非常高的并发请求,则会因为系统限制而不能创建更多的进程或线程。大家常见的 webserver Nginx 就是以支持高并发而闻名,Nginx 本身就是非阻塞设计的典型应用,当然还有很多其它服务器程序也是非阻塞的:ircd、Squid、Varnish、Bind 等。
? ? ? 因为非阻塞程序编写有一定难度,所以现在有人在写非阻塞程序时不得不转向 Erlang、Nodejs 等一些脚本式语言,要想用 C/C++ 来实现非阻塞程序还是有些难度:系统级 API 过于底层、容易出错、难于调试。虽然也有一些 C++ 库(象ACE)提供了非阻塞库,但这些库的入门门槛还是挺高的。根据本人多年在非阻塞编程方面的经验,总结出一套比较实用的 C/C++ 非阻塞函数库,本文就讲述如果使用 acl_cpp 库中的 master_aio 类来编写非阻塞服务器程序(该服务器程序可以规定启动最大进程的个数,其中每个进程是一个独立的非阻塞进程)。在文章《非阻塞网络编程实例讲解》中给出了一个非阻塞网络程序的示例,您可以参考一下。
? ? ? 一、类接口定义
? ? ??master_aio 是一个纯虚类,其中定义的接口需要子类实现,子类实例必须只能创建一个实例,接口如下:
?
# 用 select 进行循环时的时间间隔# 单位为秒aio_delay_sec = 1# 单位为微秒aio_delay_usec = 500# 采用事件循环的方式: select(default), poll, kernel(epoll/devpoll/kqueue)aio_event_mode = select# 是否将 socket 接收与IO功能分开: yes/no, 如果为 yes 可以大大提高 accept() 速度aio_accept_alone = yes# 线程池的最大线程数, 如果该值为0则表示采用单线程非阻塞模式.aio_max_threads = 0# 每个线程的空闲时间.aio_thread_idle_limit = 60# 允许访问的客户端IP地址范围aio_access_allow = 10.0.0.1:255.255.255.255, 127.0.0.1:127.0.0.1# 当 acl_master 退出时,如果该值置1则该程序不等所有连接处理完毕便立即退出aio_quick_abort = 1?
? ? ? 例如当 acl_master 服务器框架程序的安装目录为:/opt/acl,则:
? ? ? /opt/acl/libexec: 该目录存储服务器程序(acl_master 程序也存放在该目录下);
? ? ? /opt/acl/conf:该目录存放 acl_master 程序配置文件 main.cf;
? ? ? /opt/acl/conf/service:该目录存放服务子进程的程序配置文件,该路径由 main.cf 文件指定;
? ? ? /opt/acl/var/log:该目录存放日志文件;
? ? ? /opt/acl/var/pid:该目录存放进程号文件。
? ? ? 该程序编译通过后,需要把可执行程序放在 /opt/acl/libexec 目录下,把配置文件放在 /opt/acl/conf/service 目录下。
? ? ? 在 /opt/acl/sh 下有启动/停止 acl_master 服务进程的控制脚本;运行脚本:./start.sh,然后请用下面方法检查服务是否已经启动:
? ? ? ps -ef|grep acl_master # 查看服务器控制进程是否已经启动
? ? ? netstat -nap|grep LISTEN|grep 5001 # 查看服务端口号是否已经被监听
? ? ? 当然,您也可以查看 /opt/acl/var/log/acl_master 日志文件,查看服务进程的启动过程及监听服务是否正常监听。
?
? ? ? 可以命令行如下测试:telnet 127.0.0.1 8888
? ? ? ?原文地址
? ? ? ?acl_cpp 下载
???????acl_cpp 的编译与使用
? ? ? ?更多文章
?
?
?