上篇写了一个基本算是糊弄别人的代理。在那个代理里边,主要有几个问题。
1)如果LWP在请求HTTP的时候,比较慢,或者干脆阻塞了怎么办?
2)如果用户有特别的HTTP头部要直接发送出去怎么办?
3)如果目标URL服务器返回有特殊的HTTP头部(如cookie等)该怎么办?
要回答这些问题,我们先来回顾下上篇代理服务器的结构。这个程序只有一个线程,当用户连接上来时,回调函数直接用LWP去连接用户需要访问的URL。如果这个时候等待或者阻塞,那整个进程就阻塞了。一旦阻塞,别的连接请求就不能得到处理。
打个比方,动物园里,假如有100只猴子需要喂食,但只有一个饲养员。饲养员发现其中一只猴子饿了,他就过去喂一口。然后等待其他猴子喊饿。这本来好好的一个过程。问题就出在“喂一口”上。把食物放进猴子口中,把勺子拿出来,这喂一口就算结束了。但有的猴子调皮,非得咬住勺子,等他咽掉才松口。那这个过程就长了。如果他不松口,别的猴子就是喊破喉咙也没得吃。
这种服务器的结构称为迭代式服务。在迭代的过程中,要尽量避免阻塞和等待。如果不能避免,那后续的请求就要等待。
既然有这个缺点,那我们为啥还用?
很充分的理由,大多数服务(如Web服务),处理的是一些很简单的动作。消耗不了什么太多的CPU资源,因此,顺序迭代用户请求就行了。不用引入复杂的架构。
对于这种迭代引起的问题,我们在下篇会介绍办法来消除。
对于2)和3),这个问题也好解决。我们可以把之前的代理服务器改造成透明代理。把用户请求的HTTP头,除了URI外,原封不动的送到目的URI。从目的服务器返回来的HTTP头部也原封不动的写回到用户那边就是了。
只要解决了上面的问题,这个代理还是勉强可以把玩一下的。