1969年,美国国防高等研究计划署( ARPA ,Advanced Research Projects Agency )开始建立一个命名为ARPANET的网络。当初,ARPANET只联结4台主机,从军事要求上是置于美国国防部高级机密的保护之下,从技术上它还不具备向外推广的条件。
1983年1月1日,原先ARPANET使用的交流协议NCP(Network Control Protocol)成为历史,TCP/IP开始成为通用协议。
1986年,美国国家科学基金会(National Science Foundation)建立了大学之间互联的骨干网络NSFNET,这是互联网历史上重要的一步。
互联网的发展当然也离不开操作系统的发展,起初贝尔实验室给大学研究室提供的UNIX,是附带源码的,各个研究室可以自行修改。1977,Bill Joy(比尔·乔伊,Sun Microsystems联合创始人,03年离开SUN) 伯克利大学的学生,编译发行了 BSD(Berkeley Software Distribution)。BSD UNIX 是第一个包含了网络协议栈库的UNIX(一开始支持的还是NCP协议),这个库也就是熟知的BSD Sockets。通过将套接字与Unix操作系统的文件描述符相整合,使得网络读写数据和读写本地文件一样容易。BSD Sockets几乎成了网络访问的标准,其他系统的Sockets多多少少是基于BSD Sockets修改而来的,即便是Windows中的Winsock也借鉴了BSD Sockets。
乔布斯1985年被赶出苹果,后来他创建了NeXT.Inc,并开发出NEXTSTEP操作系统。这个操作系统是基于Mach和BSD(混合内核 Hybrid kernel)的。1988年NeXTSTEP第一个正式发布版本问世了。
至于超文本的概念其实在HTTP之前就已经被提出来了,预言了一种非线性结构的文本,只是一直没有应用到计算机中。
1980年中Tim Berners-Lee到CERN工作,几个月间创建一个以超文本系统为基础的项目,方便研究人员分享及更新讯息。同时,他创建了一个原型系统,叫ENQUIRE。 但工作了几个月就离开了CERN,转到一个图形计算相关的公司工作,并在工作中积累了网络编程的经验。
1984年,伯纳斯-李以正式员工的身份重返CERN,并于1990年开始着手他构想了多年的万维网以及超文本协议,WorldWideWeb项目,只花了两个月开发在年底开发出来。于是世界上第一个Web出现了,而第一个Web正是构建在NeXTcube工作站上的,运行着NeXTSTEP系统。
后来伯纳斯-李创建了非赢利性的万维网联盟W3C。为Web的良性和谐发展做出了巨大的贡献。
HTTP的全称为Hypertext Transfer Protocol,也就是所谓的超文本传输协议。是一个C/S(客户端/服务器端)结构下的请求响应协议。
在HTTP之初,只是用来传输静态内容,一个URL对应网络中的一个文件,不管你是谁,什么时候,用什么浏览器访问,返回的内容都是一样的,所以这是一种没有状态(stateless )的访问。所以HTTP一开始设计成无状态的也是可以理解的。
但是随着Web的不断发展,动态内容的需求出现了,所以状态的必要性显现出来了。现在一般都有Session的概念 ,服务器端一般可以通过以下方式来实现Session:
下面我们再来看看HTTP请求响应的过程 当TCP连接成功后,HTTP的请求响应总的来说就分两步:
以下数据来自 WireShark抓包的数据
1.发送GET请求
GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22 Accept-Encoding: gzip,deflate,sdch Accept-Language: zh-CN,zh;q=0.8 Accept-Charset: UTF-8,*;q=0.5 Cookie: BAIDUID=3D028EC08E879EE43F74D73F5C5A3E6D:FG=1; BDUT=btisCE4CE66A884493DB42E76032CA2D85AB13d15f1600c2
2.服务器端发送响应
HTTP/1.1 200 OK Date: Fri, 22 Mar 2013 06:54:22 GMT Server: BWS/1.0 Content-Length: 4278 Content-Type: text/html;charset=utf-8 Cache-Control: private Expires: Fri, 22 Mar 2013 06:54:22 GMT Content-Encoding: gzip Set-Cookie: H_PS_PSSID=2071_1435_1944_2068_1788; path=/; domain=.baidu.com Connection: Keep-Alive Content-encoded entity body (gzip): 4278 bytes -> 10329 bytes
如果Connection是keep-alive的话,tcp连接不会立即关闭。从HTTP/1.1起,默认都开启了Keep-Alive。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache,Nginx)中设定这个timeout时间。
Web Server 的功能其实很简单,就是接收HTTP请求,并对请求进行响应。
Web起初只支持静态的文件,后来为了支持动态的内容,就制定了一套web服务器执行脚本并返回结果的标准, 后来这套标准发展出了CGI标准。
每次执行CGI脚本都需要新建一个进程(fork-and-execute),在这个进程还可能需要加载解释器之类的动作,所以代价比较高,如果短时间cgi访问较多的话,会很容器使得系统资源耗尽。
FastCGI,是对CGI的一个优化(或者说是对CGI的一个扩展),提出了FastCGI Server的概念,FastCGI Server在启动后会预先加载多个CGI解释器进程,用于等待请求,其实也就是多了一个进程池的概念。减少不必要的创建销毁CGI进程的代价。Web Server将环境信息以及请求的信息通过UNIX Domain Socket的方式(比如Web Server和FastCGI在同一个机器上) 或者tcp连接(FastCGI Server分布在不同的机器上),然后FastCGI处理好了以同样的方式的连接将内容返回给web server。 对于不同的语言,FastCGI Server 可能会有不同的语言的实现,这些FastCGI Server并提供相关的API接口供你的web app使用。
SCGI(Simple Common Gateway Interface),和FastCGI类似,不过简单的多,没有FastCGI用得多。
AJP(Apache JServ Protocol,Apache 1.x通过mod_jk模块实现,2.0中直接集成了AJP Connector)它是一种二进制格式的传输协议,所以性能比较可观,一般后端为Java Servlet 容器,Apache Tomcat和Jetty这两个Servlet容器都支持AJP协议。
以上的CGI,FastCGI,SCGI以及AJP这些都可以看做数据交换的协议,和语言无关的。
现在再将视线往Web Application这边移一步,这里说说Python的情况,在2003 出现WSGI之前,你若要使用Python写一个Web程序,可以专门针对CGI或者FastCGI写,也可以针对mod_python(集成了python解释器)写,为了解决这种Python Web应用编写时API不一致的情况,提出了WSGI(Web Server Gateway Interface),在Web Server 和 Web App之间增加一个抽象层,使得Web App这边的接口得到统一。一般所谓的协议或者接口其实都需要两方,WSGI也不例外,分为WSGI Server端和WSGI App端,WSGI Server端也就是所谓的那个抽象层。 有了WSGI,我们写的Python Web App可以在所有的兼容WSGI的Server上跑起来了。在WSGI App这一层接口统一的另一个好处就使得是通用的Web组件成为可能,也就出现了所谓的Middleware中间件。
WSGI Family
Web Server Interfaces
而至于Java语言,其用于Web开发的标准为Servlet。目前Servelet已经发展到3.0版。
常用的网站部署方式 前端web server 比如Apache,nginx,lighttpd,HAproxy用来直接处理用户的请求以及给用户响应,如果是静态文件的请求,那么web server直接给用户静态文件,毕竟前端的web server一般都是c语言写的,效率较好。 而动态的部分,则由 web server转至后端的 app server进行处理,传送的方式可以是cgi,fastcgi,ajp,或者直接反向代理。 像Apache或者Nginx都可以通过一定的方式支持FastCGI。 比如一下方式可以作为某个Python Web App的部署方式:
Nginx/FastCGI <----FastCGI----> FastCGI/WSGI Server
还有一种方式就是前端的Web Server只负责请求的转发,也就是反向代理的方式,后端的Web App Server本身就集成了Web Server的功能:
Nginx<----反向代理---->Web App Server Instance1 ^ |----反向代理---->Web App Server Instance2
Web Application的开发依赖于 web app server/framework,需要遵循相应的API。 一般Web App都分好几个层,表现层,业务逻辑层,持久层。