web服务器一些概念

2023-05-16,,

一、Web服务器

Web服务基于HTTP协议,HTTP协议基于TCP/IP协议。

HTTP请求底层必然是套接字,也就是TCP协议,HTTP服务器就是监听端口的一个守护进程。

它负责HTTP连接的建立、根据HTTP协议解析请求等底层处理。

常见的Web服务器有Nginx(俄国造),Apache(Apache造),lighttpd(德国造),IIS(微软造)。

Nginx跟Apache等普通服务器是不一样的,Nginx有反向代理功能,这决定了它可以以一个“大管家”的身份凌驾于其它Web服务器之上。

如果只有Web服务器,那么只能访问静态资源。要想生成动态内容,就需要程序。

二、CGI

CGI即通用网关接口(Common Gateway Interface),是Web服务器和用户程序之间进行交流的一种接口。它是语言无关的。

它的缺点如下:

效率低下:每一个连接 fork 一个进程处理。
功能有限:CGI只能收到一个请求,输出一个响应。不方便对请求进行过滤,比如验证一下用户有没有登录。

三、fastCGI

CGI的缺点是效率低,fastCGI维护一个线程池,效率大大提高,不用每个请求都开辟销毁线程。它也是语言无关的。

四、WSGI

Python Web Server Gateway Interface,类似于CGI,但是它是语言相关的,它只适用于Python。WSGI是Web服务器和Web应用之间进行交流的一种接口

WSGI之于Python相当于Servlet之于Java。

下面举个例子(来自廖雪峰Python教程)

首先,实现一个请求处理函数,写在hello.py中

# hello.py

def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '<h1>Hello, web!</h1>'

以上代码中:

application是处理一切请求的地方,它需要两个参数
environ是一个字典,包含请求参数、路径等信息
start_response是一个函数指针,它需要返回请求状态码和HTML头部,用于生成HTML的header部分,在我看来,这部分也是可以直接return str产生的,可能是WSGI认为这部分与回复体应该分开。
return的内容即为HTML中的内容

要让支持WSGI的服务器来调用上面的函数,最简单的WSGI服务器莫过于wsgiref,这是Python内置WSGI服务器。

# server.py
# 从wsgiref模块导入:
from wsgiref.simple_server import make_server
# 导入我们自己编写的application函数:
from hello import application # 创建一个服务器,IP地址为空,端口是8000,处理函数是application:
httpd = make_server('', 8000, application)
print ("Serving HTTP on port 8000...")
# 开始监听HTTP请求:
httpd.serve_forever()

运行python server.py,打开浏览器访问localhost:8000即可看到结果。但是在python3中会抛出异常。

五、Servlet

Servlet机制是Java Web的标准,Java Web自成一家,没有采用CGI机制,毕竟CGI机制只有python,php,ruby这些脚本语言才用,Java不屑与之为伍。

狭义的Servlet指处理请求的Java类,广义的Servlet指Servlet运行的容器等与Servlet相关的一切东西。

Servlet统一了Java Web各个框架,像struts,spring MVC等框架底层都是Servlet。

同理,WSGI也统一了Python Web各个框架,像Django、Flask、web.py等框架底层都是WSGI,只要是实现了WSGI标准的Web服务器,Python Web框架都能在上面运行。

六、uWSGI

uWSGI是一个服务器,它实现了wsgi协议,从而它就相当于Python世界中的Tomcat,它可以运行一切Python Web程序(因为一切Python Web程序底层都按照wsgi协议来实现的)。

除了wsgi,uWSGI还定义了一种uwsgi协议用于跟其它服务器通信,比如通过uwsgi协议跟Nginx通信、跟Apache通信等。uwsgi只是一种数据传输协议,只有Nginx也支持uwsgi协议才能使得Nginx可以跟uWSGI对话。

七、Gunicorn

corn 玉米

unicorn 独角兽

Gunicorn是uWSGI的竞争者,它也是实现了WSGI协议、可以作为Python Web服务器的一种服务器,也相当于Python世界中的Tomcat。

相比uWSGI,Gunicorn更好用,部署更简单。

八、wsgiref

Python语言内置的wsgi服务器,可以用于测试

九、mod_wsgi

mod_wsgi是Apache的一个模块,跟mod_php一样。

Apache服务器本来不支持php,添加mod_php模块之后就支持php了。mod_wsgi也是一样,添加之后Apache就支持Python了。

现在已经很少使用mod_wsgi了,更多使用Gunicorn作为Python服务器。

十、为啥要用Nginx

Tomcat、uWSGI都是服务器,Nginx也是服务器,那么为啥用了前两者,还要用Nginx?

Tomcat、uWSGI处理动态,Nginx处理静态,像一些静态资源Tomcat也可以处理,但是肯定不如Nginx处理得快,所以Nginx就充当了一个大管家,这个大管家不仅善于处理静态内容,并且可以用于分发请求从而实现负载均衡。

Nginx的作用:

    负载均衡,Nginx占用80端口,其它服务器可以占用多个非80端口;
    拦截静态请求;
    伪静态化并缓存,减少动态请求数量;
    依赖于nginx强大的功能和性能,可以做访问控制,限速,限连接数等等;
    nginx缓存客户端发起的请求,直到收完整个请求,转发给Gunicorn,等Gunicorn处理完成后,拿到响应,再发给客户端,这个流程是nginx擅长处理,而Gunicorn不擅长处理的。

Nginx的作用是反向代理。正向代理指客户端通过代理服务器访问我的服务器,反向代理是客户端通过我的服务器上的代理服务器访问我的服务器上的服务器。

十一、Tornado(龙卷风)

Tornado是一个功能丰富、强大不可方物的库。

    高性能的网络库,这可以和gevent,twisted,libevent等做对。提供了异步io支持,超时事件处理,在此基础上提供了tcpserver,httpclient,尤其是curlhttpclient在现有http客户端中肯定排第一。可以用来做爬虫,游戏服务器,据我所知业界已有使用tornado作为游戏服务器
    web框架,这可以和django,flask对。提供了路由,模板等web框架必备组件。与其他区别是tornado是异步的,天然适合长轮训,这也是friendfeed发明tornado的原因,

    当前flask也可以支持,但必须借住gevent等
    较为完备的http服务器,这点可以和nginx,apache对比,但只支持http1.0,所以使用nginx做前段不仅是为了更好利用多核,也是让其支持http1.1
    完备的wsgi服务器,这可以和gunicore,gevent wsgi server做对比,也就是说可以让flask运行在tornado之上,让tornado加速flask
    提供了完备的websocket支持,这让html5的游戏等提供了便利。像知乎长轮训就是使用了websocket,但websocket手机支持的不是很好,前段时间不得不使用定时ajax发送大量请求,期待手机浏览器赶快奋起直追

参考资料

知乎关于Tornado的讨论

博客园关于Python部署

web服务器一些概念的相关教程结束。

《web服务器一些概念.doc》

下载本文的Word格式文档,以方便收藏与打印。