震惊。服务器体系结构一篇通。速看。

一、前言

希望信息技术相关知识能像数学、物理学等传统理科一样严谨————我最近被一些乱用专业名词的作者搞的头很大,像一条大头鱼。

所以,请不要将“协议”与“实现”混在一起说,如————“什么是WSGI?什么是CGI?什么是uWSGI?”

答:WSGI、CGI都是协议。uWSGI根据WSGI协议实现的一种Application服务器(又称动态服务器,还称脚本解析服务器,知道我为什么头很大了吧————别名太多了)

还有「服务器」和「服务器软件」这两个概念也很混淆,现在的人喜欢把「服务器软件」叫做「服务器」————Nginx是服务器软件,不是服务器。但是虽然我知道这个叫法不好不严谨,但是已经习惯成自然了,因此下文中的「服务器」大多也是指「服务器软件」。

二、一切的一切都是由万维网这个概念开始的(万维网又称Web,还称WWW

伟大的伯纳斯-李在1991年8月6日,正式向全世界介绍了万维网,万维网是由他发明的三项关键技术构成的:

·URI:统一资源标识符

·HTTP:超文本传输协议

·HTML:超文本标记语言(或者我觉得这里把HTML换成「资源」更能解释当前的网络)

在万维网中,每台电脑中有用的文件,都被称为一个“资源”,并且由一个全球唯一的“统一资源标识符”(URI)标识。

我们通过「以URI为输入参数发起HTTP请求」的方式来获取资源,资源通过HTTP协议从「持有资源的电脑」传送给「发起请求的电脑」。

我认为这才是互联网的本质————全球每台电脑上的每个资源都有自己的名字(URI),在双方允许的情况下,我们可以用这个全球唯一的名字,通过HTTP协议传输其对应的文件。

当然————万维网是互联网所能提供的服务之一,万维网不是互联网。

三、我画的后端体系图

我觉得我画的这图无敌清晰,它要是完全正确的话,简直就是麦克斯韦方程组之于电磁学的存在,所以也请诸位看官给它找找毛病。

四、理解我画的后端体系图所需要的知识

问题1:什么叫关系型数据库?什么叫NoSQL数据库?」

答:数据库分两种:关系型数据库和非关系型数据库,而非关系型数据库就是我们说的NoSQL型数据库。

非关系型数据库的优势在于其「性能」和「可扩展性」。性能好是因为其不需要经过SQL层的解析,可扩展性好是因为其基于键值对存储,所以数据没有耦合性,十分容易扩展。

关系型数据库的优势在于其「复杂查询」和「事务支持」的能力。复杂查询能力是因为可以使用SQL语句进行查询,事务支持则使得对于安全性能要求很高的数据访问操作得以实现。

问题2:「什么叫静态资源?什么叫动态资源?」

答:静态资源就是在你电脑里现成儿的文件,比如你先写好了一个“fuck.html”文件,然后存在你的电脑里,当别人通过URI请求你的这个"fuck.html"时,你的服务器可以直接将其通过HTTP协议传输过去。

动态资源则不是这样的,动态资源是由你的程序,根据别人发过来的HTTP请求,动态生成的资源。比如你需要根据不同用户的用户名生成一个界面————“欢迎XXX光临”,这个XXX可以是任何用户的用户名。此时你就需要用程序来生成内容不一样的文件,生成之后再将它通过HTTP协议传输过去。

问题3:「什么是HTTP服务器?」

注:HTTP服务器有很多别名————Web服务器,静态服务器,反向代理服务器

但是,做为反向代理服务器只是HTTP服务器众多功能中的一个,故不可理解为HTTP服务器=反向代理服务器。(况且这两个名词也不是一个层级的,一起说就好比是问一个INT型变量是不是等于一个BOOLEAN型变量————即杜甫和滕王阁序哪个屌?)

答:HTTP服务器就是只能处理静态资源请求的服务器,也就是说,你的程序无法直接跑在HTTP服务器上。现在市面儿上流行的HTTP服务器有:Apache、Nginx、IIS等。

问题4:「那么我们用于处理用户HTTP请求的程序跑在何处呢?」

答:虽然我们的程序无法直接跑在HTTP服务器上,但是我们可以通过实现一个叫CGI协议来让「应用程序」间接跑在HTTP服务器上。

问题5:「什么是CGI协议?什么是WSGI协议?」————注意了,我认为我说的是全网最清楚的

答:最初,HTTP服务器只需要响应静态资源的请求,也就是把服务器文件系统中的每一个资源对照成URI,然后通过HTTP协议把这些已经存在的资源传给发起HTTP请求的客户端。

后来,仅仅是响应静态资源的请求已经满足不了人们的需求了————人们需要动态的返回数据,也就是通过程序解析收到的HTTP请求,并针对该请求现生成一份儿数据返回给客户端。

而这个运行在HTTP服务器上,负责处理HTTP请求,并生成响应数据的程序,我们称之为「服务器脚本」。

最初,不同的服务器使用不同的方式与脚本交换信息(服务器给脚本提供客户端传给它的HTTP请求信息,而脚本给服务器提供自己运算完得出的HTTP响应信息,图例如下:

因此,不可能有那个脚本可以不做修改而运行在不同的服务器上————你Apache服务器上能运行的脚本,无法直接拿到Nginx上运行。

那这就很姜硬了,部署的时候想换个服务器还得重新写脚本,很不方便。

因此,NCSA(国家超级计算应用中心,美国的)发明了一个协议来解决这一问题。这个协议就是CGI,它标准化了服务器程序与脚本交换信息的方式。

什么事儿一标准化就简单了,一经推出,CGI协议广受好评,被所有的知名服务器软件采用————例如Apache、IIS、Nginx和基于node.js的服务器软件。

根据CGI协议中所规定的,服务器把「HTTP请求」中的数据写进命令行(就像我们出学C语言时,用标准化输入/输出在命令行中与程序互动一样),然后脚本通过类似于scanf这样的函数把数据读进来,再通过类似于printf这样的函数向命令行输出一个HTML(当时脚本的作用主要就是生成HTML,因为当时还没有手机应用,不用生成什么JSON给手机客户端),然后服务器拿着这个HTML返回给客户端。

但是,随着时间的推移,人们渐渐发现CGI协议有很多的缺点。例如它规定针对一个HTTP请求就要新开一个子线程去处理————这样的话,每当服务器收到的请求一多,很快就会不堪重负而崩了。

所以,根据CGI协议,后来人们又制定出了一些它的改进升级版本,如FastCGI协议。

「那WSGI是做什么的呢?」

WSGI协议的发明,是因为当时类似于FastCGI这样的改进协议太多了,Python的开发者用哪种的都有————于是这就又造成了不同服务器软件需要搭载不同的脚本的问题(CGI协议本身就是为了解决这个问题而产生的)

于是Python社区给Python自己制定了一个官方的CGI协议的升级版本,叫WSGI协议。(注意,千万不要把协议和具体实现搞混,WSGI不是Python版的CGI实现————我在一个知乎答案底下看到过这样的言论)

WSGI协议规定了三个内容:

·HTTP服务器:如HTTP服务器

·中间层:我认为中间层的实现就是Application服务器,也就是python中的uWSGIgunicornJava中的Tomcat————我不是很确定这一点,因为没有文章中明确的给出这样的解释,所以这是一个personal opinion,欢迎大家来讨论。

·服务器脚本:如Werkzeug框架+我们自己根据自己的业务逻辑写的Python代码

HTTP服务器与服务器脚本之间的沟通需要通过中间层来实现————

对于服务器脚本来说,中间层扮演服务器;

对于HTTP服务器来说,中间层扮演服务器脚本。

问题6:「什么是Application服务器?

注:Application服务器有很多别名————脚本解析服务器,动态服务器,应用服务器

还记得「HTTP服务器」上面无法直接运行脚本程序吗?

「Application服务器」上可以直接运行脚本程序,它接受并分析客户端的HTTP请求,调用响应的「服务器脚本」完成对该请求的处理,然后返回相应结果。

虽然一些「Application服务器」也具有「HTTP服务器」的功能,但通常「Application服务器」仍然会和「HTTP服务器」配合在一起使用,这样做有以下两个优点:

·动静态资源分离————让动态资源的请求交给「Application服务器」,静态资源的请求则直接由「HTTP服务器」返回到浏览器,这样就可以大大减轻「Application服务器」的压力。

·负载均衡————当业务压力增大时,可能一个「Application服务器」实例不足以应付业务需求,那么这时可以启动多个「Application服务器」实例进行水平扩展,而「HTTP服务器」的负载均衡功能可以把请求通过算法分发到各个不同的实例进行处理

问题7:「什么是前向代理服务器?什么是反向代理服务器?

「前向代理服务器」

当客户端不被允许直接访问服务器时,就需要通过「前向代理服务器」去间接访问目标服务器。(这有一点像代购————我不想出国,但我想买韩国....呸,我想买巴基斯坦的洗面奶,于是我拜托一位老到巴基斯坦出差的朋友帮我买)

「反向代理服务器」

客户端想请求服务器上的资源时必须先经过「反向代理服务器」,这个反向代理服务器一般有以下几种用途:

·内容分发网络:有一个超大的网站,每天都有世界各地的用户在访问。于是这个网站搭建了一个反向代理服务器,把用户的访问导入到离他最近的服务器上去处理。

·重定向:使用「HTTP服务器」把动态资源请求重定向到「Application服务器」上去。

问题8:「什么是模板引擎?(Django是什么?Jinjia2是什么?)

答:Django和Jinjia2都是基于Python的模板引擎,就如同PHP的Smarty一样。

模板引擎被发明的目的是为了让前后端分离————让Python或PHP或Java或其他语言和HTML分离。

(我不想贴模板引擎的定义了,自己查去)

问题9:「 Werkzeug是什么?

答:Werkzeug是Python基于WSGI协议写的函数库,它的应用很广泛,基于BSD协议。

五、结束语

何炅老师曾经和韩国人打了一个赌,说假如有人要收藏邵励治的文章,他一定会先点个赞。

最后何炅老师都哭了。