CHARPSERVER design and implementation
aims:
1. Design a high-performance webserver, support HTTP protocol, simple dynamic page features
2. The initial version is tested as an experimental design, used to familiarize you with the C language and HTTPSERVER architecture
3. Support multi-CPU structure
One: Summary
The main platform developed in Linux, the kernel version is 2.6 or more. This Server takes an event-driven scheduling policy. There are techniques used:. Epoll, Aio, SmallLangage, Libevnet design improvements over MemCached on the use of the framework design of Tux.
Figure 1 is a holistic
2: Implementation method of event drive mechanism
Event list involved
1. EV_CONNREAD event This event indicates that the Socket connection that has been created is read.
2. EV_HTTPPARSE event This event indicates that data has been read from the Socket connection.
3. EV_HTTPHANDLE Event This event indicates that the data has been analyzed and the data needs to be processed.
4. EV_CACHEMISS Event This event indicates that the data requested does not exist in cache, and the next processing needs to be processed.
5. EV_AIOWRITE event, the event represents your hard disk
6. EV_AIOREAD event, the event represents reading data from the hard disk
7. EV_CONNWRITE event, the event indicates that the server-side has been processed and can send data to the client.
The relationship and role between each queue
The main line is responsible for the Trunking Checking Epoll Event Queue, Event Queue, AIO Active Queue Three Queues. The main thread uses the EPENT_WAIT function of EPOLL to monitor the event that has been established. Specific code can see the EPOLL_DISPACH function in ePoll.c in libevent. This function should be changed, each process, must check if there is data in other queue, and perform corresponding processing. ServerThread is responsible for transforming the EPOLL event into an EVENT event and adds it to EventQueue.
The main thread checks the EPOLL EVENT Queue After processing an EVENT, check if there is a task in Event Queue if there is, from the queue to get a task and proceed.
After checking EVENT Queue, then check the AIO ActiveQueue to check if there is a read and write disk. If there is a IO event from the AIO event queue, and transform the event into Event's Event Queue, wait for the next hand.
AIO's event drive mechanism, you can see
Perform three steps to perform a rim strategy until ePolleventQueue, EventQueue, AioQueue
There is no task that can be handled. The main thread block. Surveys if there is a new connection arrival.
Related connections:
http://developer.osdl.org/daniel/aio/
http://lse.sourceforge.net/io/aio.html
http://www.monkey.org/~provos/libevent
http://www.danga.com/memcached/
1. Simple design structure of various structures
See also the design of the event structure of libevent, and the sixteen entry code corresponding to each event is
EV_CONNREAD 0x00
EV_HTTPPARSE 0x01
EV_HTTPHANDLE 0x02
EV_CONNWRITE 0x04
EV_AIOREAD 0x08
EV_AIOWRITE 0X0F
EVENT structure
Struct Event {
TAILQ_ENTRY (EVENT) EV_NEXT;
TAILQ_ENTRY (EVENT) EV_PREV; STRUCT CONN_STRUCT * CONN;
INT Event_count_active; / * Need to process in EventATIVEQueue * /
Struct Event_list ** ActiveQueues; / * There is a priority event list * /
INT NACTIVEQUEES; / * A number of events * /
Void (* ev_callback) (INT Short, Void * Arg);
SHORT EV_FLAGS;
}
ServerThread structure
Struct serverthread {
Pthread_t pthread_id;
Struct EPOLL_EVENT * Events; // Epoll queue
Struct Event_list ** ActiveQueues; EVENT priority queue
INT NACTIVEQUEES;
Struct IO_EVENT Events [AIO_MAXIO]; / / Read and write the event queue
}
Struct conn_struct {
Int sfd;
Int State;
Struct Event_list event;
Struct socket * sock;
#define max_username_len 16
Char username [MAX_USERNAME_LEN];
Unsigned int usrname_len;
// http part
HTTP_METHOD_T METHOD;
Const char * method_str;
Unsigned int method_len;
HTTP_VERSION_T VERSION;
Const char * VERSION_STR;
Unsigned int version_len;
/ * Requester Uri: * /
Const char * URI_STR;
Unsigned int URI_LEN;
/ * ObjectName (filename / scriptname) this uri refers to: * /
#define max_Objectname_len 256
Char Objectname [MAX_Objectname_len 4]; // Space for .gz as Well
Unsigned int objectname_len;
/ * Query string within the uri: * /
Const char * query_str;
Unsigned int query_len;
/ * Cookies: * /
Const char * cookies_str;
Unsigned int cookies_len;
Unsigned int parse_cookies;
/ * Content-Type * /
Const char * content_type_str;
Unsigned int content_type_len;
/ * Content-length: * /
Const char * contentlen_str;
Unsigned int contentlen_len;
Unsigned int content_len;
/ * User-agent: * /
Const char * user_agent_str;
Unsigned int user_agent_len;
/ * Accept: * /
Const char * accept_str;
Unsigned int access_len;
/ * Accept-charset: * /
Const char * accept_charset_str;
Unsigned int access_charset_len;
/ * Accept-language: * /
Const char * accept_language_str; unsigned int access_language_len;
/ * Cache-control: * /
Const char * cache_control_str;
Unsigned int Cache_Control_len;
/ * If-modified-Since: * /
Const char * if_modified_since_str;
Unsigned INT if_modified_since_len;
/ * If-none-match: * /
Const char * if_none_match_str;
Unsigned int if_none_match_len;
/ * If-range: * /
Const char * if_range_str;
Unsigned int if_range_len;
/ * Negotiate: * /
Const char * negotiate_str;
Unsigned int Negotiate_len;
/ * Prgma: * /
Const char * prgma_str;
Unsigned int prigma_len;
/ * Referer: * /
Const char * referer_str;
Unsigned int Referer_len;
/ * Accept-encoding: * /
Const char * accept_encoding_str;
Unsigned int access_encoding_len;
Unsigned int allow_send_gzip;
Unsigned int content_gzipped;
/ * Host * /
#define max_host_len 128
CHAR HOST [MAX_HOST_LEN];
Unsigned int host_len;
/ * Posted data: * /
Const char * post_data_str;
Unsigned int pos_data_len;
Unsigned int stat;
/ * The file being Sent * /
Unsigned int reference;
#if config_tux_debug
Unsigned int reference;
#ENDIF
Unsigned long first_timestamp;
Unsigned int body_len;
Unsigned int usr_error;
CHAR ERROR;
CHAR PostPoned;
Char had_cachemiss;
Char lookup_dir;
Char lookup_404;
CHAR Keep_Alive;
Struct Timer_List Keepalive_timer;
Unsigned int total_bytes;
Struct Timer_List Output_timer;
Unsigned int NR_keepalives;
Unsigned int event;
U64 private;
Unsigned int magic;
#if config_tux_extended_log
Unsigned long accept_timestamp;
UNSIGNED long parse_timestamp;
Unsigned long output_timestamp;
Unsigned long flush_timestamp;
# Define set_timestamp (x) DO {(x) = jiffies;} while (0)
#ELSE
# Define set_timestamp (x) do {} while (0)
#ENDIF
}
Method of event cycle
Eventloop ()