我遇到了下面的线程,希望实现为请求而非客户端连接提供线程,但我不确定如何在每次TCP传输之间不关闭与客户端的连接的情况下实现。我看到了下面的内容,但不确定如何在不保持线程处于活动状态的情况下保持服务器和客户端之间的TCP连接。
最上面的答案指定:";注意,每个请求的线程并不意味着框架必须关闭HTTP请求"one_answers"之间的TCP连接;我很想看看是怎么做到的。
每个连接的线程数与每个请求的线程数之间的区别是什么?
@aholbreich
您标记了TCP,但包含的链接提到了HTTP内容。我假设您的问题是在HTTP上下文中提出的,或者假设TCP之上有一个通用的请求/回复协议。
关于此:
请注意,每个请求的线程并不意味着框架必须关闭HTTP请求之间的TCP连接
在连接上处理IO的线程策略通常取决于执行IO的方式。如果执行阻塞IO,则每个连接必须(至少(有一个线程。这意味着read()
上至少有一个线程99%的时间被阻塞。
如果是这种情况,则不需要每个请求执行1个线程,除非您希望同时提供多个请求。如果是这种情况,您需要为每个请求生成一个新的线程来handle
请求(即生成响应(。这个新的每个请求线程位于用于处理底层连接的IO(读/写(的线程之上。在某个时刻,当您生成响应时,您必须将其发送回执行IO的线程之一。对于具有多路复用功能的HTTP2来说,情况并非如此。
在这种情况下,有很多if
是值得的。
这样做的问题在于,创建线程是一项成本高昂的操作。只有当产生响应由于计算而需要很长时间(即您受CPU限制(,或者如果或产生响应的行为需要阻止IO时,这样做才有意义。但在这一点上。。。我不会首先使用阻塞IO来处理连接(即,我会放弃1个线程<->1个连接的想法。
我的直觉是,你把两件不同的事情混为一谈:
- 执行实际IO(从套接字读取和写入(
- 执行";处理";服务器中的特定消息,并最终生成响应
就我个人而言,在事先不了解的情况下,一个安全的选择是使用类似Netty的东西来处理IO(非阻塞IO的多线程事件循环(,然后将长或阻塞请求处理卸载到固定大小的线程池。
阻塞本身并不坏,当它浪费操作系统资源时,它是坏的。未来免责声明:当项目Loom将登陆JDK时,我认为阻塞API的使用将死灰复燃,这一领域的做法将发生一些变化。