WebSphere v4.0 的插件是如何处理HTTP请求的

来源:互联网 发布:淘宝的手表拍卖靠谱吗 编辑:程序博客网 时间:2024/04/28 00:34

http://www-900.cn.ibm.com/cn/support/nav/200202/p24.shtml

WebSphere Application Server V4.0x 版本中Web服务器和WebSphere应用服务器间使用了HTTP 1.1的传送(transport)来通讯,而版本4.0之前,使用的是OSE(Open Servlet Engine)协议。那么,WebSphere V4.0x的插件(plug-in)是如何处理HTTP请求的呢?

了解了插件对HTTP请求的处理模式,将有助于您部署应用的静态页面和动态页面,同时,当您遇到诸如无法访问所有的JSP和小服务程序(servlet)、无法访问特定的JSP和小服务程序等问题时,也有助于您定位问题并解决问题。

这篇文章中将对插件的处理模式加以描述。

当Web服务器接收到一个HTTP请求时,插件需要确认这个请求是否属于运行于WebSphere中的某一个Web应用。如果这个请求不应由WebSphere处理,插件返回给Web服务器一个代码告诉Web服务器去处理这个请求。如果这个请求应该由WebSphere处理,则插件需要确定相应的应用程序运行在哪个节点上,在克隆(clone)的情况下,还需确定应由哪个克隆来处理这个请求。

插件使用的规则在文件plugin-cfg.xml中配置,默认位置是<WAS_HOME>/config 。下面是一个简单的plugin-cfg.xml例子。

=========================================================================
<?xml version="1.0"?>
<Config>
<Log LogLevel="Error" Name="C:/WebSphere/AppServer40/logs/native.log"/>
<VirtualHostGroup Name="default_host">
<VirtualHost Name="*:80"/>
<VirtualHost Name="*:9080"/>
</VirtualHostGroup>
<ServerGroup Name="websphere/Default Server">
<Server CloneID="to0oee2t" Name="Default Server">
<Transport Hostname="websphere" Port="9080" Protocol="http"/>
</Server>
</ServerGroup>
<UriGroup Name="websphere_sampleApp/default_app_URIs">
<Uri Name="/servlet/snoop/*"/>
<Uri Name="/servlet/snoop2/*"/>
<Uri Name="/servlet/hello"/>
<Uri Name="/ErrorReporter"/>
<Uri Name="*.jsp"/>
<Uri Name="*.jsv"/>
<Uri Name="*.jsw"/>
<Uri Name="/j_security_check"/>
<Uri Name="/servlet/*"/>
</UriGroup>
<UriGroup Name="websphere_sampleApp/examples_URIs">
<Uri Name="/webapp/examples/*"/>
</UriGroup>
<Route ServerGroup="websphere/Default Server"
UriGroup="websphere_sampleApp/default_app_URIs" VirtualHostGroup="default_host"/>
<Route ServerGroup="websphere/Default Server"
UriGroup="websphere_sampleApp/examples_URIs" VirtualHostGroup="default_host"/>
</Config>
=========================================================================

当一个HTTP请求到达Web服务器时,插件在XML配置文件中查找路由(Route),一个路由由两个信息来确定,VirtualHostGroup 和 UriGroup 。我们以请求 http://localhost/servlet/hello 为例进行说明。

如果配置文件中存在 VirtualHostGroup 的定义,插件尝试将该请求的域名和端口与VirtualHostGroup 中定义的 VirtualHost 进行匹配。如果配置文件中不存在 VirtualHostGroup 的定义,插件将假定路由与所有的虚拟主机都匹配。本例中,由于HTTP请求的默认端口为80,所以请求的域名和端口为 localhost:80 ,与 <VirtualHostGroup Name="default_host"> 中定义的 <VirtualHost Name="*:80"/> 相匹配。

如果配置文件中存在 UriGroup 的定义,插件尝试将该请求的 URI 与 UriGroup 中定义的 URI 进行匹配。如果配置文件中不存在 UriGroup 的定义,插件将假定路由与所有的 URI 都匹配。本例中,请求的URI为 /servlet/hello ,与 <UriGroup Name="websphere_sampleApp/default_app_URIs"> 中定义的 <Uri Name="/servlet/hello"/> 相匹配。

如果该请求能够匹配到相应的 VirtualHostGroup 和 UriGroup ,并且相应的 VirtualHostGroup 和 UriGroup 同属于一个路由(Route)的定义,则请求将被发送到该 Route 定义中的 ServerGroup 来执行。本例中,相匹配的 Route 定义为:

<Route ServerGroup="websphere/Default Server"

UriGroup="websphere_sampleApp/default_app_URIs" VirtualHostGroup="default_host"/>

所以,该请求将被发送到 <ServerGroup Name="websphere/Default Server"> 去执行。

根据应用服务器是否被克隆了,ServerGroup 中可能定义有一个或多个服务器(Server),下一步就是确定该请求应被发送到ServerGroup中的哪一个服务器。

首先,插件检查该请求的会话亲缘性(session affinity)。如果该请求具有会话亲缘性 cookie ,说明这个会话在以前的请求中已经被分配到了某一个特定的应用服务器。遵从 Servlet 2.2 的规范:"Within an application that is marked as distributable, all requests that are part of a session can only be handled on a single VM at any one time",当会话已经被分配了一个服务器时,这个请求必须发送给同一个服务器。插件在报头或URL中查找名为 JSESSIONID 的cookie ,如果 JSESSIONID 存在,并且包含有 CloneID ,而这个 CloneID 与 ServerGroup 中定义的某个服务器(Server)的 CloneID 相匹配,则这个请求将被发送到该服务器。

如果会话亲缘性(session affinity)没有被建立起来,将根据负载均衡的规则给这个请求和会话分配一个服务器。默认规则是轮循(Round Robin)。轮循的起始点是随机的,也就是说第一个服务器是随机抽取的,然后开始循环。所以对于多进程的Web服务器,不同的进程分别随机抽取其起始点,并不会都把第一个请求发送给同一个应用服务器,保证了应用服务器的使用均衡;另一方面,由于会话并不都由同一个进程处理,所以从Web服务器的整体角度来看,轮循并不是绝对的。负载均衡的另一个规则是随机(Random),这种规则下,会话将被随机分配给可用的应用服务器。

本例中,<ServerGroup Name="websphere/Default Server"> 中只定义了一个服务器,<Server CloneID="to0oee2t" Name="Default Server">,所以请求将被发送给该服务器。

确认了应用服务器后,插件必须确定使用什么传送(Transport)。每个服务器都可以定义一个或多个传送,但是如果同种类型的传送定义了多个,例如定义了多个HTTP传送,那么配置文件中的第一个传送将会被使用。下面的表格列示了插件如何把HTTP和HTTPS请求映射到应用服务器的可用传送:

接收到的
协议请求 应用服务器
只有HTTP传送 应用服务器
只有HTTPS传送 应用服务器既有HTTP传送
又有HTTPS传送 HTTP HTTP HTTPS HTTP HTTPS HTTP HTTPS HTTPS

一旦确认了传送,插件便可由传送的定义获得主机,端口和传送协议来发送请求。
本例中,<Server CloneID="to0oee2t" Name="Default Server">中只定义了一个传送,<Transport Hostname="websphere" Port="9080" Protocol="http"/>,所以插件将使用该传送,将请求以HTTP协议发送到主机“websphere”的9080端口。