高並發伺服器的設計–fastcgi的設計

來源:互聯網
上載者:User

伺服器開發中不何或缺的要使用fastcgi,其使用方法如下:

while( FCGI_Accept() >= 0 ){                printf( "Content-type: text/plain \r\n"                "Content-Length: %d\r\n"                "Connection: close\r\n\r\n%s\r\n", strlen( buffer ), buffer );        }

facgcgi 標頭檔有如下宏:

#undef  fprintf#definefprintf  FCGI_fprintf#undef  printf#defineprintf   FCGI_printf

可以看出,已經對printf函數進行了宏轉向,在程式裡的printf 不再是標準輸出了。這樣就有一個問題,如果想調試列印資訊到stdout中,就不行了。

現實開發中,可能會出現各種問題,有時候的確需要列印出一些資訊,這時候可以修改fcgi_stdio.h標頭檔,改成如下:

#undef  _fprintf#define _fprintf  FCGI_fprintf#undef  _printf#define_printf   FCGI_printf

在程式中的相應地方也要換成相應的宏。

fastcgi 的解析可以通過這個函數:

char *getenv(const char *name) 

有如下幾類參數:

CONTENT_TYPE

CONTENT_TYPE 得到請求類型
CONTENT_LENGTH 本文段長度
QUERY_STRING 請求字串

以如下一段HTTP請求報文為例:

GET /s?ie=utf-8&bs=%E8%BF%99%E6%98%AF&f=8&rsv_bp=1&rsv_spt=3&wd=%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%80%E5%8F%91&rsv_sug3=11&rsv_sug=0&rsv_sug4=609&rsv_sug1=2&inputT=32681 HTTP/1.1Host: www.baidu.comConnection: keep-aliveContent-Type: text/html;charset=utf-8Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31Referer: http://www.baidu.com/s?wd=%E8%BF%99%E6%98%AF&rsv_bp=0&ch=&tn=baidu&bar=&rsv_spt=3&ie=utf-8&rsv_sug3=4&rsv_sug=0&rsv_sug4=240&rsv_sug1=3&inputT=2835Accept-Encoding: gzip,deflate,sdchAccept-Language: zh-CN,zh;q=0.8Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3Cookie: BAIDUID=A83324E58AE26486E46FC49ED127891B:FG=1; BDSVRTM=163; H_PS_PSSID=1439_2448_2454_2256_1788_2249; WWW_ST=1369271667063

CONTENT_TYPE 對應第5行,QUERY_STRING 對應第一行。

fastcgi 不是物件導向的,所有的任務都是在主迴圈內完成,包括解析,處理,響應。

在實際的開發中,為了提高效率,開發成員不用關心底層,我將其封裝成一個類:fcgi_net_duty

#ifndef __FCGI_NET_H__#define __FCGI_NET_H__#define FCGI_NET_OK           0#define FCGI_NET_ERROR        1#define FCGI_NET_PARAM_ERROR  2enum fcgi_net_type{        FCGI_NET_TEXT = 0,        FCGI_NET_APP_STREAM,        FCGI_NET_IMAGE,};class fcgi_net_duty{public:        fcgi_net_duty();        ~fcgi_net_duty();        void do_request();protected:        void  do_prev();        void  do_cast();        virtual void  do_handle();        void  do_write();        void  do_finish();        int get_req_int( const char* param, int *value );                int get_req_ll( const char* param, long long *value );        int get_req_str( const char* param, const char **value );        int get_cookie_int( const char* param, int *value );        int get_cookie_ll( const char* param, long long *value );        int get_cookie_str( const char* param, const char **value );private:        std::map< const char*, const char* > m_req;        std::map< const char*, const char* > m_cookie;        int rtn;                int content_type;        int content_length;        char* content_buf;};

主迴圈放在do_request 函數裡

fcgi_net_duty.cpp

void fcgi_net_duty::do_request(){        while( FCGI_Accept() >= 0 ){                do_prev();                do_cast();                do_handle();                do_write();                do_finish();        }}

子類只需要關心相應的業務,每個業務可以用一個子類完成,如現有三個業務:busi1, busi2, busi3,我們以其中一個為例:

fcig_busi1.h

#ifndef __FCGI_BUSI1_H__#define __FCGI_BUSI1_H__class fcgi_busi1 : public fcgi_net_duty{public:         fcgi_busi1();        ~fcgi_busi1();        void do_handle();};#endif //__FCGI_BUSI1_H__

fcgi_busi1.cpp

void fcgi_busi1::do_handle(){        const char* busi1;        int flag;        rtn = FCGI_NET_ERROR;        flag = get_req_str( "busi1", &busi1 );        if( flag ){                rtn = FCGI_NET_PARAM_ERROR;                return;        }        sprintf( content_buf, "%s","your busi is ok" );        rtn = FCGI_NET_OK;}int main(){        fcgi_busi1 busi1;        busi1.do_request();}

相應的makefile:

INC=-I./ LIB=-L/usr/lib64 -lfcgiCPPFLAGS=-g -w $(INC)CC=g++BUSI1=./build/busi1BUSI2=./build/busi2BUSI3=./build/busi3all: $(BUSI1) $(BUSI2) $(BUSI3)$(BUSI1): ./fcgi_net_duty.o ./fcgi_busi1.o        $(CC) -O $@ $^ $(LIB)$(BUSI2): ./fcgi_net_duty.o ./fcgi_busi2.o        $(CC) -O $@ $^ $(LIB)$(BUSI3): ./fcgi_net_duty.o ./fcgi_busi3.o        $(CC) -O $@ $^ $(LIB)

OK,現在一個輕型的fastcgi開發架構就搭建起來了,現實開發中,可以讓一個成員開發網路處理,其他人專門做相應的業務處理,可以達到事半功倍的處理,我的理念就是讓專業的人做專業的事,這樣大家在專業技能上有更好的提升。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.