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->cfg->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->link) //建立管道
w->pool = pool_new(w, s->cfg->pool_size_per_thread);
pool_new主要函数:
p->ac = calloc(count, sizeof(redisAsyncContext*));
p->cfg = w->s->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-></code><code>base</code> <code>= event_base_new();</code><code>//注册一个事件</code>
<code>worker_start(s->w[i]);</code><code>//开启worker</code>
<code>s->fd = socket_setup(s->cfg->http_host, s->cfg->http_port);</code><code>//建立socket</code>
<code>/* start http server */</code>
<code>event_set(&s->ev, s->fd, EV_READ | EV_PERSIST, server_can_accept, s);</code>
<code>event_base_set(s-></code><code>base</code><code>, &s->ev);</code>
<code>event_add(&s->ev, NULL);</code>
<code>event_base_dispatch(s-></code><code>base</code><code>);</code>
worker_start主要函数:
<code>pthread_create(&w->thread, NULL, worker_main, w);</code><code>//开了一个线程来运行worker_main函数</code>
worker_main主要函数:
<code>w-></code><code>base</code> <code>= event_base_new();</code><code>//注册event</code>
<code>/* monitor pipe link */</code>
<code>event_set(&ev, w->link[0], EV_READ | EV_PERSIST, worker_on_new_client, w);</code>
<code>event_base_set(w-></code><code>base</code><code>, &ev);</code>
<code>event_add(&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-></code><code>base</code><code>);</code>
worker_pool_connect主要函数:
<code>pool_connect(w->pool, 1);</code><code>//指定w->pool来连接redis</code>
pool_connect主要函数: //连接redis
<code>ac = redisAsyncConnect(p->cfg->redis_host, p->cfg->redis_port);</code>
<code>redisLibeventAttach(ac, p->w-></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->cfg->redis_auth);</code>
<code>下面就进入到了hiredis的部分了</code>
<code>-------------------------------start 的过程结束---------------------------------------</code>
本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/03/13/2393716.html,如需转载请自行联系原作者