天天看點

Webdis内部解析

webdis.json是配置檔案

webdis.c是入口程式

其中有三個比較重要的結構:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<code>struct</code> <code>server {</code>

<code>    </code><code>int</code> <code>fd;</code>

<code>    </code><code>struct</code> <code>event</code> <code>ev;</code>

<code>    </code><code>struct</code> <code>event_base *</code><code>base</code><code>;  </code><code>//libevent的event事件</code>

<code>    </code><code>struct</code> <code>conf *cfg; </code><code>//配置檔案,設定有多少個程序(http_threads)啥的放在裡面</code>

<code>    </code><code>/* worker threads */</code>

<code>    </code><code>struct</code> <code>worker **w; </code><code>//有多個worker,父程序有多少worker線程</code>

<code>    </code><code>int</code> <code>next_worker;</code>

<code>    </code><code>/* log lock */</code>

<code>    </code><code>struct</code> <code>{</code>

<code>        </code><code>pid_t self;</code>

<code>        </code><code>int</code> <code>fd;</code>

<code>    </code><code>} log; </code><code>//日志結構</code>

<code>};</code>

<code>struct</code> <code>worker {</code>

<code>    </code><code>/* self */</code>

<code>    </code><code>pthread_t thread; </code>

<code>    </code><code>struct</code> <code>event_base *</code><code>base</code><code>; </code><code>//libevent的event事件</code>

<code>    </code><code>/* connection dispatcher */</code>

<code>    </code><code>struct</code> <code>server *s; </code><code>//父server</code>

<code>    </code><code>int</code> <code>link[2];</code><code>//由pipe建立的管道,link[0]是管道讀取端,link[1]是管道寫入端</code>

<code>    </code><code>/* Redis connection pool */</code>

<code>    </code><code>struct</code> <code>pool *pool; </code><code>//連接配接池,與redis連接配接的連接配接池</code>

<code>struct</code> <code>pool {</code>

<code>struct</code> <code>worker *w;</code><code>//worker線程</code>

<code>struct</code> <code>conf *cfg;</code><code>//配置檔案</code>

<code>const</code> <code>redisAsyncContext **ac;</code><code>//redis的同步上下文</code>

<code>int</code> <code>count;</code><code>//pool大小,即s-&gt;cfg-&gt;pool_size_per_thread</code>

<code>int</code> <code>cur;</code>

這三個結構每個結構都有一個指針指向父結構,比如pool的worker*

這樣能保證從任意一個結構中都能取得父結構的需要的屬性

webdis的server-worker-pool的關系是這樣的:

一個Server包含多個worker,每個woker占一個程序的資源

一個worker包含一個pool

Server的任務是接受HTTP請求,傳遞HTTP的套接字給worker

Worker才是webdis的實際處理類,一方面接受Server傳遞過來的HTTP請求,一方面由pool保持和redis的連接配接

Pool是連接配接池,保持了與redis的連接配接,防止重複的連接配接操作造成過多的資源浪費

webdis的入口是Webdis.c檔案

主要運作了:

Server_new(conf)

server_start(s)

-------------------------------new 的過程開始----------------------------------------

Server_new主要函數:

conf_read

worker_new * n

worker_new主要函數:

Pipe(w-&gt;link) //建立管道

w-&gt;pool = pool_new(w, s-&gt;cfg-&gt;pool_size_per_thread);

pool_new主要函數:

p-&gt;ac = calloc(count, sizeof(redisAsyncContext*));

p-&gt;cfg = w-&gt;s-&gt;cfg;

pool中有一個redisAsyncContext結構,這個結構是hiredis的範圍了:

Hiredis是redis的C用戶端庫

<a href="https://github.com/antirez/hiredis">https://github.com/antirez/hiredis</a>

Hiredis is a minimalistic C client library for the Redis database.

Hiredis:

使用方法大是:

<code>redisAsyncContext *c = redisAsyncConnect(</code><code>"127.0.0.1"</code><code>, 6379);</code>

<code>int</code> <code>redisAsyncCommand(</code>

<code>redisAsyncContext *ac, redisCallbackFn *fn,</code><code>void</code> <code>*privdata,</code>

<code>const</code> <code>char</code> <code>*format, ...);</code>

<code>int</code> <code>redisAsyncCommandArgv(</code>

<code>int</code> <code>argc,</code><code>const</code> <code>char</code> <code>**argv,</code><code>const</code> <code>size_t *argvlen);</code>

<code>void</code> <code>redisAsyncDisconnect(redisAsyncContext *ac);</code>

<code>-------------------------------</code><code>new</code> <code>的過程結束----------------------------------------</code>

<code> </code> 

<code>-------------------------------start 的過程開始---------------------------------------</code>

server_start主要函數:

<code>s-&gt;</code><code>base</code> <code>= event_base_new();</code><code>//注冊一個事件</code>

<code>worker_start(s-&gt;w[i]);</code><code>//開啟worker</code>

<code>s-&gt;fd = socket_setup(s-&gt;cfg-&gt;http_host, s-&gt;cfg-&gt;http_port);</code><code>//建立socket</code>

<code>/* start http server */</code>

<code>event_set(&amp;s-&gt;ev, s-&gt;fd, EV_READ | EV_PERSIST, server_can_accept, s);</code>

<code>event_base_set(s-&gt;</code><code>base</code><code>, &amp;s-&gt;ev);</code>

<code>event_add(&amp;s-&gt;ev, NULL);</code>

<code>event_base_dispatch(s-&gt;</code><code>base</code><code>);</code>

worker_start主要函數:

<code>pthread_create(&amp;w-&gt;thread, NULL, worker_main, w);</code><code>//開了一個線程來運作worker_main函數</code>

worker_main主要函數:

<code>w-&gt;</code><code>base</code> <code>= event_base_new();</code><code>//注冊event</code>

<code>/* monitor pipe link */</code>

<code>event_set(&amp;ev, w-&gt;link[0], EV_READ | EV_PERSIST, worker_on_new_client, w);</code>

<code>event_base_set(w-&gt;</code><code>base</code><code>, &amp;ev);</code>

<code>event_add(&amp;ev, NULL);</code>

<code>/* connect to Redis */</code>

<code>worker_pool_connect(w);</code><code>//worker和pool的連接配接,即worker和redis的連接配接</code>

<code>/* loop */</code>

<code>event_base_dispatch(w-&gt;</code><code>base</code><code>);</code>

worker_pool_connect主要函數:

<code>pool_connect(w-&gt;pool, 1);</code><code>//指定w-&gt;pool來連接配接redis</code>

pool_connect主要函數: //連接配接redis

<code>ac = redisAsyncConnect(p-&gt;cfg-&gt;redis_host, p-&gt;cfg-&gt;redis_port);</code>

<code>redisLibeventAttach(ac, p-&gt;w-&gt;</code><code>base</code><code>);</code>

<code>redisAsyncSetConnectCallback(ac, pool_on_connect);</code>

<code>redisAsyncSetDisconnectCallback(ac, pool_on_disconnect);</code>

<code>redisAsyncCommand(ac, NULL, NULL,</code><code>"AUTH %s"</code><code>, p-&gt;cfg-&gt;redis_auth);</code>

<code>下面就進入到了hiredis的部分了</code>

<code>-------------------------------start 的過程結束---------------------------------------</code>

本文轉自軒脈刃部落格園部落格,原文連結:http://www.cnblogs.com/yjf512/archive/2012/03/13/2393716.html,如需轉載請自行聯系原作者

繼續閱讀