博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tomcat+nginx+shiro+jfinal 实现负载均衡,session共享
阅读量:7115 次
发布时间:2019-06-28

本文共 10034 字,大约阅读时间需要 33 分钟。

hot3.png

1.创建OnlineSessionDao继承EnterpriseCacheSessionDAO,实现session持久化共享 

package com.jsaas.core.security;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 java.util.Collection;import org.apache.shiro.session.Session;import org.apache.shiro.session.UnknownSessionException;import org.apache.shiro.session.mgt.SimpleSession;import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;import com.jfinal.log.Log;import com.jfinal.plugin.ehcache.CacheKit;import com.jfinal.plugin.redis.Redis;/** * @ClassName: onlineSessionDao * @Description: session管理,获取在线用户等(session持久化,配合nginx负载均衡,实现共享session) * @author tuozq * @date 2017年11月3日 上午9:48:01 * */public class OnlineSessionDao extends EnterpriseCacheSessionDAO {	private static final Log log = Log.getLog(OnlineSessionDao.class);		//定义sessionDao缓存的前缀,可以通过 Redis.use().getJedis().keys(OnlineSessionDao.cacheNamePrefix + "*") 获取到sessionDao缓存的所有session	public static final String cacheNamePrefix = "shiro_sessionDao_cache:";		private void set(String key, Object value){		Redis.use().set(cacheNamePrefix + key, value);	}		private Object get(String key){		return Redis.use().get(cacheNamePrefix + key);	}		private void remove(String key){		Redis.use().del(cacheNamePrefix + key); 	}		/**	 * 创建session	 */	@Override	public Serializable doCreate(Session session) {		Serializable sessionId = super.doCreate(session);		log.info("创建  Session:"+session.getHost() + ";" + session.getId());		set(session.getId().toString(), sessionToByte(session));		return sessionId;	}			/**	 * 删除session	 */	@Override	public void doDelete(Session session) {		log.info("删除 Session:"+session.getHost() + ";" + session.getId());		remove(session.getId().toString());		super.doDelete(session);	}	/**	 * 更新session的最后一次访问时间	 */	@Override	public void doUpdate(Session session) throws UnknownSessionException {		log.info("更新 Session:"+session.getHost() + ";" + session.getId());		set(session.getId().toString(), sessionToByte(session));		super.doUpdate(session);	}	/**	 * 获取session	 */	@Override	protected Session doReadSession(Serializable sessionId) {		Session session = super.doReadSession(sessionId);		if(session == null){			byte[] bytes = (byte[]) get(sessionId.toString());			if(bytes != null && bytes.length > 0){				session = byteToSession(bytes);			}		}		return session;	}		// 把session对象转化为byte保存到缓存中	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;	}	// 把byte还原为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;	}}

2.使用redis接管shiro cacheManage

创建RedisCacheManage类实现CacheManager接口,在shiro.ini中指定cacheManager为RedisCacheManage

package com.jsaas.core.security.cache;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import org.apache.shiro.cache.CacheManager;import com.jfinal.log.Log;import com.jfinal.plugin.redis.Redis;/**   * @Title: RedisCacheManage.java * @Package com.jsaas.core.security * @Description: TODO(接管shiro缓存管理) * @author tuozq * @date 2017年12月7日 上午9:26:07 * @version V1.0   */@SuppressWarnings({"rawtypes","unchecked"})public class RedisCacheManage implements CacheManager {		private static final Log log = Log.getLog(RedisCacheManage.class);			private final ConcurrentMap
caches = new ConcurrentHashMap
(); public
Cache
getCache(String name) throws CacheException { // TODO Auto-generated method stub log.info(String.format("获取redis %s 实例", name)); if(caches.containsKey(name)){ return caches.get(name); } RedisCache
redisCache = new RedisCache
(new RedisManage(name)); caches.put(name, redisCache); return redisCache; }}

 实现shiro的cache

package com.jsaas.core.security.cache;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.List;import java.util.Set;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheException;import com.jfinal.log.Log;import redis.clients.jedis.Jedis;/**   * @Title: RedisCache.java * @Package com.jsaas.core.security.cache * @Description: TODO(shiro缓存cache) * @author tuozq * @date 2017年12月7日 上午9:50:19 * @version V1.0   */public class RedisCache
implements Cache
{ Log log = Log.getLog(RedisCache.class); private RedisManage redisManage; public RedisCache(RedisManage redisManage){ this.redisManage = redisManage; } private com.jfinal.plugin.redis.Cache getCache(){ log.info("user cache :" + redisManage.getPrefix()); return redisManage.getCache(); } public void clear() throws CacheException { // TODO Auto-generated method stub getCache().getJedis().flushDB(); } public V get(K key) throws CacheException { // TODO Auto-generated method stub return getCache().get(redisManage.getPrefix() + key); } @SuppressWarnings("unchecked") public Set
keys() { // TODO Auto-generated method stub Jedis jedis = getCache().getJedis(); Set
keys = jedis.keys(redisManage.getPrefix() + "*"); Set
ks = new HashSet
(); for (String key : keys) { ks.add((K)key); } return ks; } public V put(K key, V value) throws CacheException { // TODO Auto-generated method stub getCache().set(redisManage.getPrefix() + key, value); return value; } public V remove(K key) throws CacheException { // TODO Auto-generated method stub V value = getCache().get(redisManage.getPrefix() + key); getCache().del(redisManage.getPrefix() + key); return value; } public int size() { // TODO Auto-generated method stub return keys().size(); } public Collection
values() { // TODO Auto-generated method stub Set
ks = keys(); List
vs = new ArrayList
(); for (K k : ks) { vs.add(get(k)); } return vs; }}

shiro redisManage

package com.jsaas.core.security.cache;import com.jfinal.plugin.redis.Redis;import com.jsaas.common.Constant;/**   * @Title: RedisManage.java * @Package com.jsaas.core.security.cache * @Description: TODO(shiro redis 缓存管理) * @author tuozq * @date 2017年12月7日 上午11:28:31 * @version V1.0   */public class RedisManage {	private com.jfinal.plugin.redis.Cache cache;		//用于区分shiro不同的cache name	private String prefix;		public RedisManage(String cachename) {		// TODO Auto-generated constructor stub		this.prefix = cachename + ":";	}		public com.jfinal.plugin.redis.Cache getCache() {		if(cache == null){			//在jfinalConfig中添加redis插件  me.add(new RedisPlugin(Constant.REDIS_SHIROMANAGE_CACHE, "127.0.0.1", 6379));			cache = Redis.use(Constant.REDIS_SHIROMANAGE_CACHE);		}		return cache;	}		public String getPrefix(){		return this.prefix;	}}

 

3.nginx配置

#配置集群	upstream jsaas_server {                                                         		server localhost:81 weight=5;		server localhost:82 weight=5;					}    #gzip  on;    server {        listen       80;        server_name  localhost;				#配置代理服务器		location / {			proxy_pass http://jsaas_server;# http://localhost:80/ 请求转发到jsaas_server集群			proxy_set_header Host  $http_host;            proxy_set_header Cookie $http_cookie;            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_set_header X-Forwarded-Proto $scheme;            client_max_body_size  100m;            proxy_connect_timeout 1;#连接超时时间,不能设置过长,否则服务器宕机时无法快速切换服务器			#proxy_set_header Host $host:$server_port;		}

4.shiro.ini

#指定sessiondaosessionDAO = com.jsaas.core.security.OnlineSessionDaosessionDAO.activeSessionsCacheName = shiro-activeSessionCachesessionManager.sessionDAO = $sessionDAO#指定cacheManagercacheManager = com.jsaas.core.security.cache.RedisCacheManagesecurityManager.cacheManager = $cacheManager###############################全部shiro配置########################################[main]#realm#自定义RealmmyRealm = com.jsaas.core.security.ShiroDbRealmsecurityManager.realm = $myRealm#配置shiro的密码验证方式为盐加密   也可以通过ShiroDbRealm 中 setCredentialsMatcher方法指定自定义的密码验证方式credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatchercredentialsMatcher.hashAlgorithmName=SHA-1credentialsMatcher.hashIterations=1024credentialsMatcher.storedCredentialsHexEncoded=truemyRealm.credentialsMatcher=$credentialsMatcher#没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”shiro.loginUrl = /login#登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。shiro.successUrl = /sys/user/successUrl#没有权限默认跳转的页面。shiro.unauthorizedUrl = /403#sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManagersessionManager = com.jsaas.core.security.MyWebSessionManager#ehcache#shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager#shiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xml#securityManager.cacheManager = $shiroCacheManager#redis cachecacheManager = com.jsaas.core.security.cache.RedisCacheManagesecurityManager.cacheManager = $cacheManager#session#sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAOsessionDAO = com.jsaas.core.security.OnlineSessionDaosessionDAO.activeSessionsCacheName = shiro-activeSessionCachesessionManager.sessionDAO = $sessionDAOsecurityManager.sessionManager = $sessionManagersecurityManager.sessionManager.globalSessionTimeout = 360000[urls]/res/** = anon/login/** = anon/user/** = anon/** = authc

 

转载于:https://my.oschina.net/u/2276456/blog/1585202

你可能感兴趣的文章
2、使用rpm包安装grafana
查看>>
CS 2505 Computer Organization I C05: Pointers in C
查看>>
BZOJ3527 [Zjoi2014]力
查看>>
Could not find gradle wrapper within android sdk
查看>>
LeetCode – Refresh – Generate Parentheses
查看>>
【Prince2科普】Prince2七大流程之启动流程
查看>>
CentOS6.5安装后无法启动Emacs问题的解决
查看>>
转载----开发者大杀器 —— 刨根问底,揪出 Android App 耗电的元凶代码
查看>>
【数学基础篇】---详解极限与微分学与Jensen 不等式
查看>>
Spring MVC -- UEditor 编辑器整合 上传图片至外部文件夹(非项目文件夹)
查看>>
构建之法第六、七章读后感
查看>>
ti processor sdk linux am335x evm /bin/setup-minicom.sh hacking
查看>>
Android学习笔记001
查看>>
依赖注入(DI)与服务容器(IoC)
查看>>
享元模式(Flyweight)
查看>>
翟振武教授的荒唐逻辑
查看>>
python2和python3的区别
查看>>
ssh 公钥认证方式登录
查看>>
php json_decode
查看>>
SQL Server case when 日期字符串转换 多表查询 嵌套子查询
查看>>