话说Web服务器通信接口协议
之前写过几篇不同语言框架的http请求响应处理流程,但基本上都是讲述的是框架内部的一个处理流程。然而实际上应用程序前面还有一个Web服务器,之前都没有好好介绍一下,因此本篇文章的目的是介绍Web服务器以及服务器通信接口协议。
之前写的文章的链接:
我们在搭建Web服务时,主要包括两大部分,一个是应用程序,一个是Web服务器,应用程序是真正实现业务逻辑的,但其不负责底层的通信以及原始http协议的解析、响应封装,这部分通用的工作由Web服务器来做,Web服务器负责Socket的建立,监听,处理请求等底层操作。当有客户端请求过来时,Web服务器负责处理,解析后会将请求封装成一个应用程序可识别的对象,应用程序处理后返回给web服务器,web服务器封装成http响应返回给客户端。
看到上面,一个很重要的问题是,Web服务器和应用程序该如何交互,也就是说两者之间是否有共同的一个语言是大家都能听得懂的,Web服务器发送给应用程序的对象,应用程序能否正确识别处理,同时应用程序返回给Web服务器的响应,Web服务器是否可以正确解析?如果让我们自己开发一个Web服务器和应用程序,那好说,只要我自己制定一个约定,两者都遵循即可。然而目前Web服务器有很多,应用程序框架有很多(我们开发目前都是使用框架开发层序,不用造轮子,方便快捷),比如在Python领域,应用框架有Django,Flask,Tornado等,Web服务器有很多,诸如Gunicorn、uWSGI等。这么多的框架和Web服务器,他们相互该如何去通信?这时候,必须要制定一个标准,协议,大家多遵守,只要你遵守了这个协议,大家就互相之间就可以正常通信了。这个就如我们电脑上的USB接口,所有厂商都要按照这个开发产品。
在Python领域,这个接口协议叫做WSGI,Web Server GateWay Service Interface。上述所说的Web服务器和应用程序框架都遵循WSGI协议。WSGI要求开发者自己定义一个http响应函数,用来响应http请求。函数如下:
def application(environ, start_response):
start_response('200 ok', [('content-type', 'text/html')])
return 'hello, web!'
environ包含所有http请求头信息,是一个字典dict,它和cgi环境变量差不多: path_info、request_method、server_name,query_string等等。 start_response是一个发送http响应的函数,它接收两个参数,一个是http响应码,另外一个是http header,它是一个列表list。列表中的元素是一个含有两个str的元祖,这两个字符串其实就是一个是key,一个是value。形式如上面函数。
执行完start_response后,服务器会返回把body,即'hello, web!'给客户端。
关于WSGI的协议的介绍可以看我之前写得文章:
和Python的WSGI类似,Java中同样有相应的接口规范,叫做Java Servlet API,Web服务器诸如Tomcat,jetty,netty等都实现了规范,通常把他们也叫做Servlet容器,同理应用程序框架,spring系列也都实现了该规范,即实现了Servlet,springboot里叫做DispatchServlet,这个可以和Python对比一下,Python里面叫做WSGIHandler,一个道理。JAVA中都是以Servlet为通信协议。看一下其接口定义:
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
乍一看上面的接口感觉比Python的WSGI稍微复杂一些,但仔细看它约定了整个Servlet生命周期的行为,从初始化init,到调用服务提供服务service,到最后的销毁。开发者可以自实现自己在整个生命周期不同阶段的行为。
关于Java Servlet API更详细的介绍可以看对应文档,已在下面参考资料里面列出。
参考资料:
微信分享/微信扫码阅读