我目前正在实施一个充当2台服务器的守护程序服务器。其中一台服务器通过UDP从生产者集合中接收日志。第二个服务器正在将从生产者接收的每个日志广播到当前通过TCP连接的消费者。
这是2个separte套接字。我当前(非常基本的)实现是在这两个套接字上使用select()
,并相应地处理每个读取信号,所以我的代码是基本的(注意这是伪代码)
for(;;) {
FDSET(consumers_server)
FDSET(producers_server)
select()
if consumers_server is set:
add new client to the consumers array
if producers server is set:
broadcast the log to every consumer in the array
}
这很好用,当这段代码被压入时,问题就出现了。当多个产品发送日志(UDP)时,这里的真正瓶颈是TCP的消费者。向消费者发送日志可能会导致阻止,这是我无法承受的。
我尝试过使用非阻塞套接字和select()ing
消费者写入fds,问题是这会导致将未发送的日志保存在缓冲区中,直到可以发送它们为止。这导致了非常不优雅的大规模代码,并且系统资源也很少(主要是RAM)
我在Linux发行版上运行。
欢迎在这些UDP和TCP连接之间同步的另一种方法。
答案 0 :(得分:1)
这注定要失败。迟早你将无法发送给TCP消费者。这是否表现为阻塞或EAGAIN / EWOULDBLOCK与底层问题无关,即生产者正在超越消费者。你必须决定该怎么做。您可以拥有一定数量的内部缓冲,但在某些时候您将不得不停止从UDP生成器读取。此时,UDP数据报将被丢弃,您的系统将丢失数据,当然,由于使用UDP,它可能会丢失数据。
不要这样做。对生产者使用TCP:或者只是接受数据丢失并使用阻止模式。非阻塞模式只会稍微改变问题并使代码复杂化。