博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Webdis内部解析
阅读量:7021 次
发布时间:2019-06-28

本文共 3713 字,大约阅读时间需要 12 分钟。

Webdis是redis的http代理,源代码在:

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客户端库

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

你可能感兴趣的文章
ADT中通过DDMS导入文件出错ddms transfer error: Read-only file system,Failed to push selection...
查看>>
mac 10.11.6 root没有最高权限解决方案
查看>>
tomcat+nginx 以https方式访问
查看>>
camel 项目中用到的功能(一)
查看>>
如何去掉UIWebView的黑色背景
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Phoenix官方教程 (九) Channel
查看>>
【百度地图API】如何判断点击的是地图还是覆盖物?
查看>>
MySQL日期时间函数大全
查看>>
raid详细介绍
查看>>
高项-3月26号培训作业
查看>>
WebP - Mac上使用cwebp,dwebp,webpmux工具
查看>>
Nginx使用uninx socket来连接fastcgi(php)
查看>>
硬盘安装 12.04 i386 desktop
查看>>
分布式文件系统MFS(moosefs)实现存储共享
查看>>
Memcache知识点梳理(转)
查看>>
外网访问内网IIS
查看>>
有趣的Java编程题
查看>>
ASP.NET MVC3中使用AllowHtml attribute
查看>>