《编程机制探析》第二十二章 互联网应用

《编程机制探析》第二十二章 互联网应用

在前面的章节中,我们一直在编程的基本原理和模型中折腾。从本章起,我们将进入真正的应用程序的世界。
《黑客帝国》中,莫菲斯递给尼奥一粒药丸,“欢迎来到真实的世界。”
在计算机界中,也有“真实的世界”(Real World)的说法。比如,我们经常看到这样的话:这种方案看起来很美,但不适用于真实的世界。(That sounds great, but not for real world.)
我不喜欢真实的世界,我只喜欢在理想的模型中畅游。历经多年的应用开发,我早已明白,真实的世界是嘈杂的、琐碎的、无聊的。你很难把东西做得很漂亮,很满意。
为了避免误解,我这里澄清一下。我并非完美主义者,也没有精益求精的精神。我只是希望能够达到一种基本的要求:写出来的东西,用户满意,我自己也满意。
做到这点很难吗?貌似不难,实际却相当难。尤其是复杂度到了一定级别的系统,想做到各方都满意,那几乎是不可能的任务(mission impossible)。
在我使用软件的经验中,只有一些功能简单、明确、固定的小软件,才能让我感到基本满意。
只要软件具有了一定的规模,就一定会有很多不如意的地方。我们(这里,我们是甲方,即软件用户的角色)之所以使用那些软件,不是因为我们喜欢它们,而是因为别无选择。我们只能瘸子里拔将军,从众多不如意中,选一个差强人意的。
这里面有个用户需求问题。用户的需求,都是从现实世界中来的。而程序员要实现需求,则必须根据计算机模型来实现,需要把现实世界中的需求映射到计算机模型中。这两个模型之间,经常存在着难以跨越的鸿沟。程序员怪用户不懂计算机,用户怪程序员不懂业务。最终,妥协的总是程序员。因为,脱离于实际应用的软件是没有用处的,也很难卖到钱。所以,程序员必须紧跟用户的需求。
当用户的需求比较固定的时候,程序员的工作就轻松许多。当用户的需求经常变动的时候,程序员可就苦也。
应用软件大致可以分为两类——产品和项目。产品是指针对某一种行业的通用的软件产品,项目是指针对某一个公司具体业务的软件项目。
有些公司是做网站运营的,不卖产品,而是卖服务。这种运营服务,也可以看做是一种产品。
产品的优点很多。
第一,利润高。写一个好产品,可以卖给整个行业内多家客户。
第二,需求稳定,程序员不需要疲于奔命地应对用户层出不穷的新需求。
产品的缺点也是很明显的。
第一,开发周期长,成本高。一个好产品,从底层架构、功能实现到用户界面,都需要良好的设计。
第二,同质化竞争激烈。由于需求固定稳定,大家都可以了解和学习这些通用的需求,都可以做这类产品,因此竞争激烈。
项目的优缺点和产品正好倒过来。
项目周期短,来钱快。但是,项目的特点是劳动力密集型。没项目时,得养一大帮闲人。项目一旦多了,马上就需要大量的人。想要赚更多的钱,就得接更多的项目,跟起来就越累。这就是劳动力密集型产业的弱点。相对的,产品只需要几个或者十几个核心开发人员即可。赚钱多少,不依赖于人数,而依赖于产品质量。
以上的优缺点是针对软件公司老总来说的。对于程序员来说。做项目积累的经验是博而杂,做产品积累的经验是少而精。
喜欢做项目,还是喜欢做产品,这要看个人偏好。在我看来,大部分程序员都是喜欢做产品的。因为做项目很累,学到的东西又很散很浅。
但是,真实的世界正好是倒过来的。软件行业中,大部分的职位都是做项目的,少部分才是做产品的。因为,通用产品的需求是固定的,胜者通吃,一两家好的产品,就足以霸占整个行业市场了。而项目就灵活许多了,大大小小那么多公司,每个公司都有不同的需求,软件公司永远不愁没有项目做,只要你吃苦耐劳,并且愿意把自己的利润降到极点。
产品难,项目累,何方才是出路?出路在于项目和产品之间的桥梁。针对一系列中小型公司的种种特殊需求,开发出一系列灵活多样的产品。项目可以容易地产品化,产品也可以容易地项目化(定制化)。这应该是软件业的共识了。
好了,鸟瞰完软件行业的真实世界,我们回到地面,来看一些真实世界中的具体问题。
在前面的章节中,我们讨论的各种编程模型,都是基于单一进程的模型,很少涉及到跨进程的模型。
但是,在真实的世界中,所有的软件模型都是跨进程的。道理很简单,我们前面已经讲过了。独自运行在内存中、不和外部打交道的程序是没有意义的。一个程序要有用处,则必须要有I/O(输入/输出),既要接受用户的指令,又要把执行结果输出到外围设备(硬盘、屏幕、打印机、网络等),才能为人所知,才能为人所用。
前面讲过,而所有的I/O,都是和进程外部状态交互,都是跨进程的。比如,最简单的文件操作,实际上就是调用了操作系统的文件管理进程和硬盘控制驱动进程。再比如,最简单的屏幕显示操作,实际上就是调用了操作系统中安装的显卡驱动进程。
简单的I/O如此,复杂的I/O就不用说了。我们来看一个典型的互联网(Internet)应用的例子。这是个很常见、也很重要的例子。在这个例子中,我们将学习到关于互联网应用(也叫做web应用)的知识。现代的软件中,互联网软件占了很大份额,提供了大多数的工作岗位。其重要性不容忽视。这也是本章的主题。
我们先从互联网用户的角度来看。
一个用户打开网页浏览器,访问千里之外的某个网站(Web Site),看到了一个页面。这里面发生了什么事情呢?
首先,浏览器是一个进程。浏览器进程要根据网址访问互联网上的一个网站,它应该怎么做呢?它应该像一条鱼一样,顺着网线游出去,到处打听,找到那个网站,然后,叼了内容,再游回来吗?
不是这样的。它先把网址包装一下,发给操作系统的网络服务进程。然后,网络服务进程就负责剩下的工作。当然,网络服务进程也不会像鱼一样游出去。它只是把网络请求再次包装一下,就转交给网卡驱动进程了。然后,网卡驱动进程再次把网络请求包装一下,就把网络请求信息通过网线,或者无线网络,发送到本局域网中的路由器上去了。
这里,原本的网址请求经过浏览器、网络服务进程、网卡驱动进程的一层层包装,已经膨胀为一个包了好几层的大包裹了。
在这个过程中,涉及到极为重要的网络协议层概念。这是计算机网络编程的核心概念。这方面的内容有很多,写得也很透。我没什么可发挥的,这里只是简述一下。
在现实的编程模型中,网络协议层分为应用层、TCP层、IP层、网卡层。
其中,TCP层也叫做传送层(Transport Layer)。TCP就是Transmission Control Protocol(传输控制协议)的缩写。
IP层也叫做互联网络层(Internet Layer)。IP就是Internet Protocol(互联网络协议)的缩写。在互联网上,每一个直接连接到互联网上的计算机、路由器或者其他设备,都有一个唯一的独立的IP地址。
有读者问了,IP层有地址,TCP层没有地址吗?TCP层是没有地址的。TCP层只有端口(Port),叫做TCP端口,是应用进程向本机网络服务进程申请到的一个整数。用来标志某个TCP通信结点。
TCP端口和IP地址通常是合在一起使用的,合称TCP/IP地址。比如,192.168.1.1是一个IP地址。9052是一个TCP端口。那么,192.168.1.1:9052就是一个TCP/IP地址。
需要注意的是,目前的IP地址大都是4段,叫做IP4,已经不敷使用。以后的IP地址正在向6段发展,叫做IP6,那时候的IP地就是133.189.192.168.1.1这样的了。
在实际的网络服务实现中,TCP/IP也通常作为一层,叫做TCP/IP层。TCP协议和IP协议也通常合称为TCP/IP协议,是网络编程中最为重要的协议。
TCP/IP协议是一个有始有终、有来有回、有请求有反馈的协议。在一个典型的TCP/IP场景中,TCP/IP地址都是成对出现的。一个是客户主机(即浏览器所在的计算机)的TCP/IP地址。一个是服务主机(即目标网站所在的主机)的TCP/IP地址。
一般来说,服务主机的TCP/IP地址(即IP地址和TCP端口)都是公开在互联网公共网络上,是固定不变的,是唯一的公网地址。而客户主机的IP地址只是一个局域网内部的IP地址,只在本网内有意义。至于客户主机中,某个应用程序(比如浏览器)的TCP端口,那更是随即分配的,只在整个网络请求的周期内有意义,用完就丢。
IP层之下,就是网卡层了,也叫做物理层。为了明晰起见,我叫它网卡层。至少现在的计算机架构中还需要网卡。
对应到前面的例子中。浏览器就是应用层。它接受的网址格式,需要遵守相应的应用层网络协议。其中最重要的一种应用层网络协议就是HTTP(Hypertext Transfer Protocol,超链接文本传输协议)。这东西,大家也应该耳闻能详了,无需费舌。如有不明之处,请自行到网上查阅。你看看浏览器地址栏中的内容,打头的就应该是HTTP这几个字母。
网络服务进程负责处理TCP/IP协议,对应的是TCP/IP层。这个网络服务进程有可能是一个进程,同时处理TCP/IP协议。也有可能是两个进程,一个处理TCP协议,一个处理IP协议。还有可能是多个进程,分担着多个TCP和IP协议的处理。
浏览器负责把HTTP协议格式的网址,包装成TCP协议的格式,然后,输出到网络服务进程。HTTP协议包装成TCP协议的过程,有些复杂。
大部分情况下,浏览器需要调用互联网上的DNS(Domain Name Service,域名服务),把网址(即域名)转换成IP地址。这也是一个颇为复杂的服务。这里先不多讲。
网络服务进程负责把TCP协议包装成IP协议,转给网卡驱动进程。网卡驱动进程在IP协议包上在加上自己的网卡物理地址(Mac Address),就把网络协议包顺着网线发出去了。
网络中有一个重要的角色,叫做路由器(Router)。路由器是构成所有网络的基石,无论是局域网,还是互联网。
路由器是一个人际高手,维护着一个巨大的社交网络。二十一世纪,什么最重要?人脉!路由器有一个花名册,其中记录了相连的其他路由器的关系网,这个花名册叫做路由表。依靠着这个巨大的关系网,路由器就可以把经由自己的网络协议包正确地转发给下一个路由器。
网络协议包就像一个四处托关系求人办事的人,总是先从最近的关系户(路由器)打听。路由器就像一个热心的中介人一般,再把网络协议包介绍给关系网中下一个离目标主机更近的中介人(路由器)。
需要注意的是,路由器只解析IP层和物理层。路由器只关心目标IP地址。对于路由器来说,TCP端口和HTTP协议内容都属于不可理解的内容,它对此也漠不关心。
局域网中的路由器接到网络协议包,在外面添加上自己的IP地址和网卡物理地址,根据自己的路由表,就把网络协议包发了出去。这时候,网络协议包就出了局域网,进入了外网(即互联网)。
互联网上的道路和现实世界中的道路一样,是分级别的。分国道、省道、市道、县道。互联网的各个级别的道路上,都分布着各个级别的路由器。
一路上,网络协议包遇到了很多路由器。这些路由器都很热心,甚至过于热心。他们都把这个协议包拆开看一看,看到里面的目标IP地址之后,就去查自己的路由表,看看这事儿能不能帮上忙。路由表中记录了一些相邻路由器的信息。如果路由器觉得帮不上忙,就把协议包扔了,让别人去操心。如果能帮上忙,就把协议包继续向路由表中的下一个路由器传。注意,外网路由器在转包的过程中,是不会添加自己的IP地址的,他还没有热心到这种程度。所以,网络协议包的去程和回程,不一定遵守同一条路线。完全是途中的路由器随即决定的。
网络协议包如同接力棒一般,在互联网上的路由器之间传递着。这种传递,通常是从下级路由器到上级,道路宽度从细到宽,比如,可能从电话线ADSL到光纤。然后再从上级到下级,找到目的网站。
终于找到组织了。网络协议包热泪盈眶。目标网站主机抓到这个网络协议包之后,就不再转发,而是自行处理。至于怎么处理的,暂且不谈。我们回顾一下网络协议包在路由器关系网中的四处寻觅的艰辛路程。
网络协议包一旦出了本机(浏览器所在的主机),就进入了路由器的关系网络,直到最终到达目标网站主机。网络协议包出了本机,在路由器关系网络中畅游的整个过程中,一直是在IP协议层和物理层两层中打转。
当网络协议包就脱离了路由器的关系网,进入了目标主机之后,就进入了更高的协议层——TCP层和HTTP层。
目标主机的网络服务进程,接到了网络协议包之后,根据其中的目标TCP端口(这是目标网站进程的TCP端口),把网络协议包转发给到本机内运行的网站进程。至此,一次TCP/IP协议层上的通信,就完成了一半。
网站进程收到了网络协议包之后,取出其中的HTTP协议内容,就开始忙活,最后得到一个结果(通常是一个页面)。然后,网站进程再把结果打包成一个结果协议包,向客户浏览器所在的局域网的路由器的IP地址发送。这个过程和来时一样。路漫漫而修远兮,吾将上下而求索。不再细述。
路由器接收到结果网络包之后,发现目标IP地址正是自己的IP地址,就抓了下来,不再转发。路由器首先将自己添加的IP地址和物理地址剥去,里面就露出了客户主机的局域网IP地址和物理地址。然后,路由器就把网络协议包发向局域网。客户主机受到这个包之后,就知道自己要的东西到了,一个Nice Catch,抓住,就开始处理。这个过程类似于网站的处理过程。客户主机的网络服务进程先根据TCP端口(浏览器的TCP端口)把网络协议包发给浏览器进程。至此,一次TCP/IP通信就完整地结束了。有始有终,有来有去,有请求有反馈。然后,浏览器进程再处理其中的HTTP协议内容,把网页显示到屏幕上。
需要提醒的是,为了简化起见,我们假设一个网络包去,一个网络包回。在真实的世界中,并不一定如此。如果网络协议包过大的话,会被拆成多个小包。细节是魔鬼。诚不我欺。真实的世界中,充满了各种各样的琐碎细节。
我们可以看到,一次简单的网站访问,牵扯到多少人力和物力。可想而知,互联网路上是多么繁忙,各式各样的网络协议包四处流窜。
值得庆幸的是,浏览器进程并不需要知道这些。浏览器进程只知道申请一个TCP端口,把HTTP请求发过去就行了。这就是网络协议分层的意义所在。各层管各层的事情。
对于浏览器来说,一次复杂的互联网访问,和一次本机的文件访问,没有什么太大区别,都是对进程外部状态的I/O(输入/输出)。
以上的流程,是从客户端(浏览器)的角度来看的。对于我们开发人员来说,我们更关注的是服务器(网站主机)一端的实现。这就是本章及后续章节的主题——Web应用。
这里,我们要说明一下internet和web的区别。Internet是互联网的意思,这是一个计算机术语,是一个新词。Web是一个老词,原意是蛛网。Internet更广义一些,internet应用(互联网应用)包括所有基于互联网的软件,包括小软件,也包括大型网站。而Web则狭义一些,web应用主要指网站。本章的题目叫做互联网应用,但这么写只是为了好看,实际上,本章及后续章节的主要内容就是网站开发,即Web应用。
现在,让我们把目光转向服务端,看看在一次典型的网站访问中,网站主机中发生了什么。
基于网络协议分层的机制,我们不需要考虑TCP/IP层以下的事情。我们只需要考虑HTTP协议层。
当网站接收到浏览器(客户端)发来的HTTP协议包的时候,就会进行相应处理,提供结果,反馈给客户端。这个处理过程有可能非常简单,也有可能非常复杂。
在互联网刚刚出现的原始年代,网站提供的内容都是静态的,只需要根据客户请求,找到相应的网页文件,发给客户就是了。什么叫网页文件?就是HTML文件。HTML是Hyperlink Text Markup Language(超链接文本标记语言)的缩写,是一种XML格式的文本。
静态内容就是一系列的HTML文件。每个HTML文件中通常包括HTML文本、CSS(cascade style sheet,用来定义HTML元素的格式)、Javascript、图片等。其中,图片是最大的资源,其余的都是文本资源,个头比较小。
每个HTML文件都有自己的网址,HTML文件中包含的每一个资源,比如,CSS、Javascript、图片等,也都有自己的网址。因此,一次HTTP请求并不是一次就玩了,通常会引起一系列的内含资源的HTTP请求。
在寂静年代,只需要一个网页设计师,就可以建设一个网站。
历史的车轮总是滚滚向前。随着技术的发展,用户的口味越来越重,错了,是越来越丰富多样,静态内容已经无法满足用户的精神需求了。这时候,就出现了动态内容。于是,网站的建设方式发生了深刻的变化。在静态内容时代,网站建设领域是网页设计师的天下。到了动态内容时代,网站建设领域就成了程序员的天下。因为,动态内容的提供,必须要通过程序。
一开始的时候,典型的动态内容网站的架构是这样的。一个Web Server(也叫做HTTP Server)中,配置了一个个CGI(Common Gateway Interface,公共网关接口)程序。
这些程序为什么叫做CGI程序?我是不太了解的。我进入Web开发领域的时候,CGI模式已经是一种过时的开发模式,虽然还在广泛使用,但是已经不为追赶新潮的程序员所喜。
Gateway是网关的意思,表示内网(局域网)到外网(互联网)的关口,通常就是指局域网的出口路由器。CGI应该就是指网站入口点的意思吧。
CGI程序可以是编译语言,但更多的是解释语言,因为解释语言无需编译,更加方便。由于这个原因,CGI程序通常被称为CGI脚本(Script,通常指一小段解释程序的代码)。
CGI的一个主要问题在于效率问题。当用户发来一个动态内容请求的时候,Web Server就得把对应的CGI进程运行起来。处理完请求之后,再结束进程。也就是,每一个请求都对应一个进程的生灭。而进程是相当昂贵的资源。
除此之外,还有一个原因。那就是CGI模式下,CGI脚本都是一个个分离的脚本程序,彼此之间很难共享什么东西。一个用户的每一次请求都相当于一次独立的请求。一个用户的多次请求,很难形成连续的关系。
这在动态内容时代的初期,不是什么问题。但是,随着用户的要求越来越高,用户希望自己的一连串请求之间,能够连续起来,保持一定的状态。这种一连串请求之间的状态保持,有一个专有名词,叫做Session(会话,会谈)。因为客户端和服务器端之间的一连串请求、反馈就像两个人你一句我一句谈话一样。
两个人初次邂逅,还不认识,等搭上了第一句话之后,就开始热情地交谈起来。这时候,两个人就成了熟人,每一句话都可以建立在前一句的话的基础上,而不用每一次都需要重新搭话。这就形成了一种客户端和服务器端之间的连续的会话状态。
会话(Session)的需求同时对HTTP协议和Web开发模式提出了要求。
HTTP一开始是无状态的协议,一次HTTP请求就是一次TCP/IP连接,然后就断开,结束了。但是,随着时代的发展,无状态的HTTP不能满足人们的需求,人们又在HTTP协议上增加了状态。这是非常重要的概念,我们后面有专门的章节来讲解。
用户连续多次请求之间的状态保持,不仅需要HTTP协议的支持,还需要Web开发模式的支持。因为Web Server总得找个地方把用户的一连串请求的状态存放起来,以便该用户的后续请求可以共享这些状态。在CGI模式下,CGI脚本之间是分离的。要想共享状态,只能借用文件、数据库、网络服务器等进程外I/O存储设备,而且每次都得打开/关闭外部的I/O设备,这个开销也是不小。
为了解决CGI模式的问题,Application Server(应用服务器,简称App Server)的开发模式出现了。App Server是一个独立运行的服务进程。它通过TCP协议与web server交互。当web server遇到动态内容请求时,就把请求转发给App Server处理。App Server就会启动一个线程来处理该请求。
App Server的模式好在哪里呢?首先,线程比进程轻量一些。其次,所有的处理请求的线程都运行在同一个进程空间内,因此,可以共享进程内的资源,最主要的是内存资源,还有一些保持打开状态的I/O设备。
App Server模式一出现,立刻大行其道,占据了CGI模式的不少份额。我赶上的就是App Server这一拨。App Server模式给了程序员偌大的发挥自由。各种层次不穷的网站开发架构模式就是在App Server的构架上创建出来的,并影响到App Server模式以外的领域,比如,CGI模式。
App Server同时也是HTTP Server,可以单独作为Web Server来运行。一个App Server就可以同时处理静态内容请求和动态内容请求。
不过,术业有专攻,App Server专攻动态内容请求,在处理静态内容请求方面不是很擅长。因此,App Server常和Web Server一起组合使用。App Server负责处理动态内容请求,Web Server负责静态内容请求。因为,动态HTML页面中经常含有各种静态资源(比如,很多图片资源),所以,一次动态内容请求,通常会引起十几次静态资源请求。
一次典型的动态内容请求的过程是这样的。App Server收到HTTP请求,就把HTTP请求转发给内部运行的某个网站应用程序(Web Application,简称web app)。一个App Server里面可以跑多个web app,但通常情况下,只跑一个web app。
Web app收到HTTP请求之后,就回去查找动态内容,典型的,是在一个数据库中查找。Web app需要访问App Server进程之外的数据库进程,并获取查询结果。然后,web app根据查询结果,拼装成一个HTML页面,再交给App Server进行后续的处理。动态拼装页面的技术有个名字,叫做模板(Template)技术。这曾经是很重要的一个技术。那时候,各种模板技术层出不穷,争芳斗艳。
历史的车轮继续向前滚动。随着时间的推移,web应用有了长足的进展。无论是在前台(指发送到浏览器的HTML页面部分)还是后台(指服务器端),都发生了深刻的变化。
首先来看前台HTML部分。动态HTML页面的产生,有两种方式。一种是后台服务器端生成。一种是由HTML页面包含的Javascript生成。
第一种方式就是我们提到的Template(模板)技术。第二种方式中,浏览器中的Javascript可以获取用户的操作,直接向后台服务器发送HTTP请求,然后把动态内容取回来,填充到当前的HTML应用中。这种技术有很多名字,ajax,富客户端(Rich Client),等等。这些表述都不太直观。在本书中,我使用Javascript HTTP这个词。
随着Google公司的在线文档办公软件和Gmail的推出(这两个卓越的产品都是用Javascript开发的),Javascript HTTP技术奠定了自己坚实的基础,逐渐成为了web应用交互的主流开发模式。
与此同时,其他的富客户端(Rich Client)技术也进入了人们的视野,主要是Adobe公司的Flash技术。不过,这不在本书讨论之列,先不去管它。
随着Javascript HTTP技术的兴起,HTML页面越来越静态化,曾经喧嚣一时的Template技术逐渐失去了用武之地,陷入了沉寂,慢慢淡出了人们的视野。当然,Template技术的地位只是降低了,并不是消失了。而且,Template还广泛地用于其他各种需要动态生成文本的领域,比如,动态生成代码和查询语句,等等。
以上是前台的状况。我们现在把目光投向后台。服务器端的发展主要在于架构的扩展上。随着用户越来越多,请求越来越多,网站规模也越来越大,一个服务器已经不能满足要求了。这时候,集群(Cluster)技术就出现了。局域网中的多台服务器组合在一起,共同响应用户的请求,这种架构叫做集群(Cluster)。
一个典型的集群架构是这样的。局域网内的计算机分为三层。第一层是十几台或者更多的Web Server,负责应对用户浏览器对静态页面资源(静态文本和图片)的请求。第二层是几台App Server,负责应对用户浏览器对动态页面资源的请求。第三层是一台或者两台数据库服务器(db server),用来响应App Server的请求。
Web Server上全都是静态文件资源,每台Web Server上的静态资源都是一样的,不会改变,是无状态的,因此可以任意扩展。Web Server可以有任意多台,上百台,上千台都可以,甚至可以放到局域网外的互联网上任何一个网络结点上。这也是静态网站的常见策略。
App Server由于需要保持用户会话(Session)状态的,可扩展性就受到了限制。当App Server集群和某个浏览器之间建立了用户会话(Session)关系,那么,该集群必须保证,下一次用户请求过来的时候,还能够找到这个会话状态。实现方案主要有三种。
第一种方案,叫做Session Sticky(粘住会话)。意思就是,当一个浏览器访问集群中某一台App Server时,建立了会话关系。下一次该浏览器请求再次过来的时候,还由这台App Server负责接待。这就像客户专员原则一样。一个客户服务人员跟踪服务一个客户,一直到底。而不是每次都换一个客服人员。
这种方案的缺点在于,难以实现负载平衡。有的App Server客人多,有的App Server客人少,无法最大限度地发挥集群的效能。
第二种方案,叫做Session Replication(会话复制)。意思就是,当一个浏览器访问集群中某一台App Server时,建立了会话关系。那么,该会话关系会广播(Broad)到集群中的其它App Server中。下一次该浏览器请求再次过来的时候,任何一台App Server都可以负责接待。
这种方案的优点在于容易实现负载平衡,大家的工作量都差不多。缺点在于制造了大量的网络通信。
第三种方案,叫做Session Cache Center(会话缓存中心)。意思就是,专门用一个服务器来存储用户的所有会话状态。当一个浏览器访问集群中某一台App Server时,建立了会话关系。这个App Server自己不保存这种关系,而是交给客户关系经理,即会话缓存中心。下一次该浏览器请求再次过来的时候,任何一台App Server都可以负责接待。这台App Server首先要去会话缓存中心服务器中查找是否已经存在了该会话关系,如果已经存在,那么就取出来继续用,如果不存在,就建立一个会话关系。处理完毕之后,再把更新后的会话状态存回到会话缓存中心服务器中。
这种方案的优点在于结构简单,实现容易,也不会产生网络广播,而且,缓存中心不仅可以用来缓存会话状态,还可以缓存其他信息。这种方案的缺点在于,一旦缓存中心出了问题,所有App Server都得忙乱一番,失去响应一段时间。不过,这种缺点可以用备份缓存中心来缓解。因此,这种方案被大量采用。
由于会话缓存中心这种方案的兴起,CGI开发模式又焕发了新的生机。在这种Session方案下,App Server模式和CGI模式站在了同一个起点上。大家处理Session都是要进行网络通信。谁也别说谁。而且,在CGI模式下,还可以省掉App Server。可以直接把CGI脚本放置在Web Server中,这节省了成本和资源。
而且,现在还有一种说法。多进程模式比单进程模式更加健壮。在单进程模式下,一个线程出了问题,可能会引起整个进程死掉。这对于网站来说,是难以容忍的。而多进程模式下,一个处理请求的进程死了就死了,不会影响到网站服务主进程。从这个角度来看,CGI的多进程模式还是一种优点了。这真是,风水轮流转,老树发新枝。
最后,我们再来看db server(数据库服务器)层。由于数据库中装的全都是数据,而且是随时可能会改变的数据,而且是随时可能会变的海量数据。这是一个极为庞大的状态。这种状态几乎是不可能即时复制和传输的。因此,db server是最难扩展的。通常来讲,db server只有一台。最多还有另一台备份数据库,提供一些旧数据的只读服务。
在我看来,数据库集群的发展方向不在于即时复制和传输状态,而在于分布式存储管理。即数据分区域存放到不同的数据库服务器上。但是,这无形中就增加了数据库表格关联查询的难度,从而增大了数据库管理员和数据库应用程序员的工作难度。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值