维护工作线程池的 Web 服务器如何确保当两个请求同时进入时,同一个线程不会专用于这两个请求?它是如何实现的:“每个请求都有自己的线程?”
如果我要实现这个线程池,我会使用一个队列来保存我的线程并同步所有“获取线程”操作。但显然这是低效的。
那么网络服务器是做什么的呢?
维护工作线程池的 Web 服务器如何确保当两个请求同时进入时,同一个线程不会专用于这两个请求?它是如何实现的:“每个请求都有自己的线程?”
如果我要实现这个线程池,我会使用一个队列来保存我的线程并同步所有“获取线程”操作。但显然这是低效的。
那么网络服务器是做什么的呢?
这取决于网络服务器。
例如,Nginx 不使用多线程:
Nginx 是为解决 C10K 问题而编写的少数服务器之一。与传统服务器不同,Nginx 不依赖线程来处理请求。相反,它使用可扩展性更高的事件驱动(异步)架构。这种架构在负载下使用少量但更重要的是可预测的内存量。即使您不期望同时处理数千个请求,您仍然可以从 Nginx 的高性能和小内存占用中受益。Nginx 向各个方向扩展:从最小的 VPS 一直到服务器集群。
另一方面,Apache 可以执行多线程/多进程,具体取决于配置。
如果我要为 Web 服务器实现线程池,我可能会将请求放在阻塞队列中。
池中的所有线程都将在队列中等待。一旦有请求进来,第一个可用的线程就会得到请求并回答它。如果另一个请求进来,而第一个线程正在回答,它会自动分配给另一个线程,这要归功于阻塞队列。一旦线程完成回答,它可以简单地在队列中再次等待并准备再次回答。在伪代码中,这会像:
处理请求的 Web 服务器代码
function onRequestReceived(request)
requestQueue.put(request)
//Note: request would be a custom object, containing info about the request, like the tcp connection the headers and possibly additional info
然后,工作线程看起来像:
function run()
while true:
request = requestQueue.get()
handleRequest(request)
所有线程都在应用程序开始时启动。这是关于它的。