Webdis内部解析
2012-03-13 13:56 轩脉刃 阅读(2773) 评论(0) 编辑 收藏 举报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 | |
----------------------
作者:yjf512(轩脉刃)
出处:http://www.cnblogs.com/yjf512/
本文版权归yjf512和cnBlog共有,欢迎转载,但未经作者同意必须保留此段声明
实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”
本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库