- 論壇徽章:
- 0
|
Webdis內(nèi)部解析
Webdis是redis的http代理,源代碼在:git://github.com/nicolasff/webdis.git
webdis.json是配置文件
webdis.c是入口程序
其中有三個比較重要的結(jié)構(gòu):
- ?123456789101112131415161718 struct server { int fd; struct event ev; struct event_base *base; //libevent的event事件 struct conf *cfg; //配置文件,設(shè)置有多少個進(jìn)程(http_threads)啥的放在里面 /* worker threads */ struct worker **w; //有多個worker,父進(jìn)程有多少worker線程 int next_worker; /* log lock */ struct { pid_t self; int fd; } log; //日志結(jié)構(gòu) };
復(fù)制代碼
- ?12345678910111213 struct worker { /* self */ pthread_t thread; struct event_base *base; //libevent的event事件 /* connection dispatcher */ struct server *s; //父server int link[2]; //由pipe建立的管道,link[0]是管道讀取端,link[1]是管道寫入端 /* Redis connection pool */ struct pool *pool; //連接池,與redis連接的連接池 };
- ?12345678910111213 struct pool { struct worker *w; //worker線程 struct conf *cfg; //配置文件 const redisAsyncContext **ac; //redis的同步上下文 int count; //pool大小,即s->cfg->pool_size_per_thread int cur; };
復(fù)制代碼 這三個結(jié)構(gòu)每個結(jié)構(gòu)都有一個指針指向父結(jié)構(gòu),比如pool的worker*
這樣能保證從任意一個結(jié)構(gòu)中都能取得父結(jié)構(gòu)的需要的屬性
webdis的server-worker-pool的關(guān)系是這樣的:
一個Server包含多個worker,每個woker占一個進(jìn)程的資源
一個worker包含一個pool
Server的任務(wù)是接受HTTP請求,傳遞HTTP的套接字給worker
Worker才是webdis的實(shí)際處理類,一方面接受Server傳遞過來的HTTP請求,一方面由pool保持和redis的連接
Pool是連接池,保持了與redis的連接,防止重復(fù)的連接操作造成過多的資源浪費(fèi)
webdis的入口是Webdis.c文件
主要運(yùn)行了:
Server_new(conf)
server_start(s)
-------------------------------new 的過程開始----------------------------------------
Server_new主要函數(shù):
conf_read
worker_new * n
worker_new主要函數(shù):- Pipe(w->link) //建立管道
- w->pool = pool_new(w, s->cfg->pool_size_per_thread);
復(fù)制代碼 pool_new主要函數(shù):- p->ac = calloc(count, sizeof(redisAsyncContext*));
- p->cfg = w->s->cfg;
復(fù)制代碼 pool中有一個redisAsyncContext結(jié)構(gòu),這個結(jié)構(gòu)是hiredis的范圍了:
Hiredis是redis的C客戶端庫
https://github.com/antirez/hiredis
Hiredis is a minimalistic C client library for the Redis database.
Hiredis:
使用方法大是:- ?123456789101112131415 redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); int redisAsyncCommand( redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); int redisAsyncCommandArgv( redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); void redisAsyncDisconnect(redisAsyncContext *ac);
- ?1 -------------------------------new 的過程結(jié)束----------------------------------------
- ?1
- ?1 -------------------------------start 的過程開始---------------------------------------
復(fù)制代碼 server_start主要函數(shù):- ?1234567891011121314151617 s->base = event_base_new(); //注冊一個事件 worker_start(s->w[i]); //開啟worker s->fd = socket_setup(s->cfg->http_host, s->cfg->http_port); //建立socket /* start http server */ event_set(&s->ev, s->fd, EV_READ | EV_PERSIST, server_can_accept, s); event_base_set(s->base, &s->ev); event_add(&s->ev, NULL); event_base_dispatch(s->base);
-
復(fù)制代碼 worker_start主要函數(shù):- ?1 pthread_create(&w->thread, NULL, worker_main, w);//開了一個線程來運(yùn)行worker_main函數(shù)
- worker_main主要函數(shù):
- ?123456789101112 w->base = event_base_new(); //注冊event /* monitor pipe link */event_set(&ev, w->link[0], EV_READ | EV_PERSIST, worker_on_new_client, w); event_base_set(w->base, &ev); event_add(&ev, NULL); /* connect to Redis */worker_pool_connect(w); //worker和pool的連接,即worker和redis的連接 /* loop */event_base_dispatch(w->base);
- worker_pool_connect主要函數(shù):
- ?1 pool_connect(w->pool, 1); //指定w->pool來連接redis
-
- pool_connect主要函數(shù): //連接redis
- ?123456789 ac = redisAsyncConnect(p->cfg->redis_host, p->cfg->redis_port); redisLibeventAttach(ac, p->w->base); redisAsyncSetConnectCallback(ac, pool_on_connect); redisAsyncSetDisconnectCallback(ac, pool_on_disconnect); redisAsyncCommand(ac, NULL, NULL, "AUTH %s", p->cfg->redis_auth);
- ?1 下面就進(jìn)入到了hiredis的部分了
- ?1 -------------------------------start 的過程結(jié)束---------------------------------------
- ?1
復(fù)制代碼 ----------------------
作者:yjf512(軒脈刃)
出處:http://www.cnblogs.com/yjf512/
本文版權(quán)歸yjf512和cnBlog共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明
|
|