代理服务器(4)--从迭代到并发

上文讲到,我们不能在收到用户请求,调用LWP的时候被阻塞。这个问题要怎么解决呢?

最简单的办法就是“一气化三清”。让主程序创建进程/线程,在独立的进程/线程空间里边执行有时间消耗或阻塞的操作。这样,用以跟用户交出的主程序不会被阻塞。这种多个进程/线程协同工作的方式,称为并发。

让我们先来看一下古老的CGI程序。基本上CGI就是这样的结构。Apache作为跟用户交互的web服务器,他在获得用户请求后,会fork出一个进程来用来执行CGI处理程序。在这个CGI处理程序里边,把请求结果计算出来,并且返回给用户。Apache主程序并不关心CGI的结果。

简单,方便。于是乎很多同学拿到了必杀技。来个请求,开个进程。

什么,进程开销大?那就来个线程。

什么,线程也不够轻量?那就来个协程(在同一个线程里边,有多个执行单元,程序自己调度这些执行单元而不是靠OS本身的调度器。这样的执行单元成为协程,协程在语言如erlang,golang里边被广泛使用)。

这种并发方式在大多数情况下确实能工作的很好。但是,让我们在回顾下,为啥当初的CGI会被人诟病不已?进程不断的被创建,执行,销毁,这些其实还是要消耗不少CPU时间的。于是乎,动态网页就从CGI发展到了FCGI(Fast CGI)。

FCGI创建的是一组线程/进程池。池会跟Web Server进行IPC消息交互(通常通过unix socket)。

在我们的程序里边,我们也是可以利用这种模式的。这样,从用户的角度看过来,池有多大,就能有多少个用户可以并发请求,且用户之间不会相互影响。

在这种并发模式下,创建协程是最高效经济的。有兴趣的同学可以自己尝试下。

上面提到的并发技术,都是我们在程序里边,开我们自己写的代码完成的。对代码的编写有一定的技术要求。能不能在代码之外,利用一些工具来实现同样的效果呢?答案是肯定的。我们在下一篇会用一个比较简单的结构来替代这个架构(当然,可以使用的方案是很多的,我只介绍简单的)。

另外,对于HTTP头部的透明转发,如果采用现成的HTTP工具或者模块,这个就有点复杂了。我们会在后边的博客中介绍别的方法时来解决这个问题。




你可能感兴趣的:(代理服务器(4)--从迭代到并发)