Webdis是redis的http代理,源代码在:git://github.com/nicolasff/webdis.git
webdis.json是配置文件
webdis.c是入口程序
其中有三个比较重要的结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
struct
server {
int
fd;
struct
event
ev;
struct
event_base *
base
;
//libevent的event事件
struct
conf *cfg;
//配置文件,设置有多少个进程(http_threads)啥的放在里面
/* worker threads */
struct
worker **w;
//有多个worker,父进程有多少worker线程
int
next_worker;
/* log lock */
struct
{
pid_t self;
int
fd;
} log;
//日志结构
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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连接的连接池
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct
pool {
struct
worker *w;
//worker线程
struct
conf *cfg;
//配置文件
const
redisAsyncContext **ac;
//redis的同步上下文
int
count;
//pool大小,即s->cfg->pool_size_per_thread
int
cur;
};
|
这三个结构每个结构都有一个指针指向父结构,比如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客户端库
https://github.com/antirez/hiredis
Hiredis is a minimalistic C client library for the Redis database.
Hiredis:
使用方法大是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
的过程结束----------------------------------------
|
1
|
|
1
|
-------------------------------start 的过程开始---------------------------------------
|
server_start主要函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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
);
|
worker_start主要函数:
1
|
pthread_create(&w->thread, NULL, worker_main, w);
//开了一个线程来运行worker_main函数
|
worker_main主要函数:
1
2
3
4
5
6
7
8
9
10
11
12
|
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主要函数:
1
|
pool_connect(w->pool, 1);
//指定w->pool来连接redis
|
pool_connect主要函数: //连接redis
1
2
3
4
5
6
7
8
9
|
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
|
下面就进入到了hiredis的部分了
|
1
|
-------------------------------start 的过程结束---------------------------------------
|
1
|
|
本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/03/13/2393716.html,如需转载请自行联系原作者