by:jasonsalex
date:2016/09/05
csdn:http://blog.csdn.net/rushroom
github:https://github.com/jasonsalex/nginx_zookeeper
1.使用zk多线程的方式,会使nginx造成进程死锁,和程序崩溃。建议使用zl单线程库_st.o
2.使用nginx的事件轮询机制代替zookeeper的多线程事件轮询机制。
3.提供如下代码方案:
(1)通过nginx处理zk时间队列
static void ngx_http_zookeeper_process_event(ngx_event_t *ev)
{
ngx_http_zookeeper_main_conf_t *zmf;
zmf = (ngx_http_zookeeper_main_conf_t *)ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_zookeeper_module);
int fd, interest, events;
fd_set rfds, wfds, efds;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
struct timeval tv;
zookeeper_interest(zmf->handle, &fd, &interest, &tv);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (fd != -1) {
if(interest&ZOOKEEPER_READ)
{
FD_SET(fd, &rfds);
} else {
FD_CLR(fd, &rfds);
}
if(interest&ZOOKEEPER_WRITE)
{
FD_SET(fd, &wfds);
} else{
FD_CLR(fd, &wfds);
}
} else{
fd = 0;
}
if (select(fd+1, &rfds, &wfds, &efds, &tv) < 0)
{
printf("[%s %d]select failed, err=%d, msg=%s\n", __FUNCTION__, __LINE__, errno, strerror(errno));
}
events = 0;
if (FD_ISSET(fd, &rfds))
{
events = ZOOKEEPER_READ;
}
if (FD_ISSET(fd, &wfds))
{
events = ZOOKEEPER_WRITE;
}
zookeeper_process(zmf->handle, events);
ngx_http_zookeeper_process_event_timer((ngx_socket_t)-2, 10, ngx_http_zookeeper_process_event);
}
(2)添加到nginx 时间处理队列
static void ngx_http_zookeeper_process_event_timer(ngx_socket_t fd,ngx_msec_t time, void * call_back_p)
{
zk_process_event_dummy.fd = fd;
ngx_memzero(&zk_process_event_timer, sizeof(ngx_event_t));
zk_process_event_timer.handler = call_back_p;
zk_process_event_timer.log = ngx_cycle->log;
zk_process_event_timer.data = &zk_process_event_dummy;
ngx_add_timer(&zk_process_event_timer, time);
}