免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2064 | 回复: 1
打印 上一主题 下一主题

Webdis内部解析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-14 16:46 |只看该作者 |倒序浏览
Webdis内部解析






Webdis是redis的http代理,源代码在:git://github.com/nicolasff/webdis.git

webdis.json是配置文件

webdis.c是入口程序



其中有三个比较重要的结构:

  1. ?123456789101112131415161718 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. ?12345678910111213 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连接的连接池 };
  2. ?12345678910111213 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主要函数:
  1. Pipe(w->link) //建立管道

  2. w->pool = pool_new(w, s->cfg->pool_size_per_thread);
复制代码
pool_new主要函数:
  1. p->ac = calloc(count, sizeof(redisAsyncContext*));

  2. 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. ?123456789101112131415 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);
  2. ?1 -------------------------------new 的过程结束----------------------------------------
  3. ?1   
  4. ?1 -------------------------------start 的过程开始---------------------------------------
复制代码
server_start主要函数:
  1. ?1234567891011121314151617 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. ?1 pthread_create(&w->thread, NULL, worker_main, w);//开了一个线程来运行worker_main函数
  2. worker_main主要函数:

  3. ?123456789101112 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);
  4. worker_pool_connect主要函数:

  5. ?1 pool_connect(w->pool, 1); //指定w->pool来连接redis


  6. pool_connect主要函数: //连接redis

  7. ?123456789 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);
  8. ?1 下面就进入到了hiredis的部分了
  9. ?1 -------------------------------start 的过程结束---------------------------------------
  10. ?1   
复制代码
----------------------

作者:yjf512(轩脉刃)

出处:http://www.cnblogs.com/yjf512/

本文版权归yjf512和cnBlog共有,欢迎转载,但未经作者同意必须保留此段声明

论坛徽章:
0
2 [报告]
发表于 2012-03-14 17:02 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP