Web服务之一:Web服务及http协议

http协议的前世今生

HTTP:HyperText Transfer Protocol,超文本传输协议;

  主要是用于传输超文本的;

  超文本:指的是带有超级链接的文本;

  超链接:基于此种链接能够在文档间实现跳转。

Web:上个世纪80年代末90年代初诞生于欧洲量子物理实验室,主要用于实现能够在多个部门之间共享文档而且可以快速实现文档定位的一种协议。

http/0.9

  在当时,http协议广泛应用的版本为0.9,那个时候的Web服务仅支持纯文本(纯文本:由纯ASCII字符组成的文本),这种纯文本还包括超链接,这种超链接也是表现为纯文本形式的,但这种文本比较独特,因此称为超文本(HTML)

HTML:HyperText Mark Language,超文本标记语言;这是用于编写(开发)超文本的语言

  之所以叫标记语言是因为在这种语言当中事先规定好了将语言通过标签的形式给它加上一些特殊的标记,而这些文本在被用户客户端浏览器解析时能够将这些标记解析为字体格式或一些表现属性,如:<h2>Title</h2>。

Browser:浏览器,客户端代理的一种,通过http协议可以访问服务器端提供的超文本,而Browser能够在这些文本显示的时候将标签解析为对应的修饰的属性格式。

  当Web服务流行开来之后,全球能够提供Web服务的服务器有很多个,那么每一台服务器上都可以提供各种各样的文本,甚至于两台服务器上提供的文本的名字可能是一样的。如:1.1.1.1上建立了一个Web服务,而这个Web服务提供了一个超文本文档叫a.html,同时在2.2.2.2主机上也提供了一个a.html。那么对于客户端来讲如何区分这两个a.html呢?

  因此仅靠文件名进行区分文档是不可靠的。于是就出现了向URI这样的机制(虽然URI并不是专门为Web诞生的),URI是很好的能够让客户端识别互联网上不同文档的机制。

URIUniform Resource Indientifier,统一资源标识符;

  用于定义全局范围内标记唯一的定位一种资源访问路径的方式(命名方式);(不一定是互联网上的,全球的,包括互联网在内的可以在全局唯一引用某一个独立的资源的命名方式)  

  全局范围:包括但不限于互联网;

  统一:指的是路径格式上的统一,无论是什么样的资源,引用的方式路径的格式都是规范的。

URL:Uniform Resource Locator,统一资源定位符(URI的子对象、子集)

  用于描述在互联网上互联网资源的统一表示格式

  格式:protocol://HOST:port/path/to/file

    如:http://www.test.com/download/linux.tar.gz(唯一标识互联网上的资源)

资源(Web资源):

  能够通过统一资源定位符唯一标记并且能够让客户端访问的文件(事实上未必都是文件),如:http://www.test.com/logo.gif。每一个能够访问的单独的文件都是一个资源,但是多个资源很可能被整合成一个HTML文档

Web对象:等同于Web资源

  一个HTML文档就是可以实现将分散在多台Web服务器上的资源整合成一个页面(可以来自于不同的服务器,因为可能是交叉引用,实现跨主机引用其它主机上的资源的,但可以在同一页面中予以展示),并且能够让浏览器予以显示的语言就是HTML标记语言。

HTTP方法:(获取资源的方式)

  http/0.9时只有一个方法:

    GET,它表示直接从服务器上获取文档到本地浏览器并予以展示(不是简单的文件传输,而是超文本的文件传输);

  在http升级到1.0之后有了更多的方法:

    PUT:从远程服务器上直接获取文件到本地,与POST相对应

    POST:与GET相对应,通过表单提交数据到服务器上去;

    DELETE:在远程服务器上删除文件,与PUT相对应;

    HEAD:只返回首部,不响应主体;

  对于服务器来讲,PUT、POST、DELETE都不安全,因为它们都允许客户端直接操作服务器上的资源,因此一般来讲,需要通过认证以后才能允许客户端操作。最安全的方法就是GET,GET类似于只读的意思。

MIME机制:

  HTTP1.0更大的改进之处就是引入了MIME机制

  

  MIMEMultipurpose Internet Mail Extension,多功能(用途)互联网扩展邮件;

 

    MIME实现了能够将非文本(如:二进制)数据在传输前重新编码为文本格式再进行传输,接收方能够用相反的方式将其重新还原成原来的格式,还能够调用相应的程序打开此文件。如:传输过去一个rar文件,对方知道这是一个rar压缩包并且能够用相应的软件打开;若传输的是图片就能调用程序打开图片。所以在MIME编码当中,Base64就是一种文本编码格式。

  SMTP:Simple Mail Transfer Protocol,简单邮件传输协议;

    邮件传输协议早期只能传输纯文本,但后来不仅可以传输纯文本,还可以传输图片、视频等二进制文件,因为后来引入了MIME机制。

  


  在http1.0协议当中,也是纯文本传输的,后来参照了SMTP的纯文本传输机制将MIME引入到了http协议当中,从此以后,http协议也可以传输非文本数据了。

  实现过程:在客户端去获取某个资源时,资源传递到客户端时,明确说明是哪一类文件,如:是一个image/jpeg格式的图片,通过http协议的元数据(协议首部),在协议首部里边明确添加一个首部,告诉对方自己的文件是image/jpeg格式,所以客户端发现这是一个image大类下的jpeg小子类。此时,浏览器调用内部与之相匹配的插件来展示这个文件。若浏览器不支持这种插件,可以通过接口调用外部的系统上安装的其它的能够显示文件的插件,以插件的机制在浏览器中去解析对应MIME格式的文档的。因此我们可以发现若未安装flush插件,打开网页后许多flush插件是无法显示的也正是基于此种原理。当然,也正是这种插件机制的实现,使得后来出现了动态网页的技术。

动态效果:

  如:Java,Applet,JRE。嵌入到网页中,通过http协议传输到客户端,通过JRE环境展示动态效果,但由于过于重量级,在于flash的竞争中落败。

动态网页:

  动态网页指的就是在服务器端存储的用户访问的文档不再是HTML格式,而是编程语言开发的脚本(也可以是非脚本)。这个脚本在接收参数之后在服务器运行一次,运行完成之后会生成HTML格式的文档,并且把生成的文档发送给客户端。需要注意的是,这个编程语言所开发的脚本在用户访问时不是原封不动的发送给客户端,而是要先获取客户端的特性(客户端获取资源时需要先发起申请,而在发起申请之前需要把客户端地址、客户端浏览器的类型等一并发送给服务器),服务器获取客户端地址,浏览器类型等数据并将这些数据当做参数传递给脚本,让脚本在服务器端执行一次。因此任何一个用户去访问,都是根据用户的特性随时生成的,所以称为动态网页。

  此外,执行脚本与Web服务器没有任何关系,Web服务器需要调用额外的工具来实现执行脚本。如:建立了一个Web服务器,在Web服务器上建立了一个index.php的文件,当客户端去申请访问这个脚本时,服务器会根据它的扩展名来判断这不是HTML文档而是一个脚本,此时Web服务器不会立即响应客户端的访问,而是通过某种协议或机制去调用额外的运行程序,如:调用PHP的解释器,让这个解释器去运行index.php,这个运行结果自身会生成HTML文档,将HTML文档再通过这种协议返回给Web服务器,Web服务器再返回给客户端;过程:web --> protocol --> php(运行index.php)。需要注意的是,Web服务器只是一个http服务器,它并不负责处理动态内容

http请求在服务器端处理的过程详细描述:(请求分别为静态网页与动态网页时的情况)

  首先我们需要确定的是Web服务器是一个进程,这个进程在用户空间(Web服务器是一个特殊的具体应用,而既然是具体应用那就是一个具体的软件,那么这个软件就应该放在用户空间)。而用户所有能够访问的网页文件都存放在磁盘上,因此客户端向服务器发起请求时,这个请求先到达内核空间,而又因为这个客户端请求一定是通过网络协议发送过来的,而协议工作在内核(TCP/IP协议在内核工作),所以首先到达内核,内核空间解析接收到请求后,在内核中通过TCP/IP协议栈中各种路由机制(编码)等发现这个请求访问的是本机地址80端口的套接字,因为Web服务一旦启动之后一定会监听在TCP协议的80端口之上,因此内核就将请求通过套接字转交给用户空间的Web服务器,因此执行流程就从内核空间转到了用户空间了。

  若Web服务器发现用户访问的是一个文件,如:index.html,此时服务器就得陷入到内核中,重新转换为内核模式,到磁盘上将文件加载过来,内核找到这个文件后再返回给用户空间,此时又回到了Web服务器了,Web服务器发现这个文件取出来了就可以响应客户端了。此时再通过套接字回到内核空间,通过网络TCP/IP协议栈最终响应给客户端。

  如果用户访问的是动态网页,就不能直接予以响应了,需要通过其它协议启动另外一个进程,这个进程一定是一个解释器,如bash脚本就是bash解释器,PHP脚本就是PHP解释器。然后通过协议将这个文件传递给这个解释器或者这个解释器能够访问这个文档解释器自己陷入到内核模式将文档读取到解释器中,在解释其中执行一次,将执行结果返回给Web服务器。Web服务器将请求的结果通过网络传递给客户端,它需要额外启动一个进程,进程和服务器之间建立的联系是通过协议实现的,而在这个进程执行结束后需要销毁。所以对于Web服务器来讲,若要响应一个动态内容,需要先创建一个新的子进程,这个进程执行一次结束后需要将这个进程销毁,而这都是系统资源开销,对于一个客户端访问可能无所谓,但成千上万的客户端访问呢?因此我们可以推断到响应动态内容服务器需要更多的系统资源。

  在一个HTML网页中,可能会通过超链接引用n个资源(Web对象),而这n个web对象每一个都有自己的URL。而动态网页生成的HTML结果中也可以引用web对象,这些web对象是静态的,所以动态网页包含静态内容(无需改变或无需执行的内容如:图片、文件、rar压缩包)和动态内容(需要执行一次才能返回给客户端,只有动态内容才需要运行)。在http1.0之后就能支持这些机制了,正是1.0中引入了MIME,使得Web服务对于多媒体的支持得到了极大的扩展,也正是1.0系列的出现,使得web服务器迅速流行开来并大大的促进了互联网的发展。

  

  我们再来详细讨论一下整个过程:

  以纯静态页面来讲,所有用户访问的内容都是一样的,由此我们来分析一个问题:一个客户端发起Web服务请求到服务器需要经过多少个层次呢?如在浏览器输入www.test.com访问,第一步需要把FQDN转换成IP地址,因此在请求发出之前需要先通过DNS服务器解析FQDN,而DNS服务器可能会递归、迭代,需要消耗一些时间(在第一次访问时,记录未缓存到本地),之后客户端输入地址发送请求给服务器,服务器接收请求后,在内部需要有一个机制能够接收用户的请求,这种机制就叫做监听,监听在某个端口上,等待客户端的请求。一旦用户请求来了,而内核通过TCP/IP协议栈发现有人监听在这个端口上,于是这个请求就可以交给这个套接字了。但如果本地没有任何一个用户进程监听在某个套接字,但有客户端来访问了,此时内核无法知道有谁能够响应这个请求,此时就会拒绝客户端请求,如:此地未启动这个服务,因此必须到内核中去注册需要使用哪一个端口并一直在这个端口上处于等待状态。所以当有请求到来时,通过TCP/IP协议的首部解码后发现用户访问的是这么一个端口,于是就把这个请求转交给这个端口,而进程又一直监听在这个端口,一旦有请求来了,可进行响应。

http报文:

  TCP/IP协议在封装报文时,TCP首部主要是源端口(Source Port)、目标端口(Destination Port),IP首部主要是源IP地址(Source IP)、目标IP地址(Destination IP)。但却并没有明确说明具体访问哪个文档或资源,因此某一特定的应用在通过TCP/IP协议往外发送时,TCP/IP最多就是将报文传递到目的地,到达目的地后还需要具体协议的报文首部。因此http协议也有自己的首部,叫http首部,它明确定义了基于哪种协议获取哪个资源的,需要说明获取什么文档,如:GET /2.html,并且还需要说明获取哪个主机的资源,因此通常还有一个首部叫:Host:www.test.com(加主机是HTTP1.0中引入的一种机制,在发起获取资源请求时,不但要指明获取哪个资源,还要再加上获取哪个主机的资源,这个主机一定是主机名称,这是为虚拟主机做准备的)。说白了,这一切就叫http报文

  IP:

    Source IP

    Destination IP

  TCP:

    Source Port

    Destination Port

  http首部:

    GET/2.html

    Host:www.test.com

  http报文分为两种:请求报文、响应报文。

    报文语法:

    上面两个报文的第一行称为报文"起始行(start line)";后面的标签格式的内容称作首部域(Header field),每个首部域都由名称(name)和值(value),中间用逗号分隔,另外,响应报文通常还有一个称作Body的信息主体,即响应给客户端的内容。

    请求报文:

    method:资源获取方法;

    request-URL:请求的资源是什么;

    version:对应请求资源协议的版本号;

    headers:http协议首部;

    headers后的空白行是必须的;

    entity-body:空白行后有一些报文主体(报文内容)

    响应报文:

    version:对应请求的版本

    status:状态(代)码,请求结果正确与否的标识符

      状态码分为5类:

      1xx:纯信息,与请求的资源没有太大的关系;

      2xx:“成功”类的状态码信息,常用状态码:200(表示请求资源正常,已获取到正常响应);

      3xx:重定向类的信息,表示请求的资源已存在,但资源已被挪到其它地方了,如:给了一个参考答案说这个资源已经被挪走了,请重新发起请求另外一个地址,并且把另外的参考地址也响应给客户端了。常用的状态码:301(表示永久重定向,永久的挪到了那个位置了)、302(临时重定向,繁忙时重定向到指定位置寻找)、304(表示请求的内容未发生任何改变,若缓存过直接使用缓存即可)。需要注意的是,重定向的信息未必都是重定向,如304状态码;

      4xx:客户端错误类信息,常用状态码:404(请求了一个不存在的文件);

      5xx:服务器端错误类信息;

    reason-phrase:定义解释status的意义;

    headers:响应报文首部;

    entity-body:报文主体;

    报文举例:

    GET / HTTP/1.1中的/表示访问一个网站但没有明确指定访问哪个页面,/表示访问对方的默认页面(主页)。

缓存:在http/1.0中,引入缓存的机制时为了加速系统访问、节省网络带宽的。

Web服务器的主要操作:

1、建立连接——接受或拒绝客户端的连接请求;

2、接收请求——通过网络读取HTTP请求报文;

3、处理请求——解析请求报文并做出相应的动作;

4、访问资源——访问请求报文中相关的资源;

5、构建响应——使用正确的首部生成HTTP响应报文;

6、发送响应——向客户端发送生成的响应报文;

7、记录日志——当已经完成的HTTP事务记录进日志文件;

  从上述操作中可以看出,Web服务器没有执行脚本的过程。因此真正意义上的原生态的Web服务器是不会处理动态内容的

  

  http协议基于TCP协议,每一个TCP的建立都需要3次握手,而拿到资源后需要4次断开。为了避免每一次访问资源都要三次握手、四次挥手,推出了http/1.1。

http/1.1:

  增强了缓存功能;

  引入了长连接;

    获取资源后并不是立即断开连接,而是继续获取下一个资源;而长连接可以让同一个客户端发起第二个请求时尽可能缩短时间也降低服务器端资源占用率,但是当服务器端带宽占用巨大时,后来的客户端可能很难建立连接了。

    因此,为了资源的有效利用不能让建立长连接的客户端永久在线,因此给出两个限定:1.若请求第一或第二个资源后就不再请求,需要定义一个超时时间,到达一定时间后超时断开;2.当一直请求不断开时,定义做多请求多少次,如还请求,需要重新排队。

Web服务器处理模型

  服务器可能会出现多个客户端请求同时连进来的状况,那么怎么去响应多个用户请求呢?  

web服务器处理并发连接请求的架构方式:

  1、单线程web服务器(Single-threaded web server)

  此种架构方式中,web服务器一次处理一个请求,结束后读取并处理下一个请求。在某请求处理过程中,其它所有的请求将被忽略,因此,在并发请求数较多的场景中将会出现严重的必能问题。

  2、多进程/多线程web服务器

  此种架构方式中,web服务器生成多个进程或线程并行处理多个用户请求,进程或线程可以按需或实现完成。有的web服务器应用程序为每个用户请求生成一个进程或线程来进行响应,不过,一旦并发请求数量达到成千上万时,读个同时运行的进程或线程将会消耗大量的系统资源。

  3、I/O多路复用Web服务器

  为了能够支持更多的并发用户请求,越来越多的Web服务器正在采用多路复用的架构——同步监控所有连接请求的活动状态,当一个连接的状态正在发生改变时(如数据库准备完毕或发生某错误时),将为其执行一系列特定操作;在操作完成后,此连接将重新变回暂时的稳定态并返回至打开的连接列表中,直到下一次的状态改变。由于其多路复用的特性,进程或线程不会被空闲的连接所占用,因而可以提供高效的工作模式。

  4、多路复用多线程Web服务器

  将多进程和多多路复用的功能结合起来的Web服务器架构,其避免了让一个进程服务于过多的用户请求,并能充分利用多CPU主机所提供的计算能力。

小结:

Web服务器是一种C/S架构的模型:

  C:Client Agent(著名的有Browser,其它的还有reboot、spider)

  S:Server

  Client --> request(Client发起request报文请求) --> Server

    客户端请求的资源靠URL标记,请求的资源通过报文首部向服务器传递。

  Server --> response(Server构建response报文给客户端) --> Client

资源的获取有不同的方法,称为HTTP Method

  GET、HEAD、POST、DELETE、PUT、TRACE、OPTIONS、CONNECTION(前三个最常用)

请求的资源的状态码:

  为了明确表明客户端请求哪个资源、哪个主机上的资源、资源类型,需要HTTP Headers,格式:

    NAME:VALUE

    Host:www.test.com

    Connection:keep-alive

服务器的主要工作:

Server响应模型:

  单进程/单线程;

  多进程/多线程;

  单进程/多请求;

  多进程/多请求;

http提供了多种响应模型(称为httpd的MPM):

  prefork

  worker

  event

常用的客户端浏览器:

  IE

  Firefox

  Chrome

  Opera

  Safari

常用的Server:  

  Apache的httpd

  IIS(不仅是纯粹意义上的Web服务器还是应用程序服务器,能结合.net解析asp、asp.net等动态脚本)

  Nginx

  lighttpd(德国开发的开源软件)

  thttpd(嵌入式用到的)

应用程序服务器:(都能提供Web服务,但并不是纯粹意义上的Web服务器)

  IIS

  Tomcat(Apache的开源(Open Source)的,解析JSP)

  Websphere(IBM的(全球最牛的,Java企业级应用程序,解析JSP的,商业产品(commodity)))

  Weblogic(早期属于Bea,后被Oracle收购(83亿美元),解析JSP,商业产品(Commaodity))

  JBoss(当前属于RedHat,分为开源版和商业版(买RedHat的服务),是重新封装的Tomcat,在其基础上做了更为丰富的包装)

www.netcraft.com  此网站会每隔一段时间会统计一次全球互联网上Web服务器各产品所占的比例。

原文地址:https://www.cnblogs.com/long-cnblogs/p/10553203.html