一般情况下WEB应用集群的会话复制都是通过容器实现的,shiro权限框架中可以定义SessionDAO直接将session持久化到缓存中,这样只需要对缓存做集群就可以代替session的复制。
实现思路
1、用SessionDAO将session保存到ehcache缓存
2、配置ehcache的jgroups集群复制,如果集群服务器比较多,可升级到缓存服务器
思路很简单,但实现过程遇到不少问题,现在把过程及配置文件记录下来,避免忘记。
第一步将SessionDAO保存到ehcache缓存,这个步骤很简单,也没出什么问题,按照网上的例子很容易,下面是配置文件主要片段:
<!-- 主要是为了注入SessionDAO -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
<!-- SessionDAO用shiro提供的默认实现 -->
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<!-- <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/> -->
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!-- 为了实现自己的用户权限 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm"/>
<property name="sessionManager" ref="sessionManager"/>
<!-- By default the servlet container sessions will be used. Uncomment this line
to use shiro's native sessions (see the JavaDoc for more): -->
<!-- <property name="sessionMode" value="native"/> -->
</bean>
<!-- 自定义的用户权限,这里也需要用缓存,避免从数据库加载权限 -->
<bean id="userRealm" class="cn.ys.security.UserRealm">
<property name="cacheManager" ref="shiroCacheManager"/>
<property name="userService" ref="securityService" />
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 与spring ehcache集成 -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="ehcache"/>
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
第二步遇到很多问题,网上资料比较少,对jgroups又不熟,下面是配置文件及我遇到的问题:
ehcache.xml
<!-- 缓存同步jgroup配置 -->
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="file=jgroups_tcp.xml" />
<diskStore path="java.io.tmpdir/ehcache"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="shiro-activeSessionCache"
maxElementsInMemory="1000"
overflowToDisk="true"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="600">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />
</cache>
<cache name="cn.ys.security.UserRealm.authorizationCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />
</cache>
<cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />
</cache>
jgroups_tcp.xml
<config>
<TCP bind_port="7800" bind_addr="localhost"
loopback="false"
recv_buf_size="${tcp.recv_buf_size:20M}"
send_buf_size="${tcp.send_buf_size:1M}"
discard_incompatible_packets="true"
max_bundle_size="2M"
max_bundle_timeout="30"
enable_bundling="true"
use_send_queues="true"
sock_conn_timeout="300"
timer_type="new"
timer.min_threads="4"
timer.max_threads="10"
timer.keep_alive_time="3000"
timer.queue_max_size="500"
thread_pool.enabled="true"
thread_pool.min_threads="1"
thread_pool.max_threads="10"
thread_pool.keep_alive_time="5000"
thread_pool.queue_enabled="false"
thread_pool.queue_max_size="100"
thread_pool.rejection_policy="discard"
oob_thread_pool.enabled="true"
oob_thread_pool.min_threads="1"
oob_thread_pool.max_threads="8"
oob_thread_pool.keep_alive_time="5000"
oob_thread_pool.queue_enabled="false"
oob_thread_pool.queue_max_size="100"
oob_thread_pool.rejection_policy="discard"
/>
<TCPPING timeout="3000"
initial_hosts="localhost[7800]"
port_range="5"
num_initial_members="5"/>
<MERGE2 min_interval="10000"
max_interval="30000"/>
<FD_SOCK/>
<FD timeout="3000" max_tries="3" />
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK use_mcast_xmit="false"
retransmit_timeout="300,600,1200,2400,4800"
discard_delivered_msgs="true"/>
<pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="400000"/>
<pbcast.GMS print_local_addr="true" join_timeout="5000" view_bundling="true"/>
</config>
在网上查找的例子jgroups版本可能比较老,ehcache中的例子也一样,有些属性新的jgroups已经不认了,如start_port已经改成了bind_port,另外新版本jgroups增加了bind_addr,这样就可以直接指定ip地址绑定了,不需要在jvm上增加ipv4参数。
配置jgroups的几个需要理解的地方
1、jgroups的TCP的端口是自动分配自动发现的,同一台服务器上的多个实例不需要都配置到initial_hosts中,一个IP在initial_hosts中只需要定义一次,端口与bind_port保持一致
2、port_range是用于端口自动分配和自动发现用的,例如bind_port值为7800,当同服务上的第一个实例启动是使用7800端口,第二个实现启动时使用的是7801,最多只到7804
3、max_bundle_size不要太小,例子上该值只有64K,结果有时会现在无法复制的情况
4、当实例关闭再启动时,jgroups会认为是另一个host,原来的host如果不设置超时会一直存在,所以要注意设置keep_alive_time
分享到:
相关推荐
5. **使用 Shiro**:在代码中通过 Shiro 的 API 进行认证和授权操作,Shiro 自动使用 Ehcache 进行缓存。 **Ehcache 在 Shiro 中的应用** 1. **RememberMe 服务**:Shiro 的 RememberMe 功能可以通过 Ehcache 实现...
为实现Web应用的分布式集群部署,要解决登录session的统一。本文利用shiro做权限控制,redis做session存储,结合spring boot快速配置实现session共享。
在本文中,我们介绍了如何使用 Spring Boot 整合 Redis 实现 Shiro 的分布式 Session 共享。我们重写了 SessionDao,使用 RedisTemplate 来存储和管理 Session。这样,我们可以在分布式环境中实现 Session 共享,...
将Shiro与Redis结合,可以优化在多服务器环境下的认证和授权过程,避免了Ehcache在集群环境中可能遇到的数据同步问题。 集成Shiro与Redis的步骤主要包括以下几个方面: 1. 添加依赖:在项目中引入Shiro的Redis插件...
Shiro 提供了内置的 Servlet Filter,如 `FormAuthenticationFilter` 和 `AuthorizationFilter`,可以直接应用于 Web 应用,实现登录、权限拦截等功能。通过配置这些 Filter,可以轻松地保护 Web 资源。 6. **...
6. **会话管理**:Shiro允许自定义会话管理策略,例如设置session超时时间、是否支持集群环境下的session共享等。默认情况下,Shiro会使用内存中的session管理,但也可以配置为使用数据库存储。 7. **缓存管理**:...
Shiro 支持使用外部缓存系统如 EhCache 进行缓存管理,这对于提高性能和降低数据库负担非常有用。配置 EhCache 缓存管理器的方式如下: ```xml <bean id="ehCacheManager" class="org.apache.shiro.cache.ehcache....
因此,可以配置Shiro使用分布式缓存(如Redis或Memcached)来存储会话,以实现集群环境下的会话共享。此外,还可以设置会话超时和心跳检查,确保会话的有效性和安全性。 接下来,我们讨论Cache。Shiro允许你在Realm...
在大型分布式系统中,Ehcache 作为默认的缓存解决方案可能会遇到一些问题,例如在集群环境中无法实现共享会话。为了解决这个问题,我们可以将 Shiro 集成 Redis,利用 Redis 的分布式特性和高性能来实现集中式的缓存...
这有助于在分布式环境中保持会话的一致性,比如在集群环境下,可以利用 `SessionManager` 和 `SessionDAO` 进行会话的复制和持久化。 4. **加密支持**:Shiro 提供了多种加密工具,如 MD5、SHA 等,方便开发者对...
Apache Shiro是一个强大且易用的Java安全框架,它提供了认证、授权、加密和会话管理功能,可以简化企业级应用的安全实现。标题中的"shiro-all-1.2.3.jar"是Apache Shiro的一个完整版本的jar包,包含了Shiro框架的...
\n\n权限体系方面,基于Shiro的深度改造,不仅使用Ehcache提升一级缓存性能,还利用Redis实现二级缓存的持久化和session同步。通过Shiro注解,实现了按钮级、方法级的权限控制,构建了平台、商家和会员三套独立的...
- Apache Shiro用于权限管理和安全框架,支持二级缓存,可以通过Redis实现session同步。 - Ehcache作为Shiro的一级缓存,提高缓存效率。 - Jedis是Java实现的Redis客户端,支持Redis集群模式和单机模式切换。 - ...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问. 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...
1、项目整合redis存储,shiro可使用redisSession可使用于集群访问 2、项目增加jwt模式 3、增加默认启动模式为开发模式 4、优化已知BUG SpringBootAdmin 微服务快速开发脚手架 平台简介 SpringBootAdmin是基于多个...