web 服务整理
web 服务器
web 服务器其实是一个很宽泛的概念。
就是驻留在计算机中, 可以处理 web 请求 并返回响应响应的程序。 都可以叫 web 服务器。
主流的 web 服务器 是 nginx, alpha
但其实, 一个 python http 应用, 一个 go web 应用,一个 java web 应用, 不使用 nginx 和 alpha 也是一个 web 服务器。
当然 还有一种说法是 web 服务器 单指 静态页面的 web 服务器。 自然而是 就是 nginx 和 alpha 这种了。
HTTP Server 本质上来说都是这样几件事
监听端口
接收(accept)socket 连接
解析 HTTP 请求
使用通用或专用协议对请求进行分发
接收分发的请求产生的运行结果
将结果格式化成 HTTP Response 并写到 socket 里面
关闭连接或者 Keep-Alive
区别一方面在于用了什么语言来实现(Tomcat 用 Java),一方面是分发时支持的具体协议,Tomcat 只支持 Servlet 接口,Apache 和 nginx 支持 CGI、FastCGI、反向代理(可以认为是用 HTTP 协议进行 HTTP 请求的分发)、静态资源(可以认为是分发到磁盘读写)等,还可以用扩展模块支持其他分发方式(比如 WSGI)。
除此以外就都是实现方式的问题了。我们进一步可以说一下进程内分发和进程外分发的问题,有些分发方式是进程内分发的,需要通过内存传递一些对象,这种分发方式通常也是绑定语言的,所以一般必须用相应的语言实现(比如 Servlet);某些语言有特殊的 FFI(如 Python 有 C API),也可以通过 FFI 的方式调用。另一些分发方式是进程外的,只要序列化格式匹配就可以在不同语言之间通用,如 FastCGI、HTTP 等,这些分发就可以用统一的方法。
cgi common gateway interface
通用网关接口。
CGI(Common Gateway Interface)公共网关接口,是外部扩展应用程序与 Web 服务器交互的一个标准接口。
这里的 外部扩展应用程序 其实是 相对于 web 服务来来说的, 其实就是 能生成动态页面的 web 服务应用。
演进历史
最开始 web 服务器 其实只支持静态页面。
后来为了支持动态页面, 就出现了 cgi 这种技术。
cgi 是一个古老的技术,最开始 cgi 是很落后的, 一个请求到 alpha, alpha 创建一个 cgi 进程 执行 应用 生成动态页面, 然后返回。
后来有了 fastcgi, 就是 把 web 应用先启动起来 然后驻留在内存中, 来一个请求 找空闲的 应用进程来生成动态页面, 而不是创建了。
cgi 程序
通常说的 一个 cgi 程序,其实就是 生成动态内容的一个程序。
cgi 主要的作用就是 交互契约。
web 服务器 与 web 应用之间 交互的协议契约。
可以是 web 应用 直接实现了 cgi。 比如 一些框架都实现了 cgi, 比如 flask。也可以是 一个单独的中间件 实现了 cgi。 比如 uwsgi。
实现了 cgi 的程序, 主要的作用 就是 解析请求 解析路由。
浏览器不通过 web 服务器也能直接访问 cgi 程序。
这就是 就算没有 nginx,http 请求也能直接访问到 一个 python web 服务。
wsgi
wsgi 是 python web server gateway interface。是 python 专用的 一种 cgi 协议。
uWsgi 服务器
uWsgi 服务器 是 实现了 uwsgi wsgi http 协议 的 一个 web 服务器。
uwsgi 协议 是一种 uWsgi 服务器专用的 cgi 服务器, 效率更高。
所以 我们通过 nginx+uwsgi+python 实现的时候,其实是 有很多选择的, 可以通过 cgi 的方式, 也可以通过反向代理的方式。
选择 cgi 的方式,其实就是 要给 nginx 配置 cgi 扩展。
而反向代理, 只需要 配置转发规则即可。
uwsgi 这么牛吗
uwsgi 想要继承 fastcgi 的这种好处,它通过将消息分片的方式,可以在一个 socket 上并发传输多个请求,这样就解决了一个连接上一次只能传输一个请求的问题。熟悉 HTTP2.0 的话会发现这个分片机制跟 HTTP2.0 很像。
cgi 是面向进程的。
因为规范里说明了, 进程间的 通信协议接口。
当前其实都是 反向代理, 不会用 cgi 了。
tomcat, go server。 根本不需要 nginx 配置什么 cgi 模块。直接就是 转发。
所以 cgi 是一个 过时的技术了。
一个 web 应用服务,不一定非要用 cgi 规范。
只要能解析请求 解析路由,他就能实现一个 动态的 web 应用。
所以 go 的 http server 是不需要 cgi 的, 自己解析请求了
那么 go 的 http/cgi 包是用在什么场景的, 注释里写了 一个请求就要开启一个进程,多垃圾啊。
直接用 http server 不香吗。
评论