apache shiro使用nginx集群如何解决cache共享

本文介绍如何使用Redis替代Shiro默认缓存管理器,实现权限缓存的集群共享。通过自定义RedisCacheManager及JedisShiroCacheManager等组件,确保在分布式环境中Shiro的缓存一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果要实现集群共享cache,我们就不能用shiro默认的方式处理了。


之前在我的项目当中使用的cacheManager:

<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />

 <!-- Shiro 配置 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	    <property name="sessionMode" value="native"></property>
	    <property name="sessionManager" ref="sessionManager"/>
		<property name="cacheManager" ref="cacheManager"/>
		<property name="realm" ref="shiroDbRealm" />
	</bean>


现在需要做出一些修改:

<bean id="cacheManager" class="com.xinding.travel.security.RedisCacheManager" >
		<property name="shiroCacheManager" ref="jedisShiroCacheManager"/>
	</bean>

<!-- shiro 缓存实现,对ShiroCacheManager,我是采用redis的实现 -->
	<bean id="jedisShiroCacheManager" class="com.xinding.travel.security.JedisShiroCacheManager">
		<property name="redisManager" ref="redisManager"/>
	</bean>

RedisCacheManager:

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

/**
 * Created by Maggie on 2017/7/14.
 */
public class RedisCacheManager implements CacheManager {

    private ShiroCacheManager shiroCacheManager;

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

    public ShiroCacheManager getShiroCacheManager() {
        return shiroCacheManager;
    }

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

}

JedisShiroCacheManager:

import org.apache.shiro.cache.Cache;

/**
 * Created by Maggie on 2017/7/14.
 */
public class JedisShiroCacheManager implements ShiroCacheManager {

    public RedisManager getRedisManager() {
        return redisManager;
    }

    public void setRedisManager(RedisManager redisManager) {
        this.redisManager = redisManager;
    }

    private RedisManager redisManager;

    @Override
    public <K, V> Cache<K, V> getCache(String name) {
        return new JedisShiroCache<K, V>(name, getRedisManager());
    }
}

JedisShiroCache:

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;

import java.util.Collection;
import java.util.Set;

/**
 * Created by Maggie on 2017/7/14.
 */
public class JedisShiroCache<K, V> implements Cache<K, V> {

    /**
     * 为了不和其他的缓存混淆,采用追加前缀方式以作区分
     */
    private static final String REDIS_SHIRO_CACHE = "shiro_redis_session:";

    private RedisManager redisManager;

    private String name;

    public JedisShiroCache(String name, RedisManager redisManager) {
        this.name = name;
        this.redisManager = redisManager;
    }

    @Override
    public V get(K k) throws CacheException {
        byte[] byteKey = SerializeUtil.serialize(buildCacheKey(k));
        byte[] byteValue = new byte[0];
        try {
            byteValue =redisManager.queryObjectByKey(byteKey);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (V) SerializeUtil.deserialize(byteValue);
    }

    @Override
    public V put(K k, V v) throws CacheException {
        V previos = get(k);
        try {
            redisManager.insertObject(k.toString(),SerializeUtil.serialize(v),0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return previos;
    }

    @Override
    public V remove(K k) throws CacheException {
        V previos = get(k);
        try {
            redisManager.deleteObject(k.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return previos;
    }

    @Override
    public void clear() throws CacheException {

    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public Set<K> keys() {
        return null;
    }

    @Override
    public Collection<V> values() {
        return null;
    }

    private String buildCacheKey(Object key) {
        return REDIS_SHIRO_CACHE + getName() + ":" + key;
    }

    public String getName() {
        if (name == null)
            return "";
        return name;
    }

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

这样配置之后。我的权限的缓存就会由redis管理。这就满足了shiro集群的要求了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值