resin配置.docx
- 文档编号:23629393
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:22
- 大小:56.16KB
resin配置.docx
《resin配置.docx》由会员分享,可在线阅读,更多相关《resin配置.docx(22页珍藏版)》请在冰豆网上搜索。
resin配置
ResinSessionAnalysis
WrittenbyWooce
1.Resin的Reliability和Loadbalance机制
Resin在WebServer中的内嵌模块处理请求的顺序:
1)WebServer接收到请求
2)内嵌模块(mod_caucho,mod_isapi等)检查是否由Resin处理的请求
3)内嵌模块选中一个后台JVM,也就是一个
a.如果是已有的session,则选中拥有该session的那一个JVM
b.如果是新的请求,则采用轮循策略交由下一个
4)内嵌模块通过TCPSocket把请求发给选中的后台JVM
5)内嵌模块再通过同一TCPSocket连接接收后台JVM的响应结果.
所有的有关内嵌模块和后台JVM均在resin.conf这一配置文件中配置,使维护变得容易.
因为内嵌模块需要决定选用哪一个JVM,所以负载平衡由内嵌模块控制.从JVM的角度
看,来自内嵌模块的请求和HTTP请求是同样的,除了编码稍有不同.例如,Resin1.2或以上,同一个JVM可以在同一个端口8080同时作为srun和httpd服务器服务.
轮循策略虽然简单,但它实际上和其他复杂的负载平衡测率一样有效,并且正由于简单,它更加健壮和快速.
1.1单机
最廉价的备份策略.它在单台机器上运行一个WebServer和两个JVM.其中一个是主服务JVM,另一个是后备JVM,如果主JVM失效,将启用后备JVM维持ServletEngine仍然可用.在resin.conf中的相应配置例子:
<>
...
>
启动时应该分别单独地启动这两个sun进程.例如unix下:
unix> httpd.sh -pid srun1.pid -server a start
unix> httpd.sh -pid srun2.pid -server b start
在NT下:
c:
\resin1.2> bin/httpd -install-as ResinA -server a
c:
\resin1.2> bin/httpd -install-as ResinB -server b
1.2单WebServer,多JVM
当有多台计算机的时候,可以把负载分担到一台WebServer和多个JVM上,这比用路由器实现负载平衡较为廉价.并且采用Resin自己的负载平衡机制,可以保证使同一个session停留在同一台计算机上.
配置举例:
<>
...
>
c:
\resin1.2> bin/httpd -install-as ResinB -server b
各台计算机可以共享使用同一个resin.conf,但也可以为WebServer和每个JVM分别使用不同的resin.conf.
为了确保session停留在固定的机器上,Resin对cookie的编码中加上了主机号标识.
1.3多WebServer和JVM
对于大型的服务网站,一般使用多台计算机,并且每台计算机都分别运行一个Web
Server和一个JVM,由Router负责把负载分担到不同的机器上.
对于这种方法,由于Router随机地把负载分配到某台机器上,所以发给某台host的请求的Session不一定是这台Host拥有的.因此需要把任何持久的session维护在一台中央服务器如JDBC数据库上或者采用其他方法使能够由session的id找到拥有该session的机器.
即使对于这种Router负载平衡方法,仍然可以用Resin自己的loadbalance策略提高可靠性.对于每一台host上的webserver,都应该首先使用同一台host上运行的JVM进行处理,但同时可以另一台Host上运行的JVM作为后备.
在某一台host上的resin.conf配置举例:
<>
...
>
上面例子中host1,host2,host3上的JVM只有当localhost上的JVM失败时才会被启用.
另一个例子:
1.4多WebServer,单JVM
多个WebServer可以同时使用同一个JVM处理请求.例如,我们有一个高速的一般的
WebServer和一个采用SSL加密的WebServer的时候,这两个WebServer可以由同一个JVM处理请求(虽然如果有一个后备JVM的话会更好),这简化了引入SSL的开发.
2.Resin内部实现distributedsessions的机制
2.1session的backingstore的概念和内存中的session的同步更新
在Resin设置成loadbalanceovermultiplemachine的情况,各台运行webserver和JVM的机器组成一个loadbalancingpool.为实现loadbalanceovermultiplemachine下的distributedsession,必须考虑一个session在被生成后,在loadbalancingpool中其他不拥有该session的机器如何访问它,以及如何同步它们.在Resin中是通过把session存储到backingstore中来解决的,一个JVM创建了一个新的session后,就把它存储到backingstore去,然后只要保证以下条件:
(1)每个内存中有此session的JVM如果更新了此session,就把更新后的session写到backingstore中去,并且backingstore里做到在写某一session的时候不会同时接受读取同一session的请求.
(2)每个JVM在读取session的时候,如果它的内存cache中还没有该session,一定到backingstore去读取.
(3)某个JVM:
ServerA在读取session的时候,如果它的内存cache中已有该session,这时只要满足以下的其中一种情况即可:
a.在
(1)中写session到backingstore里时保证同时更新了ServerA的内存cache中的session
b.到backingstore中再load出session并以此更新内存cache中的session
显然,满足了以上3个条件,不同的机器存取同一session的时候就有很好的同步
性,并且亦有较好的性能.
在Resin中,backingstore可采用3种实现方式:
(参看src/com/caucho/server/http/下的
SessionStore.java,SessionFileStore.java,SessionJdbcStore.java和SessionRingStore.java)
(1)SessionFileStore(这一方式在我所看的Resin2.0.2的代码里实际上还未实现)
session的backingstore在生成它的Host的文件系统(Resin似乎考虑在将来实现一个在不同的运行JVM的机器之间共享文件的网络文件系统VFS)上.
(2)SessionJdbcStore
在一台中央服务器上的database作为backingstore,每台Host上生成的session都通过
JDBC存储到中央服务器的database中去.
(3)SessionRingStore
在这种方式中,loadbalancingpool中所有的运行JVM的机器按hostid从小到大(hostid
的首字母从’a’到’z’的顺序)组成一个JVM的index号的环,当环中的某一台Host生成了一个session(session里记录了生成它的JVM的index号)的时候,就以生成该session的JVM的index号开始,在环上顺序查找,只要某一个index的JVM是可用的,就把session存储到运行该JVM的机器的本地文件系统中,这样在两台机器上都分别存储了这个session的副本的时候就停止.明显可看出,一般情况下(所有JVM都没有crashdown)每个session都有两个副本分别存储在生成它的那台机器和环中的下一台机器的文件系统中.
Resin采用上述3种方式中的哪种方式来实现distributedsession决定于:
IFresin.conf中session-config/file-store和其下的directory的tag不为空THEN采用SessionFileStore;
ELSEIFresin.conf中session-config/tcp-store为trueTHEN采用SessionRingStore;
ELSEIFresin.conf中session-config/jdbc-store不为空THEN采用SessionJdbcStore;
在Resin的实现中,
(1)SessionRingStore方式一定能满足上面所说的3个条件,同步性最好.而对于
(2)SessionFileStore和SessionJdbcStore两种方式
a.当resin.conf中session-config/always-load-session为false的时候,如果一个JVM读入了session在内存cache中,以后除非timeout再从backingstore中reload的情况,以后有请求都一定从内存cache中读该session,不能看到其他JVM在此期间对该session的更新,这时同步性最差,但由于不需从backingstore中读取,响应速度最快;
b.当resin.conf中session-config/always-load-session为true的时候,这时任何请求都会到backingstore中读取,同步性好,但由于session的内存cache实际上不起作用,对请求的响应速度最慢.
2.2相关类分析
2.2.1QSession类
实现HttpSession接口,在Resin系统中某个JVM内存中的session就是一个QSession对象,JVM内存cache中的QSession对象需要和backingstore中的session保持同步更新.
重要数据成员和函数:
变量名
类型
功用
values
HashMap
存储一个session中包含的所有session变量的变量名和变量值
maxInactiveInterval
long
Session的最长可生存时间
srunIndex
int
生成本对象的JVM在loadbalancingpool的所有JVM中的index号(如果生成本对象的JVM运行在的host的id的首字母在’a’到’z’之间,则就等于该首字母和’a’的ASCII码的差值,否则为-1)
accessTime
long
本session的最近访问时间
needsLoad
boolean
是否需要从Backingstore中reload本session
函数
功用
voidsetNeedsLoad(booleanneedsLoad)
设置needsLoad标志
voidsetAccess(longnow)
对本session对象操作成功时,设置本session的最近访问时间为now.
voidreset(longnow)
操作时发现本session未正确保存在backingstore中,清楚本session的内容.
2.2.2VirtualHost类
在一个JVM上处理的所有Servletapplication的集合.
2.2.3SrunConnection类
维护本JVM到另一个JVM的一个用以交换session的socket连接.
2.2.4ServletServer类
实现Server接口
重要数据成员和函数:
变量名
类型
功用
sessionBackingCache
LRUCache(1024)
在内存中cache本JVM所拥有的所有session的SessionBacking对象
srunIndex
Int
本JVM在包含各JVM的loadbalancingpool中的index号(Resin的某个版本,在ResinServer.java中根据resin.conf中"srun-index"的设定值设置)
srunRing
SrunConnection[]
维持到loadbalancingpool中其他的JVM的预分配的SrunConnection连接的数组
hosts
HashTable(table中的每项以hostname为key,以VirtualHost为value)
各个JVM的(hostname,VirtualHost)列表,在initHosts()函数中调用addHost()初始化
uniqueHosts
HashTable(table中的每项以
HostuniqueHost为key,以VirtualHost为value)
各个JVM的(HostuniqueHost,VirtualHost)列表
函数
功用
getSessionBacking(Stringid,SessionManagermanager)
以id为key查找sessionid等于id的session相应的SessionBacking,如果找到即返回它(首先在sessionBackingCache中找,如果找不到再到其他地方找).
intgetSrunCount()
返回loadbalancingpool中的所有JVM的数目
SrunConnectiongetSrunPath(intindex)
根据index返回本JVM和loadbalancepool中该index对应的JVM之间的连接
ReadWritePairgetRecycleConnection(intindex)
分配一个空闲的用于跟index号对应的JVM交换数据的ReadStream/WriteStreamTCP-streampair,
ReadWritePairgetSessionConnection(intindex)
新建立一个用于跟index号对应的JVM交换数据的ReadStream/WriteStreamTCP-streampair
其他:
hostList:
ArrayList类型(VirtualHost对象)
addHost(Stringid,RegistryNodenode,StringappDir)函数:
根据(id,node,appDir)新建一个VirtualHost对象并存入HashTable类型成员hosts中.
init()函数:
初始化invocationCache(LRUCache类型)等内存中的Cache;调用initHosts()函数初始化hosts等;
2.2.5SessionStore类
负责session的访问(读取/存储)操作的基类,SessionFileStore,SessionJdbcStore,
SessionRingStore等都是它的子类.
重要数据成员和函数:
函数
功用
booleanload(QSessionsession);
负责从backingstore中读取QSession对象,隐藏backingstore究竟在什么地方的细节,在SessionFileStore,SessionJdbcStore,SessionRingStore类中分别被重载和具体定义实现细节
Voidstore(QSessionsession);
负责存储QSession对象到backingstore中,隐藏backingstore究竟在什么地方的细节,在SessionFileStore,SessionJdbcStore,SessionRingStore类中分别被重载和具体定义实现细节
booleanload(QSessionsession,InputStreamis,intoldUpdateCount);
从InputStream读出QSession对象(通过Serializable序列化字节流的方式读取)
booleanstore(QSessionsession,OutputStreamos)
把QSession对象写到OutputStream(通过Serializable序列化字节流的方式写入)
2.2.5SessionBacking类
封装session存储在filesystem上的backingpath上时的访问操作的接口.
重要数据成员和函数:
变量名
类型
功用
sessionPath
Path
filesystem上的backingpath,session存储于其中
函数
功用
booleanload(QSessionsession);
在backingpath上打开ReadStream,然后去调用SessionStore类的booleanload(QSessionsession,InputStreamis,intoldUpdateCount);函数完成从backingpath里读出QSession对象的操作
voidsave(QSessionsession)
在backingpath上打开WriteStream,然后去调用SessionStore类的booleanstore(QSessionsession,OutputStreamos)函数完成存储QSession对象到backingpath中的操作
2.2.6SessionManager类
管理一个servletapplication的所有session
重要数据成员和函数:
变量名
类型
功用
reloadEachRequest
boolean
当有request到达的时候,是否一定要到backingstore中取出session,以它来更新内存中的session
sessions
LRUCache
存放所有activesession(以sessionid为key),容量由resin.conf里的session-config/session-max定义
sessionTimeout
long
由resin.conf的session-config/session-timeout定义
sessionList
ArrayList
sessiontimeout的时候被放入其中
函数
功用
QSessioncreateSession(StringoldId,longdate,intsessionGroup,HttpServletRequestrequest);
新生成一个QSession对象:
1)如果oldId为空或者长度小于4,则调用createSessionId()生成新的session的id,否则仍使用oldId作为新的session的id
2)以新的session的id为参数调用createSession(id,date)生成QSession对象
3)以id为key,把QSession对象放入sessions中.
4)如果新的session的id采用oldId,说明backingstore中已经有该session,只是在本JVM的内存cache中没有该QSession对象了,所以调用load(session,date)从backingstore中读取QSession对象所含的各session变量的变量名和值.
QSessiongetSession(Stringkey,longnow)
读取sessionid等于参数key的QSession对象,如果没有则会创建一个QSession对象
1)在sessions中查找该QSession对象
2)如果没有找到并且now>0,则调用createSession()生成新的QSession对象并插入到sessions中
3)在需要load的情况(get出来的QSession对象的needsLoad()为true,或者是2)步中新生成的等),
调用load(session,now)函数从backingstore中读取QSession对象所含的各session变量的名和值.
voidload(QSessionsession,longnow)
尝试从backingstore中load出QSession对象,如果成功则更新其最近访问时间,如果失败则清除QSession对象的内容,可在刚执行createSession()函数后调用以检查新生成的session是否已存储成功.
2.2.6SessionRingStore类
当以Ring方式的backingstore存储distributedsessions时SessionStore类的实现.
SessionRingStore.java的voidstore(QSessionsession)函数:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- resin 配置