这是个很长的故事, 让我们从Web服务器来开始。

Web服务器是个挺简单的东西,工作很简单,在80端口上监听,解析客户端发过来的HTTP的请求, 然后把相对应的HTML文件、Image等返回给客户端就可以了。 像这样:

这就是一个静态内容服务器,所谓静态内容,就是服务器端的内容如HTML不会变化,每次请求都是一样的。除非人们手工改了它。

实现这样一个“玩具Web服务器”并不难,只要能了解服务器端Socket编程就可以了, 主要工作是编程处理HTTP协议的细节。

动态内容

但是如果想再往前走一步,让Web服务器能产生动态内容,那就难了。

比如说来了一个HTTP请求,在其中携带者用户名和密码,要求你去数据库做一个查询,看看用户是否存在。

POST  /login

user=xxxx&pwd=xxx

这个静态的Web服务器就搞不定了,它根本,也不应该去查询数据库。

怎么办呢?你可以用某种语言(比如C语言)写个程序, 来查询数据库,假设这个程序的名字叫db-query。

可是你将面对非常棘手的问题:  Web服务器是个进程,db-query也是个进程,这俩货之间怎么通信呢?

(友情提示,下面内容略显枯燥,可跳过)

首先是参数的传递,一种办法是这样:对于每个动态请求,Web服务器进程创建一个db-query的子进程,然后通过环境变量把参数传递过去。

web服务器:

setenv("QUERY_STRING","user=xxxx&pwd=xxx")

db-query子进程 :

param = getenv("QUERY_STRING")。

下一个问题:db-query这个子进程获得了用户名和密码,查询了数据库,怎么把查询结果返回给浏览器?

有个很巧妙的办法!

每个程序都有所谓的标准输出(STDOUT),db-query只要调用printf这个函数,数据就会输出到STDOUT,我们就可以在黑乎乎的控制台上看到了数据输出了。

但是输出到控制台是万万不行的,我们得输出到socket才可以发回浏览器。

每个浏览器和服务器的连接都是一个Socket, 每个socket都有一个文件描述符fd, 如果把查询数据库程序db-query的STDOUT重定向到那个fd,会发生什么?

没错!db-query的所有输出都直接发送的客户端的socket了,Web服务器可以撒手不管了!

当然,如果浏览器要看到的是HTML页面, 那db-query这个程序就需要输出HTML了。

这种方式就就是大名鼎鼎的CGI,当你看到网址中有cgi-bin字样的时候,很有可能就是用CGI实现的。  只要遵循CGI协议, 可以用任何语言来实现动态的网站。

这是人类迈出的一大步,有了这一步,才能在网上购物,办公,社交,聊天......  你才能看到我这篇文章(嗯,也许腾讯把微信公众号的文章都静态化了, 请了解详情的同学告知)

但是,CGI是非常复杂和笨拙的, 主要体现在:

第一,对每个请求,都得创建一个子进程去执行,这是个非常大的开销。

第二,对程序员来说,编程极为痛苦,要操作环境变量,还需要直接在编程语言中输出HTML!

麻烦不麻烦,难受不难受,上个世纪的程序员苦逼不苦逼?

Servlet

怎么才能跳出苦海?必须得做到关注点的分离!

程序员的关注点是:拿到Http 请求中的数据,执行业务, 然后输出Http 响应。 别的什么环境变量,重定向,别来烦我!

那就简单了,让程序员写个类,里边是业务逻辑, 然后我们想办法构建一个HttpRequest对象和HttpResponse对象,传递给程序员的类让他使用不就行了?

谁来创建这个HttpRequest和Response 对象,  然后调用程序员写的类?

静态Web服务器表示我不愿意,我就想管好我这一亩三分地,把静态内容给大家服务好。

Tomcat已经迫不及待地要上场了,我来我来。码农朋友们,我送给你们一个规范,叫Servlet, 你们按照Servlet的规范来写程序,放到我这里运行,别的什么都不用管了。

程序员很高兴,只需要写简单的Servlet就行了,HttpRequest和HttpResponse对象由Tomcat来创建,可以从HttpRequest中获得Header, Cookie, QueryString 等信息, 从HttpResponse中获得输出流,直接向浏览器输出结果, 简单又直接。

Tomcat还郑重向大家声明:对于每个请求,我只会用一个线程来出来,线程的开销可比进程小多了。

对于那个在代码中混杂HTML的问题怎么处理?

Tomcat也有办法, 可以在HTML混杂代码!这就是JSP。执行期其实会被编译成Servlet。

(码农翻身注:请移步《JSP:一个装配工的没落》)

你看,责任分离了,每个人只要办好自己的事情就好。

(注:实际上,我们不会在Servlet中写业务逻辑, Servlet现在通常是一个通往框架的入口。)

WSGI

CGI表示不服:遵循我的协议,任何语言都可以来实现动态网站,你Servlet只是Java规范,不管别的语言了?

Servlet规范确实没法跨语言实现,那要是Python也想做动态Web网站,该怎么办?

既然已经认识到动态网站的本质了, 可以采用类似的思想来处理嘛! 我们为Python也定义一个规范,叫做WSGI (Web Service Gateway Interface)。

让程序员写个类或者函数(称为wsgi application),在其中实现逻辑。让某个动态服务器(称为wsgi server)把Http Request和Response传递给它,就可以执行了。

但是Python表示:我不喜欢你们Java 那一套啰里啰嗦的类,HttpRequest 不就是一些key value吗?放到我钟爱的dict中多好 !我把它叫做enviroment, HttpResponse也没必要,直接用函数的返回值(确切说是一个可迭代对象)就好。

看看,是不是和Java 的Servlet 很像?(当然,忽略了很多细节。)

从本质上来说,都是为了关注点的分离:

1. 用一个动态内容服务器(wsgi server,Tomcat等)来接受并且封装HTTP 请求,降低程序员的负担。

2. 程序员只需要遵循约定(servlet,wsgi)就可以轻松实现自己的业务,不用关注系统的处理细节。

如果你先学的Java,通过Servlet理解了动态内容网站的本质和解决问题思路,再看到Python的wsgi,一眼就能看透,学起来飞快,反过来也是如此。

Web服务器的例子还比较简单,但是也体现出了这个道理:遇到问题要深度思考,努力看到本质,这样才能举一反三。

码农翻身公众号开放投稿,可能是全网最高片酬:

用故事讲技术 ,稿费1000

技术/职场/感悟/面试等,稿费700

翻译类文章,每千字200

详情猛戳: 可能是全网最高片酬,速来!

服务器怎么控制忽略样式_看问题要看到本质:从Web服务器说起相关推荐

  1. 服务器怎么控制忽略样式_使用JavaScript来编写你的CSS样式代码——JSS

    介绍 JSS是CSS的创作工具,它允许你使用JavaScript以声明,无冲突和可重用的方式描述样式.它可以在浏览器,服务器端或在构建时在Node中编译.JSS与框架无关.它由多个包组成:核心部分,插 ...

  2. Nginx源码从模块开发入手,3个项目弄透nginx模块开发丨Linux服务器开发丨C++后端开发丨中间件开发丨分布式丨web服务器

    Nginx源码从模块开发入手,3个项目弄透nginx模块开发 1. Nginx http请求的11个处理流程 2. Upstream, Filter,Handler模块分析 3. nginx如何拒绝无 ...

  3. ubuntu的web服务器_如何在Ubuntu上安装OpenLiteSpeed Web服务器?

    ubuntu的web服务器 Want to install OpenLiteSpeed Webserver on Ubuntu? Today we're going to do just that. ...

  4. python搭建web服务器_用Python建立最简单的web服务器

    利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录的路径下,输入命令:python -m Web服务器模块 [端口号,默认8000]例如:python -m Sim ...

  5. ibm服务器卡在开机界面_使用HTTPS配置IBM Integration Bus Web用户界面

    ibm服务器卡在开机界面 网络用户界面 developerWorks教程< 使用IBM®Integration Bus V9 Web UI配置基于角色的安全性>描述了使用HTTP为Web ...

  6. \(^_^)/ ngnix、lighttpd、apache三大web服务器

    三大WEB服务器对比分析(apache ,lighttpd,nginx) nginx lighttpd apache对比 三大WEB服务器对比分析(apache/nginx/lighttpd) 一.软 ...

  7. 云服务器流量是什么东西_在线科普,买一台云服务器到底能干嘛?

    很多行业外的用户可能会有这样的疑问,买一台云服务器来到底能做些什么,今天队长就科普一下云服务器的应用场景. 云服务器应用非常广泛,既可以作为简单的 Web 服务器单独使用,也可以与其他云产品搭配提供强 ...

  8. ENSP如何开启服务器的http_如何使用HTTP模块在Node.js中创建Web服务器(上)

    当你在浏览器中查看网页时,其实是在向互联网上的另一台计算机发出请求,然后它会将网页提供给你作为响应.你通过互联网与之交谈的那台计算机就是Web服务器,Web服务器从客户端(例如你的浏览器)接收HTTP ...

  9. 服务器系统centos7 x64位,在Centos7.2(64位)下搭建Web服务器

    一:通过Yum安装mysql 1 # wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm 2 # rpm -i ...

最新文章

  1. 全国计算机等级考试c语言程序设计真题,历年全国计算机等级考试二级C语言笔试选择真题...
  2. 中画图title函数_MATLAB-基础画图meshgrid
  3. BZOJ 1601 [Usaco2008 Oct]灌水 (最小生成树)
  4. XCode的控制台调试命令
  5. android浮动标题栏,GitHub - DARTTTTT/LBehavior: 跟随手势滑动,显示隐藏标题栏、底部导航栏及悬浮按钮的Android Behavior Library...
  6. 零基础学python还是c语言-入门是不是应该选择C而不是直接学Python?
  7. VNC+SSH相关应用
  8. 36. Never redifine an inherited non-virtual function
  9. kubernetes mysql pxc_PXC快速入门
  10. 地铁票务管理系统_[地铁票务管理论文] 地铁票务系统 场景法
  11. ssm水电费管理系统java
  12. cosmo是什么牌子_时尚COSMO - 时尚品牌 - 时尚
  13. MPQ文件结构和Partial MPQ文件结构
  14. 初学键盘计算机输入时注意,打字练习说明.doc
  15. 区块链在金融行业有哪些应用
  16. 可视化篇:Echarts2.0引入百度地图
  17. iOS二维码生成与识别
  18. Java基础语法(十三):throw和throws
  19. 破解中国电信华为无线猫路由(HG522-C)自动拨号+不限电脑数+iTV
  20. 笔记:《高效能人士的七个习惯》第七章 习惯四 双赢思维——人际领导的原则

热门文章

  1. linux进程创建截图,命令行程序创建网站截图(在Linux上)
  2. sql 24小时格式_初学SQL,80%都会踩的5个坑
  3. AttributeError: module ‘tensorflow‘ has no attribute ‘InteractiveSession‘或 ‘placeholder‘的解决
  4. Android编译32/64位so or bin(Android.bp or Android.mk)
  5. wireshark常用选项与功能总结【10分钟成为抓包大师】
  6. 多速率多传感器数据融合估计(一)
  7. ios ffmpeg+libx264
  8. vscode之调试es6代码
  9. 四个变量的图表怎么做_EXCEL系列之基础图表总结
  10. 一般将来时语法课教案_优秀教案人教版必修二Unit2——语法专题课训练