如何在分布式系统中共享shiro会话?

时间:2016-11-30 03:12:29

标签: java shiro

我有两个分布式网络应用程序A和B(A与B相同),我使用shiro来共享两个应用程序之间的http会话。但我不知道如何实现它,我想要一些帮助。 任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:1)

Shiro有Hazelcast和EhCache的官方模块。 上面的Hazelcast链接到博客文章,其中包含两个应用程序共享会话的示例。

答案 1 :(得分:-1)

我希望shiro-redis能给你一些帮助。也许这段代码不是最近的。但你可以研究他的方法。然后你可以创建你的代码。


我会给你一些代码如下:
1 sessionDao

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;

public class SessionRedisDao extends EnterpriseCacheSessionDAO {

    // create session , store to db
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = super.doCreate(session);
        RedisDb.setObject(sessionId.toString().getBytes(), sessionToByte(session));

        return sessionId;
    }

    // get session
    @Override
    protected Session doReadSession(Serializable sessionId) {
        // firstly get session from cache,if null then get it from db
        Session session = super.doReadSession(sessionId); 
        if(session == null){
            byte[] bytes = RedisDb.getObject(sessionId.toString().getBytes());
            if(bytes != null && bytes.length > 0){
                session = byteToSession(bytes);    
            }
        }
        return session;
    }


    @Override
    protected void doUpdate(Session session) {
        super.doUpdate(session);
        RedisDb.setObject(session.getId().toString().getBytes(), sessionToByte(session));
    }

    // delete session
    @Override
    protected void doDelete(Session session) {
        super.doDelete(session);
        RedisDb.delString(session.getId() + "");
    }

    // convert session object to byte, then store it to redis
    public byte[] sessionToByte(Session session){
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        byte[] bytes = null;
        try {
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(session);
            bytes = bo.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    // restore session
    public Session byteToSession(byte[] bytes){
        ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
        ObjectInputStream in;
        SimpleSession session = null;
        try {
            in = new ObjectInputStream(bi);
            session = (SimpleSession) in.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return session;
    }

}
  1. redis operator

    import java.util.Arrays;
    import java.util.Date;
    import java.util.Set;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    public class RedisDb {
    private static JedisPool jedisPool;
    // session expire time
    private static int expireTime = 1800;
    private static int countExpireTime = 2*24*3600;
    private static String password = "123456";
    private static String redisIp = "10.10.31.149";
    private static int redisPort = 6379;
    private static int maxActive = 200;
    private static int maxIdle = 200;
    private static long maxWait = 5000;
    private static Logger logger = Logger.getLogger(RedisDb.class);
    
    static {
        initPool();
    }
    // init connect pool
    public static void initPool(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxActive);
        config.setMaxIdle(maxIdle);
        config.setMaxWaitMillis(maxWait);
        config.setTestOnBorrow(false);
        jedisPool = new JedisPool(config, redisIp, redisPort, 10000, password);
    }
    // get connect from pool
    public static Jedis getJedis(){
        Jedis jedis = null;
        try{
            jedis = jedisPool.getResource();
            //            jedis.auth(password);
        } catch(Exception e){
            ExceptionCapture.logError(e);
        }
    
        return jedis;
    }
    // recycle connection
    public static void recycleJedis(Jedis jedis){
        if(jedis != null){
            try{
                jedis.close();
            } catch(Exception e){
                ExceptionCapture.logError(e);
            }
        }
    }
    // save string
    public static void setString(String key, String value){
        Jedis jedis = getJedis();
        if(jedis != null){
            try{
                jedis.set(key, value);
            } catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    
    }
    // get string data
    public static String getString(String key){
        Jedis jedis = getJedis();
        String result = "";
        if(jedis != null){
            try{
                result = jedis.get(key);
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    
        return result;
    }
    // delete string 
    public static void delString(String key){
        Jedis jedis = getJedis();
        if(jedis != null){
            try{
                jedis.del(key);
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    }
    // save byte data
    public static void setObject(byte[] key, byte[] value){
        Jedis jedis = getJedis();
        String result = "";
        if(jedis != null){
            try{
                if(!jedis.exists(key)){
                    jedis.set(key, value);
                }
                // redis中session过期时间
                jedis.expire(key, expireTime);
            } catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    }
    // get byte data 
    public static byte[] getObject(byte[] key){
        Jedis jedis = getJedis();
        byte[] bytes = null;
        if(jedis != null){
            try{
                bytes = jedis.get(key);;
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
        return bytes;
    
    }
    
    // update byte data 
    public static void updateObject(byte[] key){
        Jedis jedis = getJedis();
        if(jedis != null){
            try{
                // redis中session过期时间
                jedis.expire(key, expireTime);
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    
    }
    
    // key value add 1
    public static void inc(String key){
        Jedis jedis = getJedis();
        if(jedis != null){
            try{
                if(!jedis.exists(key)){
                    jedis.set(key, "1");
                    jedis.expire(key, countExpireTime);
                } else {
                    // 加1
                    jedis.incr(key);
                }
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
    }
    
    // get all keys
    public static Set<String> getAllKeys(String pattern){
        Jedis jedis = getJedis();
        if(jedis != null){
            try{
                return jedis.keys(pattern);
            }catch(Exception e){
                ExceptionCapture.logError(e);
            } finally{
                recycleJedis(jedis);
            }
        }
        return null;
    }
    

    }

  2. shiro的会话只是一个对象,所以如果你想分享会话,你需要将它存储在共享位置。