我正在编写一个想要订阅zeromq pubsub套接字的nginx模块,并根据收到的消息更新内存中的数据结构。为了节省带宽,有意义的是只有一个进程才能进行订阅,并且数据结构应该是shm,以便所有进程都可以使用它。对我来说,一个进程应该是主进程似乎很自然(因为如果它是一个worker,那么代码必须以某种方式决定哪个 worker)。
但是,当我从ngx_get_connection
或init_master
回调中拨打init_module
时,会出现段错误,显然是因为ngx_cycle
尚未初始化。谷歌搜索在主进程中工作的插件似乎非常悲观。有没有更好的方法来实现我的目标,即每个服务器与pubsub套接字建立单个传出连接,无论它有多少工作者?
这是一个在工作者上下文中工作的代码示例,但不是来自master:
void *zmq_context = zmq_ctx_new();
void *control_socket = zmq_socket(zmq_context, ZMQ_SUB);
int control_fd;
size_t fdsize = sizeof(int);
ngx_connection_t *control_connection;
zmq_connect(control_socket, "tcp://somewhere:1234");
zmq_setsockopt(control_socket, ZMQ_SUBSCRIBE, "", 0);
zmq_getsockopt(control_socket, ZMQ_FD, &control_fd, &fdsize);
control_connection = ngx_get_connection(control_fd, cycle->log);
control_connection->read->handler = my_read_handler;
control_connection->read->log = cycle->log;
ngx_add_event(control_connection->read, NGX_READ_EVENT, 0);
和其他地方
void my_read_handler (ngx_event_t *ev) {
int events;
size_t events_size = sizeof(events);
zmq_getsockopt(control_socket, ZMQ_EVENTS, &events, &events_size);
while (events & ZMQ_POLLIN) {
/* ...
read a message, do something with it
... */
events = 0;
zmq_getsockopt(control_socket, ZMQ_EVENTS, &events, &events_size);
}
}
答案 0 :(得分:1)
为了节省带宽,有意义的是只有一个进程应该进行订阅,并且数据结构应该是shm,以便所有进程都可以使用它。对我而言,一个进程应该是主进程似乎很自然(因为如果它是一个worker,代码就必须以某种方式决定哪个worker)。
正如我已经说过的,您所需要的只是拒绝自然的想法,并为您的目的使用一个工作流程。
哪个工人?好吧,让它成为第一个开始的。