基於POSTFIX的服務器框架的服務器程序設計

1、 概述       在當今網絡應用中,各類開源服務器可謂遍地開花。Web服務器如 Apache、AOL-Server、Lighttpd等;數據庫服務器如:Mysql、PostgreSQL;MTA服務如Postfix、 Sendmail、Qmail等;HTTP代理服務器有Squid、Oops等。每一類服務器的設計都比較複雜且相關性較強,它們所用的服務器框架通用性不夠,很難提煉出來,造成相對獨立的服務器框架,供程序員快速開發本身的項目。在咱們習慣了JAVA、.NET、PHP等快速開發帶給咱們的快樂時,卻逐漸地遠離的程序設計的本質,結果是知其然面不知因此然。好的開發框架及開發工具當然大大提升了軟件生產率,但卻容易使程序員浮於表面,沒法深刻,當須要設計開發更加高效、安全的服務器程序時,令不少人一愁莫展。     本文講述了以Postfix(http://www.postfix.org/)的服務器框架爲基礎的半駐留進程池服務器的設計模式,通過本人整理,將其歸入ACL庫中,作爲ACL基礎庫中進程池服務器框架部分的核心。若是你很是熟悉 Postfix的框架設計,那麼本節的內容對於你來講很是容易接受,固然,若是你不曾接觸過postfix,也不要緊,經過本文,你能夠很是方便快捷地建立基於高級服務器框架之上的應用服務器程序:簡單、高效、安全、可擴展性好等。 2、ACL進程池服務器框架概述   開發CGI程序、用過 inetd/xinetd的技術人大概應知道,本身所寫的程序少有網絡通訊過程,基本上全部的IO操做都是基於標準IO(stdin, stdout, stderr)進行的,一切來得是那樣簡單,由於後臺的服務器框架程序(如開發CGI時用的Apache)幫咱們處理了複雜的網絡通訊過程。ACL的進程池服務器框架進行開發也是如此,可是提供了更大的靈活性,同時更加高效。ACL進程池服務器框架有以下特色:     a、用戶直接與網絡鏈接進行網絡通訊操做,但操做的接口是通過ACL庫封裝的更加靈活、豐富的函數接口;     b、進程池是動態可調的,只需在配置文件中設置進程池中的最大進程數,則ACL進程框架便自動根據應用負載狀況調整工做進程數量;     c、進程池中的工做進程是半駐留的(這也是Postfix進程池的一大特點),當網絡負載較高時,進程池中的每一個工做進程可能都在工做,負載逐漸降低時,進程池中的工做進程並不當即退出,而是要空閒一段時間至超時,在超時以前又有新的會話鏈接到達時,其中的一個空閒進程便被服務器框架喚醒處理新鏈接,若是某些工做進程在超時時依然未接到新的處理任務則會自動退出。這即是半駐留進程池的特色:並不一直駐留內存等待新任務。這種設計的好處是:任務負載高時,進程池中的每一個工做進程在處理完上一個任務能夠當即處理新的任務,這樣大大下降了建立新進程的開銷;當任務負載較低時,工做進程在空閒必定時間後便自動退出,從而下降了資源浪費,同時也儘可能避免了開發人員的應用程序自己的一些內存泄漏隱患(固然,開發人員應儘可能避免內存泄漏問題);     d、半駐留的進程池有多種控制條件使工做進程處於半駐留狀態:空閒時間、任務處理最大上限等;   ACL進程池服務器框架有一個後臺守護進程(acl_master),該進程處於長駐留狀態,監聽着其所管理着的工做進程的對外服務的全部端口。當有新的客戶端鏈接到達時,acl_master並不具體處理該鏈接,而是建立一個新的工做進程或「讓」處於空閒狀態的工做進程接管該鏈接並進行處理。acl_master與半駐留進程池中的工做進程之間是管理與被管理的關係,同時又是一種協做關係,由於acl_master並不象真正的操做系統那樣能夠任意調度哪一個工做任務(大多經過中斷進行任務時間片的分配),acl_master沒有那種權限功能;在進程池中沒有工做進程或進程池中的全部進程都處於忙碌狀態時,若是整個進程池中工做進程的數量未超過配置中規定的最大值,acl_master便會建立新的工做進程來處理新到任務;當進程池中有空閒工做進程而又有新鏈接到達時,則acl_master知道有空閒進程存在,因此不會插手任務處理過程,此時,進程池中的空間工做進程阻塞在某一個 accept() 調用(或某一個鎖)上,這時由操做系統具體將該新到鏈接分配給某一個工做進程,該工做進程便通知acl_master本身目前已處於忙狀態,因而 acl_master便在其所維護的工做進程池的表中標記該工做進程的狀態爲忙狀態。   小結,ACL進程池服務器框架應由兩部分組成:acl_master後臺守護管理進程與半駐留式工做進程池。acl_master負責任務分配及工做進程池的管理與維護;工做進程池中的工做進程負責具體的客戶端鏈接請示與任務處理。 3、ACL進程池服務器所支持的工做進程框架模板   由於ACL的進程池服務器框架模型是基於Postfix進行修改的,因此首先你們須要知道原Postfix的工做進程框架模板有哪些被ACL所採納。     a、single模板:該工做進程框架爲開發者提供了開發服務器程序的函數接口,它的特色是每一個工做進程在同一時刻最多僅能處理一個客戶端鏈接;     b、multi模板:它的特色是每一個工做進程能夠同時處理多個併發鏈接,固然開發者在用此接口時須要在網絡IO操做中採起非阻塞的方式,以避免形成某工做進程在阻塞地讀一個鏈接的數據時,而延遲了對其它網絡鏈接的處理過程,從而形成性能上的極大下降;     c、trigger模板:它的特色是定時觸發一個工做任務,能夠把它與UNIX下的CRON功能相類比。   除以工做進程框架模板外,另外還增長了其它兩個與線程池相結合的工做進程框架模板,以下:     a、listener模板:該模板容許與線程池相結合,從而使一個工做進程能夠同時處理多個鏈接,而每一個鏈接則由該進程內線程池的某個線程進行處理(目前已不繼續開發了);     b、ioctl模板:該模板是listener模板的進一步改良,使工做進程與工做線程池結合的更加緊密,直接在工做進程的模板內嵌入了工做線程池句柄。   d、aio模板,將異步IO處理過程嵌入至工做進程模板中,從而更加高效地處理大併發網絡鏈接的狀況,其事件觸發機制採用類型於squid, lighttpd, ircd 等相似的非阻塞服務器的模式。 4、使用ACL進程池服務器框架   有時爲了讓他人明白本身所講的話,演講人總會因惟恐別人不明白而特地講得羅羅嗦嗦,豈不知此時觀衆已經被給繞暈至昏昏欲睡了,哈,希望閣下看了以上長篇累牘的描述後依然保持頭腦清醒,精神抖擻。OK,下面讓咱們從實例入手,看看怎樣用ACL進程池框架編寫本身的應用服務器程序。     a、編譯併發布ACL進程池服務器框架   首先,須要編譯acl_master守護進程,其實很簡單,只須要以下步驟便可:     cd acl_project/; make all; make install     則在 acl_project/dist/master/libexec/linux32(以32位LINUX爲例) 目錄下生成 acl_master 可執行程序     cd dist/master; chmod 755 setup.sh; ./setup.sh /opt/acl     則在 /opt/acl/ 目錄下存在以下目錄:     libexec 目錄:該目錄下存放了 acl_master 程序及其它與具體應用相關的工做進程程序;     conf 目錄:該目錄下存放了 acl_master 的配置文件 main.cf 及工做進程程序的配置文件的存放目錄 service/ ;     var 目錄: 該目錄下有兩個了目錄 log (存放日誌的位置) 及 pid (存放運行進程進程號的位置),同時該 var 目錄又是ACL進程池服務框架的默認運行路徑;     sbin 目錄:該目錄下僅有兩個比較簡單的啓動與中止腳本,它們來控制整個ACL進程池服務的啓動與中止過程。     b、編寫你的工做進程代碼併發布,參考 快速建立你的服務器程序--single進程池模型;     c、修改配置文件、啓動與中止整個進程池框架。 5、ACL進程池服務器框架配置說明   ACL進程池服務器框架有本身的配置文件格式及命名規範,它是你正確使用ACL進程池框架不可或缺的一部分,ACL進程池構架的開發者及維護者應熟練掌握這些格式與規範。下面就這些文件格式及命名規範一一說明。 5.1)main.cf 配置文件   該文件爲 acl_master 守護進程的主配置文件,目前經常使用的配置項的含義以下:     daemon_directory:指定用戶所寫的工做進程可執行程序的存入目錄,acl_master 會在該路徑下搜索工做進程程序;     log_file:acl_master 的日誌文件全路徑名;     config_directory:工做進程程序的配置文件存放目錄,acl_master 會讀取該目錄下全部有效的配置文件中並分析全部以 master_ 開頭的配置項,注:以 master_ 開頭的配置項爲保留配置項的命名規範;     queue_directory:acl_master 進程及全部的工做進程的運行時所在路徑;     pid_file:acl_master 進程的進程號的存儲文件。 5.2)工做進程的配置文件   在 config_directory 所指的目錄下,存放着各個工做進程的配置文件,acl_master 會首先讀取該配置進行分析,與 acl_master 相關的配置項的含義以下:     master_disable:acl_master 是否要啓動該工做進程所提供的對外服務(便是否會監聽該配置文件中指定的監聽端口),變量值有兩個,yes 或 no。yes: 禁止該服務工做進程提供的服務;no:容許啓動該服務工做進程;     master_service:服務工做進程所監聽的地址及端口,格式爲:[ip:]port,如:127.0.0.1:30080, :30080, 30080;     master_type:網絡服務類型,目前通常爲 inet 類型;     master_maxproc:服務工做進程的最大進程數;     master_command:服務工做進程的程序名,若是 master_disable 的配置內容爲 no,則 acl_master 會在 main.cf 中 daemon_directory配置項指定的目錄下搜索 master_command 配置項指定的服務工做進程程序名;     master_log:該服務工做進程的日誌文件名;   如下的配置與工做進程各個框架模板相關的配置項,以 xxx_開頭,其中,xxx 能夠爲:single,multi,trigger, listener,ioctl, aio。下面以 single_server 工做進程框架模板爲例進行說明:     single_use_limit:服務工做進程處理事務的次數,若是爲0則代表該服務工做進程長駐留內存,一直提供服務;若是大於0,則當該服務工做進程處理事務的次數達到此值後會自動退出;     single_pid_dir:服務工做進程的進程號的存放路徑;     single_queue_dir:服務工做進程的運行路徑;     single_rw_timeout:服務工做進程進行IO操做的超時時間,單位爲秒;     single_buf_size:服務工做進程進行IO操做時所用的 ACL_VSTREAM 庫函數的緩存大小;   除了以上的保留的配置項外,用戶能夠定義本身的配置項於該配置文件中,而後經過參數傳遞由服務器模板得到本身所要的參數。 我的微博:http://weibo.com/zsxxsz acl 庫的下載地址:http://www.sourceforge.net/projects/acl/ github:https://github.com/zhengshuxin/acl QQ 羣:242722074
相關文章
相關標籤/搜索