📄 tcp-sessions.xtp
字号:
<s1 title="TCP-Ring Distributed Sessions"><summarylist/><p>Resin's TCP-ring protocol for distributed sessions can improve reliability and scalability over JDBC-based distributed sessions.Because sessions are always duplicated on separate servers, TCP-ringsessions do not have a single point of failure. JDBC-based sessionsare vulnerable to the session database going down. As the number ofservers increases, JDBC-based sessions can start overloading thebacking database. With TCP-ring sessions, each additional servershares the backup load, so the main scalability issue reduces to networkbandwidth. In combination with sticky-session load balancing,TCP-ring sessions can approach zero overhead when the majority ofrequests read session state without modification.</p><s2 title="Configuration"><p>TCP-Ring configuration must tell each host the servers in the TCP-ringand it must enable the <var/tcp-store/> in the session configuration.Because session configuration is specific to a virtual host and aweb-application, each web-app needs <var/tcp-store/> enabledindividually. It's not possible to enable <var/tcp-store/> for anentire site.</p><p>Most sites using Resin's load balancing will already have the<var/<srun>/> configured. Each <var/<srun>/> block corresponds to ahost, including the current host. Since TCP-ring sessions usesResin's srun protocol, each host must listen for srun requests.</p><example title='resin.conf fragment'>...<http-server> <srun id='a' host='192.168.0.1' srun-index='1'/> <srun id='b' host='192.168.0.2' srun-index='2'/> <srun id='c' host='192.168.0.3' srun-index='3'/> <srun id='d' host='192.168.0.4' srun-index='4'/> ... <web-app id='myapp'> ... <session-config> <tcp-store/> </session-config> </web-app></http-server>...</example><p>Usually, hosts will share the same resin.conf. Each host will bestarted with a different <var/-server xx/> to select the correctblock. On Unix, startup will look like:</p><example title="Starting Host C on Unix">resin-2.0.x> bin/httpd.sh -conf conf/resin.conf -server c start</example><p>On Windows, Resin will generally be configured as a service:</p><example title="Starting Host C on Windows">resin-2.0.x> bin/httpd -conf conf/resin.conf -server c -install-as ResinC</example><s3 title="always-save-session"><p>Resin's distributed sessions needs to know when a session haschanged in order to save the new session value. Although Resin candetect when an application calls <var/HttpSession.setAttribute/>, itcan't tell if an internal session value has changed. The followingCounter class shows the issue:</p><example title="Counter.java">package test;public class Counter implements java.io.Serializable { private int count; public int nextCount() { return count++; }}</example><p>Assuming a copy of the Counter is saved as a session attribute,Resin doesn't know if the application has called <var/nextCount/>. If itcan't detect a change, Resin will not backup the new session, unless<var/always-save-session/> is set. When <var/always-save-session/> istrue, Resin will back up the session on every request.</p><example>...<web-app id='/foo'>...<session-config> <tcp-store/> <always-save-session/></session-config>...</web-app></example><p>In contrast to JDBC-based sessions, Resin will ignore the<var/always-load-session/> flag for TCP-based sessions. Because ofthe more sophisticate TCP-ring protocol, <var/always-load-session/> isnot needed.</p></s3><s3 title="Serialization"><p>Resin's distributed sessions relies on Java serialization to save andrestore sessions. Application object must <var/implementjava.io.Serializable/> for distributed sessions to work.</p></s3></s2><s2 title="Protocol Examples"><s3 title="Session Request"><p>To see how TCP-ring sessions work, consider a case wherethe load balancer sends the request to a random host. Host C owns thesession but the load balancer gives the request to Host A. In thefollowing figure, the request modifies the session so it must be savedas well as loaded.</p><figure src='srunc.gif'/><p>The session id encodes the owning host. The example sessionid, <var/ca8MbyA/>, decodes to an srun-index of 3, mappingto Host C. Host A must know the owning hostfor every cookie so it can communicate with the owning srun.The example configuration defines all the sruns Host A needs toknow about. If Host C is unavailable, Host A can use itsconfiguration knowledge to use Host D as a backupfor <var/ca8MbyA/> instead..</p><p>When the request first accesses the session, Host A asksHost C for the serialized session data (<var/2:load/>).Since Host A doesn't cache the session data, it mustask Host C for an update on each request. For requests thatonly read the session, this TCP load is the only extra overhead,i.e. they can skip <var/3-5/>. The <var/always-save-session/>flag, in contrast, will always force a write.</p><p>At the end of the request, Host A writes any sessionupdates to Host C (<var/3:store/>). If always-save-sessionis false and the session doesn't change, this step can be skipped.Host A sendsthe new serialized session contents to Host C. Host C savesthe session on its local disk (<var/4:save/>) and saves a backupto Host D (<var/5:backup/>).</p></s3><s3 title="Sticky Session Request"><p>Smart load balancers that implement sticky sessions can improveTCP-ring performance. In the previous request, Resin's TCP-ringsessions maintain consistency for dumb load balancers or twistedclients like the AOL browsers. The cost is the additional networktraffic for <var/2:load/> and <var/3:store/>. Smart load-balancerscan avoid the network traffic of <var/2/> and <var/3/>.</p><figure src='same_srun.gif'/><p>Host C decodes the session id, <var/caaMbyA/>. Since it ownsthe session, Host C gives the session to the servlet with no workand no network traffic. For a read-only request, there's zerooverhead for TCP-ring sessions. So even a semi-intelligent loadbalancer will gain a performance advantage. Normal browsers will havezero overhead, and bogus AOL browsers will have the non-stickysession overhead.</p><p>A session write saves the new serialized session to disk(<var/2:save/>) and to Host D (<var/3:backup/>).<var/always-save-session/> will determine if Resin can take advantageof read-only sessions or must save the session on each request.</p></s3><s3 title="Failover"><p>Since the session always has a current copy on two servers, the loadbalancer can direct requests to the next server in the ring. Thebackup server is always ready to take control. The failover willsucceed even for dumb load balancers, as in the non-sticky-sessioncase, because the srun hosts will use the backup as the new owningserver.</p><p>In the example, either Host C or Host D can stop andthe sessions will use the backup. Of course, the failover will workfor scheduled downtime as well as server crashes. A site couldupgrade one server at a time with no observable downtime.</p></s3><s3 title="Recovery"><p>When Host C restarts, possibly with an upgraded version of Resin,it needs to use the most up-to-date version of the session; itsfile-saved session will probably be obsolete. When a "new" sessionarrives, Host C loads the saved session from both the file andfrom Host D. It will use the newest session as the currentvalue. Once it's loaded the "new" session, it will remain consistentas if the server had never stopped.</p></s3><s3 title="No Distributed Locking"><p>Resin's TCP-ring sessions does not lock sessions. For browser-basedsessions, only one request will execute at a time. Since browsersessions have no concurrently, there's no need for distributedlocking. However, it's a good idea to be aware of the lack ofdistributed locking.</p></s3></s2><s2 title="Conclusion"><p>Although reliability generally will end up costing some performance,the trick for a good implementation is to increase reliability with aminimal cost. In some environments, using JDBC distributed sessionsor simple file-based persistent sessions will improve a site'srobustness with low-enough cost. Because of its scalability, it'smore likely that Resin's TCP-ring distributed sessions will be abetter choice for most deployment configurations.</p></s2></s1>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -