协做半驻留式服务器程序开发框架 --- 基于 Postfix 服务器框架改造

1、概述

     如今你们在和Java, PHP, .net写应用程序时,都会用到一些成熟的服务框架,因此开发效率是比较高的。而在用C/C++写服务器程序时,用的就五花八门了,有些人用ACE, 有些人用ICE(号称比ACE强许多),等等,这类服务器框架及库比较丰富,但入门门槛比较高,因此更多的人是本身直接写服务器程序,初始写时以为比较简 单,可时间久了,便会以为难以扩展,性能低,容易出错。其实,Postfix 做者为咱们提供了一个高效、稳定、安全的服务器框架模型,虽然Postfix主要用做邮件系统的 mta,但其框架设计却很是具备通用性。ACL(http://acl.sourceforge.net/) 的做者将Postfix的服务器框架模型抽取出来,造成了更加通用的服务器程序开发框架,使程序员在编写服务器程序时能够达到事半功倍的效果。本文主要介 绍了ACL中acl_master服务器程序(基于Postifx服务器程序框架)的设计及功能。git

 2、框架设计图程序员

      以下图所示:github

图1--框架图编程

       master主进程为控制进程,刚启动时其负责监听全部端口服务,当有新的客户端链接到达时,master便会启动子进程进行服务,而本身依然监控服务端 口,同时监控子进程的工做状态;而提供对外服务的子进程在master启动时,若没有请求任务则不会被启动,只有当有链接或任务到达时才会被master 启动,当该服务子进程处理完某个链接服务后并不当即退出,而是驻留在系统一段时间,等待可能的新链接到达,这样当有新的链接到达时master就不会启动 新的子进程,由于已经有处于空闲的子进程在等待下一个链接请求;当服务子进程空闲时间达必定阀值后,就会选择退出,将资源所有归还操做系统(固然,也能够 配置成服务子进程永不退出的模式)。所以,能够称这种服务器框架为协做式半驻留式服务器框架,下面将会对协做式和半驻留做进一步介绍。安全

 3、协做方式服务器

  Postfix服务器框架设计的很是巧妙,由于master毕竟属于用户空间进程,不能象操做系统那样能够控制每一个进程的运行时间片,因此master主进程必须与其服务子进程之间协做好,以处理好如下几个过程:网络

  1)新链接到达时,master是该启动新的子进程接管该链接仍是由空闲子进程直接接管多线程

  2)master什么时候应该启动新的子进程并发

  3)新链接到达,空闲子进程池中的子进程如何竞争接管该链接框架

  4)子进程异常退出时,master如何处理新链接

  5)空闲子进程如何选择退出时间(空闲时间或服务次数应决定子进程的退出)

  6)master如何知道各个子进程的工做状态(是死了仍是活着?)

  7)在不中止服务的前提下,服务子进程程序若是在线更新、如何添加新的服务、如何在线更新子进程配置

  8)如何减小全部子进程与master之间的通信次数从而下降master的负载

 4、流程图

 1)  master主进程流程图

 

图2--master进程流程图

   Postifx 中的 master 主进程与各个子进程之间的IPC通信方式为管道,因此管道的个数与子进程数是成正比的。若是管道中断,则 master 认为该管道所对应的子进程已经退出,若是是异常退出,master还须要标记该服务类子进程池以防止该类子进程异常退出频繁而启动也异常频繁(若是子进程 启动过于频繁则会给操做系统形成巨大负载);另外,若是某类服务的子进程在服务第一个链接时就异常退出,则master认为该服务有多是不可用的,因此 当有新的链接再到达时就会延迟启动该服务子进程。

  当服务子进程池中有空闲子进程时,master便会把该服务端口的监听权让出,从而该服务 的空闲子进程在该服务端口上接收新的链接。当某个子进程得到新的链接后便会当即通知master其已经处于忙状态,master便当即查找该服务的子进程 进程池还有无空闲子进程,若是有则master依然不会接管该服务端口的监放任务;若是没有了,则master当即接管该服务端口的监放任务,当有新的连 接到达时,master先检查有没有该服务的空闲进程,如有便让出该服务端口的监听权,若没有便会启动新的子进程,而后让出监听权。

 2)  服务子进程流程图

图3--子进程流程图

      在master主进程刚启动时,由于没有任何服务请求,因此子进程是不随master一块儿启动的,此时全部服务端口的监控工做是由master统一负责, 当有客户端链接到达时,服务子进程才由master启动,进而接收该新链接,在进一步处理客户端请求前,子进程必须让master进程知道它已经开始" 忙"了,好由master来决定是否再次接管该服务端口的监控任务,因此子进程首先向master发送“忙”消息,而后才开始接收并处理该客户端请求,当 子进程完成了对该客户端的请求任务后,需向master发送“空闲”消息,以代表本身又能够继续处理新的客户端链接任务了。这一“忙”一“闲”两个消息, 便体现了服务子进程与master主进程的协做特色。

      固然,服务子进程能够选择合适的退出时机:若是本身的服务次数达到配置的阀值,或本身空闲时间达到阀值,或与master主进程之间的IPC管道中断(一 般是由master中止服务要求全部服务子进程退出时或master要求全部服务子进程重读配置时而引发的),则服务子进程便应该结束运行了。这个中止过 程,一方面体现了子进程与master主进程之间的协做特色,另外一方面也体现了子进程半驻留的特色,从而体现子进程进程池的半驻留特性,这一特性的最大好 处就是:按需分配,当请求链接比较多时,所启动运行的子进程就多,当请求链接任务较少时,只有少数的子进程在运行,其它的都退出了。

  3) 小结

      以上从总体上介绍了Postfix服务器框架模型中master主进程与服务子进程的逻辑流程图,固然,其内部实现要点与细节远比上面介绍的要复杂,只是 这些复杂层面别人已经帮咱们屏蔽了,咱们所要作的是在此基础上写出本身的应用服务来,下面简要介绍了基于Postfix的服务器框架改造抽象的ACL库中 服务器程序的开发方式,以使你们比较容易上手。

 5、五种服务器框架模板简介

      要想使用ACL服务器框架库开发服务器程序,首先介绍两个个小名词:acl_master服务器主进程与服务器模板。acl_master服务器主进程与 Postfix中的master主进程功能类似,它的主要做用是启动并控制全部的服务子进程,这个程序不用咱们写,是ACL服务器框架中已经写好的;所谓 服务器模板,就是咱们须要根据本身的须要从ACL服务器框架中选择一种服务器模型(即服务器模板),而后在编写服务器时按该服务器模板的方式写便可。为什 么还要选择合适的服务器框架模板?这是由于Postfix自己就提供了三类服务器应用形式(单进程单链接进程池、单进程多链接进程池、触发器进程池),这 三类应用形式便分别使用了Postfix中的三种服务器模板,此外,ACL中又增长了两种服务器应用形式(多线程进程池、单进程非阻塞进程池)。下面分别 就这五种服务器框架模板一一作简介:

      1) 单进程单链接进程池:由 acl_master 主进程启动多个进程组成进程池提供某类服务,但每一个进程每次只能处理一个客户端链接请求

      2) 单进程多链接进程池:由 acl_master 主进程启动多个进程组成进程池提供某类服务,而每一个进程能够同时处理多个客户端链接请求

      3) 触发器进程池:由 acl_master 主进程启动多个进程组成进程池提供定时器类服务(相似于UNIX中的cron),当某个定时器时间到达时,便由一个进程开始运行处理任务

      4) 多线程进程池:由 acl_master 主进程启动多个进程组成进程池提供某类服务,而每一个进程是由多个线程组成,每一个线程处理一个客户端链接请求

      5) 单进程非阻塞进程池:由 acl_master 主进程启动多个进程组成进程池提供某类服务,每一个进程能够并发处理多个链接(相似于Nginx, Lighttpd, Squid, Ircd),因为采用非阻塞技术,该模型服务器的并发处理能力大大提升,同时系统资源消耗也最小;固然,该模型与单进程多链接进程池采用的技术都是非阻塞 技术,但该模型进行更多的应用封装与高级处理,使编写非阻塞程序更加容易

       以上五种服务器方式中,因为能够根据须要配置成多个进程实例,因此能够充分地利用多核的系统。其中,第5种的运行效率是最高的,固然其编程的复杂度要比其 它的高,而第1种是执行效率最低的,其实它也是最安全的(在Postfix中的smtpd/smtp 等进程就属于这一类),而相对来讲, 第4种在运行效率与编写复杂度方面是一个比较好的折衷,因此在写通常性服务器时,该服务器模型是做者推荐的方案,此外,第4种方案还有一个好处,能够作到 对于空链接没必要占用线程,这样也大大提供了并发度(即线程数能够远小于链接数)。

 6、使用简介

      本节暂不介绍具体的编程过程,只是介绍一些配置使用过程。假设已经写好了服务器程序:echo_server, 该程序能够采用上面的 1), 2), 4), 5) 中的任一服务器模型来写,假设采用了第4)种;另外,还假设:acl_master等全部文件安装的根目录为 /opt/acl/, 主进程程序 acl_master 及 echo_server 安装在 /opt/acl/libexec/,  acl_master 主程序配置文件安装在 /opt/acl/conf/,echo_server 配置文件安装在 /opt/acl/conf/service/, 日志文件目录为 /opt/acl/var/log/, 进程号文件目录为 /opt/acl/var/pid/。好比,你让 echo_server 的服务端口为 6601,服务地址为 127.0.0.1, 它只是提供简单的 echo 服务。

      你能够运行 /opt/acl/sh/start.sh 脚原本启动 acl_master 主进程(用 ps -ef|grep acl_master 会看到 acl_master 进程存在 ,但 ps -ef|grep echo_server 却没有发现它的存在),而后你在一个Unix终端上 telnet 127.0.0.1 6601, 在另外一个终端上 ps -ef|grep echo_server 就会发现有一个 echo_server子进程了,而后在 telnet 6601 的终端上随便输入一些字符串,便会当即获得回复,关闭该 telnet 链接,用 ps -ef|grep echo_server 会发现该进程依然存在,当再次 telnet 127.0.0.1 6601 时,该echo_server进程又继续为新链接提供服务了。能够试着多开几个终端同时 telnet 127.0.0.1 6601,看看运行效果如何?

      注意,服务子进程的配置文件格式须要与其所采用的模板类型一致;进程池中最大进程个数、进程中线程池最大线程个数、进程最大服务次数、空闲时间等都是能够以配置文件中指定的。

 我的微博:http://weibo.com/zsxxsz

参考文章:

 1) 快速建立你的服务器程序--single进程池模型
 2) 基于POSTFIX的服务器框架的服务器程序设计

 3) 开发多线程进程池服务器程序---acl 服务器框架应用

 4) 利用ACL库快速建立你的网络程序--ACL_VSTREAM 流的使用

 5) 利用ACL库开发高并发半驻留式线程池程序

 下载:http://sourceforge.net/projects/acl/

svn:svn checkout svn://svn.code.sf.net/p/acl/code/trunk acl-code

github:https://github.com/zhengshuxin/acl

相关文章
相关标签/搜索