目前,市场上流行有很多web服务器软件,每种服务器都有自己的特点。我们在开发的过程中,经常要和它们打交道,所以了解它们的工作原理也是很重要的。
几款比较流行的服务器
它们会做些什么?
第三篇中有这样的一张图片,它演示了客户端和服务器在发起事务时它们需要做的几个事情。
这里就详细地谈谈服务器在运行过程中会做什么。
首先服务器在完全运行起来之后,客户端就可以向服务器发起连接了(关于这个部分,大家可以看第三篇笔记)。现在的web服务器大多数都是多线程服务器了,一般在服务器上配置连接池,限制连接的数量,可以大大减轻服务器的连接压力,以保证网络服务的质量。
在这个阶段,服务器也会判断客户端的身份,比如一些有恶意行为的IP地址,服务器会拒绝建立连接。
接下来,服务器就会开始接受客户端发出的报文并解析它们(关于报文可以看第四篇笔记)。服务器首先会读取报文的起始行。从它请求的方法中以确定这个请求需要给予什么样子的响应,在这之后,服务器就会去读取uri,确定资源的地址,最后在这行信息中检测客户端使用的http版本,以确定首部的一些信息解读的方式。之后就是读取各行的信息,直到检测到以CRLF( Carriage-Return Line-Feed 回车换行)结束的标识。在这之后服务器就会对请求开始处理了,比如像post中的一些数据传递到程序中。
此时,服务器要开始很重要的步骤了,找到客户端希望得到的资源,开始构建一个特别的内容给客户端,这些都是程序处理的部分了。当然,这里请求的资源使用路径都是服务器上的虚拟路径,不是服务器文件系统上的绝对路径。这个虚拟路径恰好把资源封闭在一个固定的路径中,不让访问突破规定范围。在linux中有一种SELinux的机制,进程只能访问那些在他的任务中所需要文件。
在确定了要发送的内容之后,服务器会构建一个响应报文并发送它们。这里面通常会包括一个响应主体的MIME类型响应主体的Content-length以及响应主体页面。发送完毕后,服务器会检测这是不是一个持久连接,并根据此,决定是不是要关闭连接。
字符编码
我想凡是做过开发的人一定都遇到过字符编码乱码的问题。关于字符编码的问题非常复杂。其中有一些就和web服务器接收和构建报文有关系。
一个客户端吧请求报文在发送给服务器时,可以在发送前,在首部通过设置Accept-Charest和Accecpt-Encoding告诉服务器自己期待的字符编码方式。服务器会根据这条信息给予客户端最优化的方案。但有时,乱码依旧。而这些乱码是从哪里来的呢?
这要从它的历史说起了,最早的ASCII码并不支持中文,为了满足我们国家的需要,有人对ANSi(ASCII的扩充)码进行了扩充,制作了GB2312,后来发现GB2312不能显示一些生僻的字,于是gbk编码就诞生了,在这之后,有进行了几次扩展。
但是在ANSi编码下,同一个编码值,在不同的编码体系里代表着不同的字,这就是意味着不同国家的人相互访问网站的时候,由于不同的编码,我们就会看见不同的内容(大部分都是不知所云的乱码)。
后来有了Unicode编码,每个符号对应一个唯一的编码,乱码问题就不存在了。但是这样做这个库就非常庞大,UTF-8可以根据不同的符号自动选择编码的长短,这样又一次提高了字符编码的效率。
所以,utf-8应该是我们最好的选择。如果我们使用GB2312,我们在URL传递中文数据时,就会变成一堆符号和数字,而我们采用utf-8时,就不会有这个问题。有时候,我们很少注意,自己在开发时,页面本身的字符编码格式。所以很多不同字符编码定义,就让服务器不知所措了,有时候数据库的字符编码和接收的字符编码又是不同的,这里又一次造成了编码的不和谐。