天天看点

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,如需转载请自行联系原作者

继续阅读