Shiro集群实现

apache shiro集群实现(一) session共享 [url]http://blog.csdn.net/michaelliuyang/article/details/8819852[/url]
apache shiro集群实现(二)— cache共享 [url]http://blog.csdn.net/michaelliuyang/article/details/8820390[/url]
Redis整合Spring结合使用缓存实例 [url]http://blog.csdn.net/evankaka/article/details/50396325[/url]


原文的修改: 很多人留言希望提供基础代码, 但原文的作者不愿意提供基础代码, 让人很纳闷, 所以自己找了很久, 决定替换和修改原文的代码
[b][color=red]针对redis的session共享的配置或者源码[/color][/b]
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"></bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="192.168.0.198"/>
<property name="port" value="6379"/>
<property name="password" value="12345"/>
<property name="timeout" value="1000"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
<property name="usePool" value="true"/>
</bean>
<!--
GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
JacksonJsonRedisSerializer: 序列化object对象为json字符串
JdkSerializationRedisSerializer: 序列化java对象
StringRedisSerializer: 简单的字符串序列化
-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="defaultSerializer" ref="jdkSerializationRedisSerializer" />
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="hashKeySerializer" ref="stringRedisSerializer"/>
<property name="valueSerializer" ref="jdkSerializationRedisSerializer"/>
<property name="hashValueSerializer" ref="jdkSerializationRedisSerializer"/>
</bean>
<bean id="redisUtil" class="com.pandy.framework.base.redis.utils.RedisUtil">
<property name="redisTemplate" ref="redisTemplate"/>
</bean>



package com.pandy.framework.base.shiro.session.dao.impl;

import com.pandy.framework.base.redis.utils.RedisUtil;
import com.pandy.framework.base.shiro.session.dao.ShiroSessionRepository;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
* Created by pandy on 16-5-3.
*/
public class JedisShiroSessionRepository implements ShiroSessionRepository {
private Logger logger = LoggerFactory.getLogger(JedisShiroSessionRepository.class);
private RedisUtil redisUtil;

/**
* redis session key前缀
*/
private final String REDIS_SHIRO_SESSION = "PANDY-WP-FRAMEWORK-SESSION";
private String redisShiroSessionPre;

public void saveSession(Session session) {
if (session == null || session.getId() == null) {
logger.error("session或者session id为空");
return;
}
redisUtil.set(getRedisSessionKey(session.getId()), session);

}

public void deleteSession(Serializable id) {
if (id == null) {
logger.error("id为空");
return;
}
redisUtil.remove(getRedisSessionKey(id));
}

public Session getSession(Serializable id) {
if (id == null) {
logger.error("id为空");
return null;
}
Session session = redisUtil.get(getRedisSessionKey(id), Session.class);
return session;
}

public Collection<Session> getAllSessions() {
Set<Session> sessions = new HashSet<Session>();
Set<String> set = redisUtil.getPatternKey("*");

if (set == null || set.size() == 0)
return sessions;
Iterator<String> it = set.iterator();
while (it.hasNext()) {
try {
String key = it.next();
if(key!=null && key.indexOf(REDIS_SHIRO_SESSION)>=0){
Session session = redisUtil.get(key, Session.class);
sessions.add(session);
}

}catch (Exception e){
e.printStackTrace();
}
}

return sessions;
}

/**
* 获取redis中的session key
*
* @param sessionId
* @return
*/
private String getRedisSessionKey(Serializable sessionId) {
return getRedisShiroSessionPre() + sessionId;
}


public RedisUtil getRedisUtil() {
return redisUtil;
}

public void setRedisUtil(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}

public String getRedisShiroSessionPre() {
if (redisShiroSessionPre == null || redisShiroSessionPre.trim().length() == 0) {
return REDIS_SHIRO_SESSION + ":";
}
return REDIS_SHIRO_SESSION + "-" + redisShiroSessionPre + ":";
}

public void setRedisShiroSessionPre(String redisShiroSessionPre) {
this.redisShiroSessionPre = redisShiroSessionPre;
}
}



<!-- 使用redis处理会话DAO -->
<bean id="jedisShiroSessionRepository" class="com.pandy.framework.base.shiro.session.dao.impl.JedisShiroSessionRepository">
<property name="redisUtil" ref="redisUtil"/>
<property name="redisShiroSessionPre" value="PANDY_WEB_APP_SESSION"/>
</bean>
<bean id="sessionDAO" class="com.pandy.framework.base.shiro.session.dao.impl.CustomShiroSessionDAO">
<property name="shiroSessionRepository" ref="jedisShiroSessionRepository" />
<property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean>



针对redis的cache的配置或源码
package com.pandy.framework.base.shiro.cache;

import com.pandy.framework.base.redis.utils.RedisUtil;
import org.apache.shiro.cache.Cache;

/**
* Created by pandy on 16-5-4.
*/
public class JedisShiroCacheManager implements ShiroCacheManager {
private RedisUtil redisUtil;
private String redisShiroCachePre;


public <K, V> Cache<K, V> getCache(String name) {
return new JedisShiroCache<K, V>(name, redisUtil, getRedisShiroCachePre());
}

public void destroy() {
//jedisCacheManager.getJedis().shutdown();
throw new RuntimeException("这里要怎么实现啊,还不知道怎么实现");
}

public RedisUtil getRedisUtil() {
return redisUtil;
}

public void setRedisUtil(RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}

public String getRedisShiroCachePre() {
return redisShiroCachePre;
}

public void setRedisShiroCachePre(String redisShiroCachePre) {
this.redisShiroCachePre = redisShiroCachePre;
}
}



package com.pandy.framework.base.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;

/**
* Created by pandy on 16-5-4.
*/
public class CustomShiroCacheManager implements CacheManager, Destroyable {

private ShiroCacheManager shiroCacheManager;

public ShiroCacheManager getShiroCacheManager() {
return shiroCacheManager;
}

public void setShiroCacheManager(ShiroCacheManager shiroCacheManager) {
this.shiroCacheManager = shiroCacheManager;
}

public <K, V> Cache<K, V> getCache(String name) throws CacheException {
return getShiroCacheManager().getCache(name);
}

public void destroy() throws Exception {
shiroCacheManager.destroy();
}

}



package com.pandy.framework.base.shiro.cache;

import com.pandy.framework.base.redis.utils.RedisUtil;
import com.pandy.framework.base.utils.SerializeUtil;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;

import java.util.*;

/**
* Created by pandy on 16-5-4.
*/
public class JedisShiroCache<K, V> implements Cache<K, V> {
private RedisUtil redisUtil;
private final String REDIS_SHIRO_CACHE = "PANDY-WP-FRAMEWORK-CACHE";
private String redisShiroCachePre;
private String name;

public JedisShiroCache(String name, RedisUtil redisUtil, String redisShiroCachePre) {
this.name = name;
this.redisUtil = redisUtil;
this.redisShiroCachePre = redisShiroCachePre;
}

/**
* 自定义relm中的授权/认证的类名加上授权/认证英文名字
*
* @return
*/
public String getName() {
if (name == null)
return "";
return name;
}

public void setName(String name) {
this.name = name;
}

public V get(K key) throws CacheException {
byte[] byteKey = SerializeUtil.serialize(getCacheKey(key));
//byte[] byteValue = redisUtil.get(getCacheKey(key));
Object byteValue = redisUtil.get(getCacheKey(key));
return (V) byteValue;
}

public V put(K key, V value) throws CacheException {
V previos = get(key);
redisUtil.set(getCacheKey(key), value);
return previos;
}

public V remove(K key) throws CacheException {
V previos = get(key);
redisUtil.remove(getCacheKey(key));
return previos;
}

public void clear() throws CacheException {
byte[] keysPattern = SerializeUtil.serialize(this.REDIS_SHIRO_CACHE + "*");
redisUtil.removePattern(getCacheKey(keysPattern));
}

public int size() {
if (keys() == null)
return 0;
return keys().size();
}

public Set<K> keys() {
Set<K> set = (Set<K>) redisUtil.getPatternKey("*");
return set;
}

public Collection<V> values() {
List<V> result = new LinkedList<V>();
return result;
}

private String getCacheKey(Object key) {
if (redisShiroCachePre == null || redisShiroCachePre.trim().length() == 0)
return this.REDIS_SHIRO_CACHE + getName() + ":" + key;
else
return this.REDIS_SHIRO_CACHE + "-" + redisShiroCachePre + getName() + ":" + key;
}
}



<!-- 使用redis缓存管理器 -->
<bean id="jedisShiroCacheManager" class="com.pandy.framework.base.shiro.cache.JedisShiroCacheManager">
<property name="redisUtil" ref="redisUtil" />
<property name="redisShiroCachePre" value="PANDY_WEB_APP_CACHE"/>
</bean>
<bean id="cacheManagerWrapper" class="com.pandy.framework.base.shiro.cache.CustomShiroCacheManager">
<property name="shiroCacheManager" ref="jedisShiroCacheManager" />
</bean>


RedisUtil.java参考: [url]http://panyongzheng.iteye.com/blog/2295435[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nginx是一款高性能的HTTP和反向代理服务器,可以实现负载均衡和高可用性。Spring Boot是一个快速构建应用程序的框架,Shiro是一个用于安全验证和访问控制的框架,而Session共享是指将用户会话信息存储在多个服务器上,以实现用户请求的无缝切换。 在Nginx和Spring Boot集群中使用Shiro时,可以使用Session共享来实现用户的无状态会话管理。具体实施如下: 1. 集群配置:将多个Spring Boot实例部署在不同的服务器上,并使用Nginx进行反向代理和负载均衡。通过配置Nginx的upstream块,将请求分发给多个Spring Boot实例。 2. Session共享:使用分布式缓存来实现Session共享。可以选择使用Redis、Memcached等分布式缓存系统,将Session数据存储在缓存中。在Spring Boot中,可以使用Spring Session提供的支持来进行Session共享的配置。 3. Shiro配置:在Spring Boot中,可以使用Shiro框架来处理身份验证和访问控制。在Shiro中,可以实现自定义的SubjectDAO来将Session存储到分布式缓存中。同时,通过配置Shiro的SessionManager和SessionDAO,将Session的读取和存储操作委托给分布式缓存系统。 4. 应用程序开发:在Spring Boot应用程序中使用Shiro时,可以通过注解或配置文件来配置身份验证和访问控制规则。在验证用户身份后,可以将用户信息存储在Session中,并通过Session共享机制,在多个服务器上共享该Session数据。 通过以上步骤,可以实现在Nginx、Spring Boot集群中使用Shiro框架进行Session共享。这样,用户可以在不同的服务器上无缝切换,并享受到一致的用户体验。同时,通过Nginx的负载均衡机制,可以提高系统的性能和可伸缩性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值