bboss session共享使用方法介绍

bboss session共享使用方法介绍。

本文介绍如何配置bboss session的及主要参数含义说明,具体的集成到应用系统的方法可以参考文档:[url=https://my.oschina.net/bboss/blog/758871]bboss session集成权威指南[/url]

[size=xx-large][b]1.会话共享github地址[/b][/size]
[url]https://github.com/bbossgroups/security[/url]
下载下来包含3个子模块的gradle工程:
bboss-secutiry 会话共享核心工程(包含令牌功能)
bboss-security-web 会话共享监控工程(包含令牌功能和令牌hessian和webservice、http服务)
bboss-ticket sso工程

会话共享demo 地址
[url]https://github.com/bbossgroups/sessiondemo[/url]
session 基本会话共享demo(不包含监控功能)
sessionmonitor 包含监控功能的会话共享demo

将这些工程通过eclipse gradle sts插件导入eclipse即可,导入方法参考:
[url=http://yin-bp.iteye.com/blog/2313145]bboss gradle工程导入eclipse介绍[/url]

session共享组件与令牌组件都隶属于bboss security工程。
session共享服务器采用mongodb来存储会话信息和会话数据。
[size=xx-large][b]2.会话共享组件架构特点[/b][/size]
bboss会话共享组件架构特点如下:
[url]http://yin-bp.iteye.com/blog/2079685[/url]

[size=xx-large][b]3.会话共享组件作用[/b][/size]
为应用提供统一会话管理功能,避免集群部署场景下负载切换session丢失问题;
跨域跨应用共享会话并实现SSO功能;
解决了会话共享五大技术难题:
session数据序列化问题,
session sticking问题,
跨域跨应用session共享问题,
跨容器(tomcat,jetty,weblogic)共享session问题,
sso单点登入单点登出一致性问题。

[b][size=xx-large]4.会话共享组件过滤器配置[/size][/b]
bboss开发的平台中,为了避免重复配置,会话共享组件过滤器共用bboss字符过滤器com.frameworkset.common.filter.SessionCharsetEncodingFilter,SessionCharsetEncodingFilter是bboss session过滤器组件的子类:
org.frameworkset.security.session.impl.SessionFilter
应用系统也可以直接使用org.frameworkset.security.session.impl.SessionFilter作为session共享拦截器使用。
<filter>
<filter-name>CharsetEncoding</filter-name>
<filter-class>com.frameworkset.common.filter.SessionCharsetEncodingFilter</filter-class>
<init-param>
<param-name>RequestEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>ResponseEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>mode</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>checkiemodeldialog</param-name>
<param-value>true</param-value>

</init-param>
<init-param>
<param-name>refererDefender</param-name>
<param-value>true</param-value>

</init-param>

<init-param>
<param-name>wallfilterrules</param-name>
<param-value><![CDATA[><,%3E%3C,<iframe,%3Ciframe,<script,%3Cscript,<img,%3Cimg,alert(,alert%28,eval(,eval%28,style=,style%3D,[window['location'],{valueOf:alert},{toString:alert},[window["location"],new Function(]]>
</param-value>

</init-param>

<init-param>
<param-name>wallwhilelist</param-name>
<param-value><![CDATA[content,fileContent,extfieldvalues,questionString]]>
</param-value>

</init-param>

</filter>


<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>*.frame</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>*.page</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>*.freepage</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>/cxfservices/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>CharsetEncoding</filter-name>
<url-pattern>/jasperreport/*</url-pattern>
</filter-mapping>


只有符合filter-mapping对应规则的url请求,session才会具有会话共享功能。
[size=xx-large][b]5.会话共享组件配置[/b][/size]
[size=x-large][b]集群应用会话共享模式[/b][/size]
配置文件路径:/resources/sessionconf.xml,sessionconf.xml文件只要编译到classes的跟目录下即可
<properties>
<!--
会话共享配置:但应用集群会话共享配置实例
-->
<property name="sessionManager" class="org.frameworkset.security.session.impl.SessionManager"
init-method="init" destroy-method="destroy">
<property name="sessionTimeout" value="3600000"/>
<property name="sessionstore" refid="attr:sessionstore"/>
<!-- <property name="sessionstore" value="session"/>-->
<property name="cookiename" value="b_sessionid"/>

<!--
enableSessionIDFromParameter:支持以参数方式 传递sessionid控制开关
true 启用,使用cookiename属性对应的值作为传递sessionid的参数名称
false 关闭 默认值
优先从cookie中获取sessionid,如果从cookie中没有获取sessionid到才需要从参数中获取sessionid
从参数传递的sessionid,必须采用以下方式对sessionid进行加密,才能传递:
String sid = SessionUtil.getSessionManager().getSignSessionIDGenerator().sign(session.getId(), true);
String url = "http://otherappurl?"+SessionUtil.getSessionManager().getCookiename()+"="+sid
-->
<property name="enableSessionIDFromParameter" value="false"/>
<!--
将从请求参数中获取sessionid写回cookie控制开关,当enableSessionIDFromParameter为true时起作用<br>
true 启用,使用cookiename属性将对应的值作为sessionid写回cookie<br>
false 关闭 默认值<br>
bboss采用增强的sessionid签名校验机制,避免客户端篡改sessionid,为了避免bboss内置的sessionid的签名算法被暴露,请修改默认的signKey
-->
<property name="rewriteSessionCookie" value="false"/>
<!--
是否对sessionid进行加密存入cookie
true 加密
false 不加密,默认值
-->
<property name="signSessionID" value="false"/>

<!--
sessionid 签名key,signSessionID为true时起作用
-->
<property name="signKey" value="bboss_session"/>
<property name="httpOnly" value="true"/>
<property name="secure" value="false"/>
<property name="lazystore" value="true"/>
<property name="storeReadAttributes" value="false"/>
<property name="serialType" value="bboss"/>
<property name="sessionIDGenerator" class="org.frameworkset.security.session.impl.UUIDSessionIDGenerator"/>
<property name="monitorAttributes" ><![CDATA[
[
{"name":"userAccount","cname":"账号","type":"String","like":true,"enableEmptyValue":false},
{"name":"worknumber","cname":"工号","type":"String","like":false,"enableEmptyValue":true}
]
]]></property>
<!-- <property name="sessionlisteners" value="org.frameworkset.security.session.impl.NullSessionListener"/> -->
<!-- 指定失效session销毁线程扫描频率 ,单位:毫秒-->
<property name="sessionscaninterval" value="3600000"/>
<!-- 失效session销毁线程开启开关:true 开启, false 关闭 -->
<property name="startLifeScan" value="false"/>
</property>

<property name="sessionStaticManager" class="org.frameworkset.security.session.statics.MongoSessionStaticManagerImpl"/>

<property name="sessionstore" class="org.frameworkset.security.session.impl.MongDBSessionStore"/>
</properties>

sessionManager配置说明: org.frameworkset.security.session.impl.SessionManager是bboss提供的session会话管理组件。
 [b]sessionTimeout[/b]-属性指定会话超时时间,单位:毫秒,-1或0标识session永不超时。
 [b]sessionstore[/b]-指定session的存储机制,session表示会话使用容器默认的会话管理机制,配置为MongDBSessionStore时则启用bboss的会话管理机制 
[b]cookiename[/b]-指定会话cookie名称,为了避免同根域应用之间session id冲突,必须为这些同根域的应用指定不同cookiename;但是如果需要做跨域跨应用会话共享的情况下,这些子域名不同的应用(或者域名相同上下文不同的应用)的必须指定相同cookiename,否则无法实现跨域跨应用会话共享。
[b]enableSessionIDFromParameter[/b]-从请求参数中获取sessionid控制开关
true 启用,使用cookiename属性对应的值作为传递sessionid的参数名称
false 关闭 默认值
优先从cookie中获取sessionid,如果从cookie中没有获取sessionid到才需要从参数中获取sessionid
[b]httpOnly[/b]-指定会话cookie是否使用httponly模式,true和false两个值,默认为true
[b]secure[/b] –结合https阻止传输过程中sessionid被窃取 
[b]monitorAttributes[/b] 配置监控查询模块中可以作为查询条件的session属性清单,采用json数组进行配置,具体配置和使用方法参考文档:
[url]http://yin-bp.iteye.com/blog/2265855[/url]
[b]appcode[/b]-应用编码,如果没有指定appcode值默认为应用上下文
appcode的作用:当所有的应用上下文为“/”时,
用来区分后台统计的会话信息, 如果应用上下文为“/”时,appcode为ROOT
[b]sessionlisteners[/b]-指定session监听器,多个listener可以按照顺序以逗号分隔填入即可,listener只有在bboss管理会话的时候才有用,每一个listener必须实现接口:
package org.frameworkset.security.session;

public interface SessionListener {
public void createSession(SessionEvent event);
public void destroySession(SessionEvent event);
public void addAttribute(SessionEvent event);
public void removeAttribute(SessionEvent event);

}

[b]startLifeScan[/b]-是否在当前应用中启用失效会话扫描机制,true启用,false不启用,默认为false,一般所有连接到同一mongodb的应用在本地都会关闭失效会话扫描机制,而统一由独立的失效会话扫描服务应用(开启扫描机制)来负责失效会话扫描和销毁失效会话,这样可以提升应用性能。
[b]sessionscaninterval[/b]-指定失效session销毁线程扫描频率 ,单位:毫秒,默认1小时。

[b]lazystore[/b]:延迟存储修改的session数据到mongodb的控制开关,true表示当请求结束前一次性将request过程中所有通过session.setAttribute(key,value)方法对session数据的修改存储到会话共享平台中,提升性能,否则每次都实时将修改存储到mongodb中,默认为false
[b]sessionIDGenerator[/b]:指定session id生成机制,默认为UUID,应用可以参考文档[url=http://yin-bp.iteye.com/blog/2303040]《bboss session自定义session id生成机制介绍 》[/url]自定义session id生成机制
[b]serialType[/b]:指定session数据序列化机制,三种机制:bboss,json,jvm;默认采用bboss序列化机制;jvm机制需要对象实现java.io.Serializable接口;json机制,json适用于没有复杂对象引用关系的应用系统session数据的序列化,因此json序列化机制适用范围有限。
[b]storeReadAttributes[/b]:布尔值,当lazystore为true时起作用,storeReadAttributes为true时,提交session数据到后台存储(mongodb或者redis)时,同时将之前获取到的session属性也一并更新到后台,否则不更新。这个属性在整合bboss session框架到遗留系统中比较有用,单体应用系统中,修改session中存储的对象属性时,由于引用关系的原因,无需将最新的对象重新set到session中,但是集群应用系统中,如果不重新set到session中(持久化到redis或者mongodb中),最新的对象状态不会被其他应用看到,所以为了让其他节点看到最新的修改,必须将修改的对象重新放置到session中,势必需要修改遗留系统的程序才能实现,但是通过将lazystore设置为true并且将storeReadAttributes也设置为true,就可以自动将读取到数据也强制在提交时设置到session中,这样就无需调整遗留系统的程序了。

sessionstore用来指定session的存储组件实现类,目前只提供了mongodb和redis两种存储机制:
org.frameworkset.security.session.impl.MongDBSessionStore
rg.frameworkset.security.session.impl.RedisSessionStore
通过插件扩展机制,可以采用redis来存储会话对象。redis的配置可以参考文档:[url=http://yin-bp.iteye.com/blog/2287102]bboss session redis插件使用指南[/url]

sessionStaticManager组件是bboss会话共享组件的监控统计组件:
<property name="sessionStaticManager"
f:monitorScope="all" class="org.frameworkset.security.session.statics.MongoSessionStaticManagerImpl"/>

sessionStaticManager组件的monitorScope属性用来指定监控的应用范围,
self:表示只能监控管理本应用的会话数据(默认值)
all:表示监控管理所有应用的会话数据
出于安全性考虑,接入同一个mongodb的应用系统只能管理和监控本应用的会话数据,monitorScope为self,统一监控中心管理和监控所有应用系统的会话数据,这时monitorScope被指定为all。
管理功能包括会话应用库的删除,批量删除应用会话,清空应用下所有会话,按特定条件查询会话,查看会话详细信息(会话基本信息,会话中存放的属性数据(序列化后的xml串))。会话应用库的删除只能在监控中心进行,而且不能删除监控中心对应的会话应用,这个功能要慎用。
删除会话信息时不会删除管理用户对应的会话对象。
管理界面:

[img]http://dl2.iteye.com/upload/attachment/0103/7540/62aa00bd-9c8b-3e87-8908-721498ce3753.gif[/img]

[img]http://dl2.iteye.com/upload/attachment/0103/7542/284b510f-9c60-3547-add2-c8125484b1e3.gif[/img]

[img]http://dl2.iteye.com/upload/attachment/0103/7544/dd8d0ed7-2e0d-3312-b044-80aefc9cfe19.gif[/img]

[size=x-large][b]会话共享组件集成到跨域应用配置:[/b][/size]
<properties>
<!--
会话共享配置:跨越配置实例
-->
<property name="sessionManager" class="org.frameworkset.security.session.impl.SessionManager"
init-method="init" destroy-method="destroy">
<property name="sessionTimeout" value="3600000"/>
<property name="sessionstore" refid="attr:sessionstore"/>
<!-- <property name="sessionstore" value="session"/>-->
<property name="cookiename" value="b_sessionid"/>
<property name="httpOnly" value="true"/>
<property name="secure" value="false"/>
<property name="monitorAttributes" ><![CDATA[
[
{"name":"userAccount","cname":"账号","type":"String","like":true,"enableEmptyValue":false},
{"name":"worknumber","cname":"工号","type":"String","like":false,"enableEmptyValue":true}
]
]]></property>
<!--
应用编码,如果没有指定appcode值默认为应用上下文
appcode的作用:当所有的应用上下文为“/”时,用来区分后台统计的会话信息
如果应用上下文为“/”时,appcode为ROOT

当启用跨域会话共享时,就必须指定appcode
-->

<property name="appcode" value="pdp"/>
<!--
domain:指定跨域共享的根域,基于该域名的子域名都可以共享session
shareSessionAttrs:配置需要在应用间共享的会话数据属性名称,以逗号分隔;如果没有配置shareSessionAttrs属性,则所有的属性都是共享数据
domainApps:指定需要session共享的应用列表,每个应用必须指定path属性(对应应用上下文路径),如果应用指定了attributeNamespace属性,则用attributeNamespace对应的值来限定应用私有的会话数据名称
每个app的attributeNamespace属性只有在CrossDomain上指定了shareSessionAttrs属性才有意义
path:共享session的应用上下文名称
attributeNamespace:共享session应用私有session属性名称命名空间,用来限定应用私有session数据的存储空间 ,如果指定了shareSessionAttrs则必须指定每个应用的attributeNamespace

通过下面的配置,可以实现以下三个应用之间的会话共享和单点登录功能,应用的访问地址分别为:
http://pdp.bboss.com.cn:8080/PDP
http://g4.bboss.com.cn:169/g4studio
http://test.bboss.com.cn:8080/WebRoot

上面三个应用的用户会话信息存储在session的CREDENTIAL_INDEXS,PRINCIPAL_INDEXS两个共享属性中,所以可以实现三个应用的单点登录功能
如果需要共享跟多的会话数据,可以将对应的属性追加到shareSessionAttrs中(以逗号分割),没有出现在shareSessionAttrs中的属性都是私有会话数据(对其他应用不可见)。
如果没有指定shareSessionAttrs,则会话数据全部在三个应用间共享。
-->
<property name="crossDomain" class="org.frameworkset.security.session.domain.CrossDomain"
f:domain="bboss.com.cn"
f:shareSessionAttrs="CREDENTIAL_INDEXS,PRINCIPAL_INDEXS"
init-method="init">
<property name="domainApps">
<list componentType="bean">
<property class="org.frameworkset.security.session.domain.App"
f:path="/PDP"
f:currentApp="true"
f:attributeNamespace="pdp_bboss_com_cn"
init-method="init"
/>
<property class="org.frameworkset.security.session.domain.App"
f:path="/g4studio"
f:currentApp="false"
f:attributeNamespace="g4_bboss_com_cn"
init-method="init"
/>

<property class="org.frameworkset.security.session.domain.App"
f:path="/WebRoot"
f:currentApp="false"
f:attributeNamespace="testpdp_bboss_com_cn"
init-method="init"
/>
</list>
</property>
</property>
<!-- <property name="sessionlisteners" value="org.frameworkset.security.session.impl.NullSessionListener"/> -->
</property>

<property name="sessionStaticManager" class="org.frameworkset.security.session.statics.MongoSessionStaticManagerImpl"/>

<property name="sessionstore" class="org.frameworkset.security.session.impl.MongDBSessionStore"/>
</properties>

跨域应用session共享配置相比集群会话共享只需添加appcode 和crossDomain 两个属性即可:
[b][color=blue]<property name="appcode" value="pdp"/>
<property name="crossDomain" class="org.frameworkset.security.session.domain.CrossDomain"
f:domain="bboss.com.cn"
f:shareSessionAttrs="CREDENTIAL_INDEXS,PRINCIPAL_INDEXS" init-method="init">
<property name="domainApps">
<list componentType="bean">
<property class="org.frameworkset.security.session.domain.App"
f:path="/PDP" f:currentApp="true" f:attributeNamespace="pdp_bboss_com_cn"
init-method="init" />
<property class="org.frameworkset.security.session.domain.App"
f:path="/g4studio" f:currentApp="false" f:attributeNamespace="g4_bboss_com_cn" init-method="init" />
<property class="org.frameworkset.security.session.domain.App"
f:path="/WebRoot" f:currentApp="false" f:attributeNamespace="testpdp_bboss_com_cn" init-method="init" />
</list>
</property>
</property>[/color][/b]
会话共享组件集成到跨域应用相关属性说明(这里只说明跨域session共享相关属性,其他属性参考集群模式会话共享属性说明部分):
[b]domain:[/b]指定跨域共享的根域,基于该域名的子域名都可以共享session
[b]shareSessionAttrs:[/b]配置需要在应用间共享的会话数据属性名称,以逗号分隔;如果没有配置shareSessionAttrs属性,则所有的属性都是共享数据
[b]domainApps:[/b]指定需要session共享的应用列表,每个应用必须指定path属性(对应应用上下文路径),如果应用指定了attributeNamespace属性,则用attributeNamespace对应的值来限定应用私有的会话数据名称,每个app的attributeNamespace属性只有在CrossDomain上指定了shareSessionAttrs属性才有意义
[b]path:[/b]共享session的应用上下文名称
[b]attributeNamespace:[/b]应用私有session属性名称命名空间,用来限定应用私有session数据的存储空间 ,如果指定了shareSessionAttrs则必须指定每个应用的attributeNamespace
[b]currentApp:[/b] 标识应用是所有应用中的当前应用,true 是,false 否,每个应用中应该把自己对于的应用的currentApp属性设置为true,将其他应用的currentApp设置为false。

样例配置说明:假设有以下三个应用,访问地址分别为
http://pdp.bboss.com.cn:8080/PDP
http://g4.bboss.com.cn:169/g4studio
http://test.bboss.com.cn:8080/WebRoot

通过样例配置,三个应用的用户会话信息存储在session的CREDENTIAL_INDEXS,PRINCIPAL_INDEXS两个共享属性中,可以实现三个应用之间的会话共享和单点登录功能。如果需要共享更多的会话数据,可以将对应的属性追加到shareSessionAttrs中(以逗号分割),没有出现在shareSessionAttrs中的属性都是私有会话数据(对其他应用不可见)。如果没有指定shareSessionAttrs,则会话数据全部在三个应用间共享。

[size=large][b]通过传递加密sessionid实现跨域跨应用session共享[/b][/size]
如果几个应用没有相同的根域名或者都是通过不同的ip进行访问,那么除了做上面的crossDomain配置,还需要通过传递加密的sessionid来实现他们之间的session共享,具体方法描述如下。
[size=large][b]1.首先去掉crossDomain组件的属性 f:domain="xxxx" [/b][/size]

[size=large][b]2.在每个应用的sessionconf.xml中做以下配置,启用参数方式传递sessionid功能[/b][/size]
为sessionManager组件配置以下属性:
<!--   
enableSessionIDFromParameter:支持以参数方式 传递sessionid控制开关
true 启用,使用cookiename属性对应的值作为传递sessionid的参数名称
false 关闭 默认值
优先从cookie中获取sessionid,如果从cookie中没有获取sessionid到才需要从参数中获取sessionid
从参数传递的sessionid,必须采用以下方式对sessionid进行加密,才能传递:
String sid = SessionUtil.getSessionManager().getSignSessionIDGenerator().sign(session.getId(), true);
String url = "http://otherappurl?"+SessionUtil.getSessionManager().getCookiename()+"="+sid
-->
<property name="enableSessionIDFromParameter" value="true"/>
<!--
将从请求参数中获取sessionid写回cookie控制开关,当enableSessionIDFromParameter为true时起作用<br>
true 启用,使用cookiename属性将对应的值作为sessionid写回cookie<br>
false 关闭 默认值<br>
bboss采用增强的sessionid签名校验机制,避免客户端篡改sessionid,为了避免bboss内置的sessionid的签名算法被暴露,请修改默认的signKey
-->
<property name="rewriteSessionCookie" value="true"/>
<!--
是否对sessionid进行加密存入cookie
true 加密
false 不加密,默认值
-->
<property name="signSessionID" value="false"/>

<!--
sessionid 签名key,signSessionID为true时起作用
-->
<property name="signKey" value="bboss_session"/>


[size=large][b]3.构建并传递加密的sessionid[/b][/size]
从参数传递的sessionid,必须采用以下方式对sessionid进行加密,才能传递,示例代码如下:

String sid = SessionUtil.getSessionManager().getSignSessionIDGenerator().sign(session.getId(), true); //加密sessionid
String url = "http://otherappurl?"+SessionUtil.getSessionManager().getCookiename()+"="+sid ; //传递sessionid


[size=xx-large][b]6.mongodb客户端配置[/b][/size]
会话存储mongodb服务器连接配置文件:
[url=https://github.com/bbossgroups/security/blob/master/bboss-security/resources/mongodb.xml]/bboss-security/resources/mongodb.xml[/url]
根据mongodb的部署模式有两种配置方式:集群模式和单机模式
[size=x-large][color=blue][b]集群配置文件[/b][/color][/size]:
<properties>
<!-- 增加mongodb数据源配置和client工厂类 -->
<property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB"
init-method="init" destroy-method="close" factory-method="getMongoClient">


<property name="serverAddresses" >
10.0.15.134:27017
10.0.15.134:27018
10.0.15.38:27017
10.0.15.39:27017
</property>
<property name="option" >
QUERYOPTION_SLAVEOK
</property>

<property name="writeConcern" value="JOURNAL_SAFE"/>

<property name="readPreference" value="NEAREST"/>


</property>
</properties>

mongodb主从集群环境下,如果开启了从节点读数据模式(也就是读写分离模式),这里配置了开启模式:
<property name="option" >
QUERYOPTION_SLAVEOK
</property>
这样需要规避主从节点数据复制延迟导致数据不一致的问题,规避方法如下:
<property name="writeConcern" value="REPLICA_ACKNOWLEDGED(4,2000)"/>
我们将writeConcern设置为REPLICA_ACKNOWLEDGED(4,2000),只是在4个mongodb节点的数据复制完成确认后,写操作才返回,同时指定了等待2秒超时时间。我们这里是4个节点,可以根据实际情况mongodb节点数设置这个数字,总之不能超过mongodb节点数,但是可以少于节点数。
[size=x-large][color=blue][b]完全的读写分离配置[/b][/color][/size]:
<property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB"
init-method="init" destroy-method="close" factory-method="getMongoClient">

<!-- 这里不需要配置destroy-method,因为bboss持久层在jvm退出时会自动调用数据源的close方法 -->
<property name="serverAddresses" >
10.0.15.134:27017
10.0.15.134:27018
10.0.15.38:27017
10.0.15.39:27017
</property>
<property name="option" >
QUERYOPTION_SLAVEOK
</property>

<property name="writeConcern" value="REPLICA_ACKNOWLEDGED(4,2000)"/>
<property name="readPreference" value="SECONDARY_PREFERRED"/>
<property name="autoConnectRetry" value="true"/>
<property name="connectionsPerHost" value="10"/>
<property name="maxWaitTime" value="120000"/>
<property name="socketTimeout" value="0"/>
<property name="connectTimeout" value="15000"/>
<property name="threadsAllowedToBlockForConnectionMultiplier" value="5"/>
<property name="socketKeepAlive" value="true"/>
<!-- 如果需要用户认证则在下面配置mongodb的数据库验证用户和口令以及机制 -->
<!-- mechanism 取值范围:PLAIN GSSAPI MONGODB-CR MONGODB-X509,默认为MONGODB-CR -->
<!--<property name="credentials">
<list componentType="bean">

<property class="org.frameworkset.nosql.mongodb.ClientMongoCredential"
f:mechanism="MONGODB-CR"
f:database="sessiondb"
f:userName="bboss"
f:password="bboss"/>
<property class="org.frameworkset.nosql.mongodb.ClientMongoCredential"
f:mechanism="MONGODB-CR"
f:database="tokendb"
f:userName="bboss"
f:password="bboss"/>

</list>
</property> -->
</property>

[size=x-large][color=blue][b]单mongodb服务器配置[/b][/color][/size]:
<properties>
<!-- 增加mongodb数据源配置和client工厂类 -->
<property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB"
init-method="init" destroy-method="close" factory-method="getMongoClient">


<property name="serverAddresses" >
192.168.1.100:27016
</property>
<property name="option" ></property>


<property name="writeConcern" value="JOURNAL_SAFE"/>

<property name="readPreference" value=""/>


</property>
</properties>

如果mongodb客户端需要认证登陆,则可以在配置文件中增加认证相关的配置:
<properties>
<!-- 增加mongodb数据源配置和client工厂类 -->
<property name="default" factory-class="org.frameworkset.nosql.mongodb.MongoDB"
init-method="init" destroy-method="close" factory-method="getMongoClient">


<property name="serverAddresses" >
192.168.1.100:27016
</property>
<property name="option" ></property>


<property name="writeConcern" value="JOURNAL_SAFE"/>

<property name="readPreference" value=""/>
<!-- 如果需要用户认证则在下面配置mongodb的数据库验证用户和口令以及机制 -->
<!-- mechanism 取值范围:PLAIN GSSAPI MONGODB-CR MONGODB-X509,默认为MONGODB-CR -->
<property name="credentials">
<list componentType="bean">

<property class="org.frameworkset.nosql.mongodb.ClientMongoCredential"
f:mechanism="MONGODB-CR"
f:database="sessiondb"
f:userName="bboss"
f:password="bboss"/>
<property class="org.frameworkset.nosql.mongodb.ClientMongoCredential"
f:mechanism="MONGODB-CR"
f:database="tokendb"
f:userName="bboss"
f:password="bboss"/>

</list>
</property>

</property>
</properties>

mongodb单机和集群配置认证方法是一样的。
[size=xx-large][b]7.bboss会话管理机制与容器管理机制切换[/b][/size]
bboss会话管理兼容容器会话管理机制,bboss会话管理会话管理机制与容器管理机制可以进行切换,切换方法非常简单,只需修改sessionstore属性即可:
启用bboss会话共享机制:
<property name="sessionstore" refid="attr:sessionstore"/>  

关闭bboss会话共享机制并启用容器会话共享机制:
<property name="sessionstore" value="session"/>

[size=xx-large][b]8.使用session会话共享注意事项[/b][/size]
a. bboss会话共享不需要session粘捻机制,所以可以使用诸如haproxy,lvs的3,4层负载机制来实现应用系统的负责均衡功能。
b. 确保共享会话应用部署服务器之间的时钟保持同步一致
c. 在监控中心统一销毁所有失效session,解放应用管理失效session的职责
d. 应用必须设置为管理本应用的会话数据,只能在监控中心管理所有应用的会话数据
e. session中对象的序列化采用bboss自带的序列化框架,如果碰到对象无法序列化问题,可以通过bboss自定义序列化插件定义特定的序列化插件来实现这些对象的序列化。具体序列化介绍请参看文档:
[url=http://yin-bp.iteye.com/blog/2071882]bboss自定义类对象序列化机制介绍[/url]
[url=http://yin-bp.iteye.com/blog/1375834]bboss序列化功能介绍[/url]

[size=xx-large][b]9.遗留系统集成会话共享组件哪些情况下需要进行程序调整[/b][/size]
遗留系统集成会话共享组件哪些情况下需要进行程序调整呢,下面列举了最常见的几种情况:
a).遗留系统修改存储在session中数据对象的属性和状态,但是没有重新set到session中
修改:这个问题有两种解决方案
方案一 修改程序

调用session.setAttribute方法将修改后的对象再次存储到mongodb中的session表中,以便将修改共享给其他域应用或者集群应用节点。
TestVO testVO = (TestVO)session.getAttribute("testVO");
//修改testVO中属性的值
testVO.setId("testvoidaaaaa,sessionmonitor modifiy id");
//需要将修改后的对象重新设置到session中否则无法存储最新的testVO到mongodb中
session.setAttribute("testVO", testVO);


方案二 修改配置属性,如下:
<property name="lazystore" value="true"/>
<property name="storeReadAttributes" value="true"/>
这样修改了testVO的属性,无需手动设置回session,bboss会在请求结束时强制将复杂对象存储到redis或者mongodb,读取到的基本数据类型(String,数字,日期,Local)不会被强制存储:
TestVO testVO = (TestVO)session.getAttribute("testVO");
//修改testVO中属性的值
testVO.setId("testvoidaaaaa,sessionmonitor modifiy id");

b). 遗留系统存储在session中的对象数据无法采用bboss进行序列化或者反序列化
修改:调整对象定义或者为对象编写序列化插件,采取哪种方式视实际情况来定

c).遗留系统定义并使用Session Event Listener,bboss提供了特有的session监听器
修改:需要将原来的session监听器迁移到bboss规范的session监听器

d.)遗留系统使用了重量级的session数据对象(对象中引用了很多大对象,这些大对象彼此没有关联,如果只需要获取或者修改其中的一部分数据,每次都要完整地将从mongodb中获取/写入这个完整的大对象,导致IO和性能低下)
修改:将这些彼此独立的数据从大对象中剥离出来,作为独立属性存储到session中,从而避免不必要的开销。

[b][size=large][color=red]e.)集成常见问题解决办法[/color][/size][/b]

[b]1.无构造函数对象序列化报错问题解决方法[/b]

Caused by: java.lang.NoSuchMethodException: org.springframework.security.web.savedrequest.DefaultSavedRequest do not define a default construction.

解决方法:为这些类指定jvm原生序列化机制,以spring security框架对象为例:
org.springframework.security.providers.UsernamePasswordAuthenticationToken


修改bboss序列化插件文件:[color=blue][b]resources/org/frameworkset/soa/serialconf.xml[/b][/color],添加内容:

<property name="org.springframework.security.providers.UsernamePasswordAuthenticationToken" magic="3"serial="org.frameworkset.soa.JDKSerial"/>

最终的配置文件serialconf.xml内容
<properties>
<property name="java.util.Locale" magic="1" serial="org.frameworkset.soa.LocaleSerial"/>
<property name="net.sf.jasperreports.engine.JasperPrint" magic="2" serial="org.frameworkset.soa.JDKSerial"/>
<property name="org.springframework.security.providers.UsernamePasswordAuthenticationToken" magic="3" serial="org.frameworkset.soa.JDKSerial"/>
</properties>

注意:其中的magic属性必须在保证全局唯一

Bboss序列化插件定义和配置参考文档:http://yin-bp.iteye.com/blog/2071882

[b]2. hibernate延迟加载容器对象序列化错误问题解决方法[/b]

解决方法:升级到最新的bboss框架包和session共享包

[b]3. 404/403/500错误页面没有禁用session,导致bboss session共享失效[/b]

解决方法:404/403/500错误页面禁用session,在jsp头部添加session="false"属性

<%@ page session="false"  language="java" contentType="text/html; charset=UTF-8"%>

[b]4. sessionFilter拦截的动态请求地址必须涵盖所有需要使用session的动态请求地址,不要遗漏特殊的地址,例如:/ [/b]

[b]5.session数据序列化过程产生的一些无关紧要的Exception,可以直接忽略掉,参考以下方法设置需要忽略的异常类[/b]

指定序列化过程中可以忽略的异常信息,以换行符分割
在bboss 序列化插件配置文件/resources/org/frameworkset/soa/serialconf.xml的ignoreExceptions节点中进行设置:

<property name="ignoreExceptions">
<![CDATA[
org.frameworkset.soa.IgnoreException1
org.frameworkset.soa.IgnoreException2
]]>
</property>


默认忽略hibernate延迟加载异常:org.hibernate.LazyInitializationException

[size=xx-large][b]10.session id cookiename命名约定[/b][/size]
会话共享框架采用cookie机制在浏览器端存放session id,为了避免同根域应用之间session id冲突,必须为这些同根域的应用指定不同cookiename;但是如果需要做跨域跨应用会话共享的情况下,这些子域名不同的应用(或者域名相同上下文不同的应用)的必须指定相同cookiename,否则无法实现跨域跨应用会话共享。


总体来说bboss的会话共享机制非常简单实用和高效。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值