很早的时候不知道什么是服务器,给我感觉好象很抽象。后来接触了Linux,配置过几个服务,如
Apache,FTP,NDS SendMail等等,原来破电脑加点服务软件就可以称为服务器,多少有点让我目瞪口呆。
那个时候,水平也差,基本上是只处于简单配置水准,自己感觉就像是个网络管理员。 Linux本身可以看
做是服务器操作系统,或者说是个大一点的服务软件,在/home目录下,可以建立很多用户目录,自己管
自己的东西,当然你也可以给别人看,只要给对方权限就行。这所谓的东西,应该只有一份吧,我给了甲
乙两人读写权限,同一时,甲乙都读,估计不行,线程安全的。实现方式,想起来,用操作系统的文件系
统来说,就应该是信号量;用数据库的思想来说,应该是悲观锁乐观锁什么的,反正是一把锁。但是,甲
乙两个人同时登入是OK 的,会创建两个shell,配合甲乙两个人实现独立操作。本质上讲,甲乙两人能连
到我这里,是借助于一种程序的,当然配合这程序,我这里也得需要一种程序。这样看,好象有C/S的意
思,但是,基本上Linux把C/S的两端的程序都装了,实际中,就好象没有这么C/S个概念。 Ftp服务和上
面服务很类似,假如把Linux比做顶层容易,在这个容器下就可以加Ftp组件,那个这个容器与组件之间关
系复杂,再加上是C/S 概念,F tp组件实现Ftp协议,服务端和客户端分出,至少在概念上多了层繁杂。对
此关系,我没有研究过,谈不出什么来。 转到J2EE 上来,Apache服务实现HTTP协议,假若需要实现动
态网页服务,则可用Apache-Tomcat服务,当然还有其他的服务器,只要服务实现Servlet/Jsp容器功能就
行。服务器上有东西,当然也是独一无二的一份,甲乙两个人可以同时登入服务器,同时修改,同时存
取。各管各的,甲修改后的这份东西不影响乙的那份,乙也同样不影响甲,服务器上还是最早那份,自始
至终也不会变。把Tomcat也比做一个组件,登入功能没有放到顶层容器Linux去,就是说要由组件自己来实
现,其实,现实中Tomcat(Servlet/Jsp容器的一种)也没有做这个功能,它下面还有有一个组件 叫
Servlet,由它来实现,基本上,登入功能的实现还得让开发者自己来写。我在想,为什么不放到Tomcat中
去,简化开发者的负担呢? Tomcat组件由一些小组件构成,这些组件有层次,有先后次序的关系。S
ervice 到 connector,再到Engine,再到Host,最后在Context停留。一个Context对应于一个Web
Application。Context也可以看做一个容器,它上面有ServletManager和SessionManager组件,我的意
思,再设计个LoginManager上去。J2EE开发者只开发真正的业务逻辑。真正的业务逻辑由什么语言工具
来开发?当然是Servlet了,它比较复杂,把它本身当做为一个业务来考虑,外国人发明了
Struts,Tapestry,WebWork,JSF等等。我这里拿Tapestry来说事,Tapestry完全用Java 写的,它继承于
HttpServlet。Tapestry主要由一个或者多个引擎构成,每个客户都用这个引擎,这些引擎没有副本,只有
它自己。引擎管理着一个页面池,里面放唯一的互不相同的页面,这些页面可以被任何一个客户口访问。
说到这里的话,和操作系统的内存管理很像,从硬盘读取很费时间,从内存上读取就快很多,所以内存和
硬盘之间有个调度逻辑,同样,从页面池中访问页面速度要快很多,因为不要组装页面了,页面是现成
的。读页面,假如页面池中有该页面,就直接读,读完了再放回去;假如没有,就得先组装该页面后才能
读取,读取完了也放回到页面池中去,下次读这张页面,就不需要组装该页,提高速度。按照这个思路,
甲读完一张叫X 的页面,且做了修改,读完后放回页面池去,接着乙开始读这张X页面,从页面池中获取,
发现是甲修改了后的X 页面。这样的话就乱套了,Tapestry(当然其他的Web构架也可以这样)的开发者
很聪明,加了一个PageRecoder 结构,专门用来解决这个问题。这个解决方法是个亮点。继续说
Tapestry,Engine 其实是由“Tapestry 的 Servlet ”放到一个持久色session中去的。用Engine它来处理
各个客户端的请求,假如让我来设计的话,页面的内容已经不用管理了,Engine的PagePools和
PageRecorders已经可以做好,但是,对于每个客户的请求怎么做处理呢?比若甲发出这么一个请求
http://mysite.com/index.page?pid =1 ,乙发出这么个http://mysite.com/index.page?pid =2,这pid的值是不
一样的,怎么保存这个量?没有看Tapestry的资料,我自己猜想:利用Tapestry的上一层容器中的
SessionManager先做出判断,利用sessionid判断出这是甲乙两个用户的请求,自然会创建出两个会话。
Engine把pid的值放到各自的session中去。要做到可以存取这个pid变量,那么Engine要有到这2个session
的指针才行,用RequestContext是否可以实现这个“指针”的概念呢?想起来是应该可以的,
RequestContext可以看成是HttpservletRequest和HttpservletResponse的集合,而这2个不正是基于
session会话机制的吗?String temppid = requestContext.getParameters(“pid”),
requestContext.getSession().setAttribute(“pid”,temppid);这样就pid变量放到各自的session中去了。
而页面发出这样http://mysite.com/index.page?pid =1之类的请求,就可以用Component来做了,必须要做
到,在RenderComponent之后的,完全转变成这种http://mysite.com/index.page?pid =1类试的请求,以便
可以让浏览器解析之后的页面上用户一点,就可以发出该请求。