在spring 里面,spring-session 和 spring-session-data-redis 结合让项目平滑升级与redis 缓存的一些运用

之前每次升级的时候,还要停集群节点,然后升级以后再启动,需求需要不停机升级! 然后实现是用springsession 结合redis 做的缓存!

引入jar

 
            org.springframework.session
            spring-session
            1.2.2.RELEASE
       

        
            org.springframework.session
            spring-session-data-redis
            1.2.2.RELEASE
        

        
            org.springframework.data
            spring-data-redis
            1.7.1.RELEASE

       

注意: 如果spring 版本不高!而redis 和session版本高的话 会导致冲突





		
	 
		springSessionRepositoryFilter
		org.springframework.web.filter.DelegatingFilterProxy
   
	
	
		springSessionRepositoryFilter
		/*
	
	
		FileUploadServlet
		com.tianyi.bph.cg.web.controller.basicdata.FileUploadServlet
	

	
		FileUploadServlet
		/servlet/FileUploadServlet
	
	
		ExcelImportServlet
		com.tianyi.bph.cg.web.controller.basicdata.ExcelImportServlet
	

	
		ExcelImportServlet
		/servlet/ExcelImportServlet
	

	
		contextConfigLocation
		
			classpath*:spring/applicationContext*.xml
		
	
	
		spring.profiles.active
		development
	

	
		org.springframework.web.context.ContextLoaderListener
	
	
		org.springframework.web.util.IntrospectorCleanupListener
	

	
	
		DruidStatView
		com.alibaba.druid.support.http.StatViewServlet
	
	
		DruidStatView
		/druid/*
	

	
	
		dispatcher
		org.springframework.web.servlet.DispatcherServlet
		
		
			contextConfigLocation
			classpath:spring/dispatcher-servlet.xml
		
		1
	

	
		dispatcher
		*.do
	
	
		dispatcher
		*.action
	

	
	
		encodingFilter
		org.springframework.web.filter.CharacterEncodingFilter
		
			encoding
			utf8
		
	
	
		SessionInvalidate
		com.tianyi.bph.cg.rest.Filterlogin
		
			redirectURL
			/cg/login.jsp
		
		
			notCheckURLList
			/cg/login.jsp,/admin/help/
		
		
	
	
	
		SessionInvalidate
		*.jsp
	

	
		sitemesh
		org.sitemesh.config.ConfigurableSiteMeshFilter
	

	
		encodingFilter
		*.do
	
	
		encodingFilter
		*.action
	
	
		sitemesh
		*.action
	

	
	
		DruidWebStatFilter
		com.alibaba.druid.support.http.WebStatFilter
		
			exclusions
			*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
		
	
	
		DruidWebStatFilter
		/*
	




	
		/cg/login.jsp
	
	
		-1
	
	
		404
		/404.jsp
	
	
		500
		/500.jsp
	

配置拦截器!  注意springsession 的拦截器必须放到第一个位置,不然会有奇怪的事情发生!

#redis ��Ⱥ���� host:post,host:post
#reidsClusterNodes=xxx.xxx.xx.xx:xxx 多节点集群
#redis �������� host:post

reidsClusterNodes=xxx.xxx.xx.xx:xxx 单节点

配置redis !

package com.tianyi.bph.cg.web.cache;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * Created by fan on 2017/11/14.
 */
@Component
@PropertySource(value = "classpath:parameter.properties")
public class ClusterConfigurationProperties {

   
	@Value("#{config[reidsClusterNodes]}")
     private String  nodes;

	public String getNodes() {
		return nodes;
	}

	public void setNodes(String nodes) {
		this.nodes = nodes;
	}

    public List getNodesByno(){
    	String[] node = nodes.split(",");
    	List nodes = Arrays.asList(node);
		return nodes;
    }
    
}

spring读取配置redis 信息!

package com.tianyi.bph.cg.web.cache;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.session.data.redis.config.ConfigureRedisAction;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashSet;
import java.util.Set;


/**
 * RedisHttpSessionConfiguration的配置文件
 *
 * 引入RedisHttpSessionConfiguration.class
 *
 * maxInactiveIntervalInSeconds设置session在redis里的超时
 *
 * @author fan
 * 
 */
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=36000)
public class SessionConfig {

	 @Autowired
	 private ClusterConfigurationProperties clusterProperties;	
	 final static Logger logger = LoggerFactory.getLogger(SessionConfig.class);	
	
	 
	
	  @Bean  
      public static ConfigureRedisAction configureRedisAction() {  
          return ConfigureRedisAction.NO_OP;  
      }


	  
    @Bean(name="jedisconnectionFactory")
    public JedisConnectionFactory jedisconnectionFactory() {
    	 try {
             if (StringUtils.isEmpty(clusterProperties.getNodes())) {
                 logger.error("not set redis node");
                 return null;
             }
             if (clusterProperties.getNodesByno().size() > 1) {
                 logger.info("redis sever enable cluster model");
                 RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(
                         clusterProperties.getNodesByno());
                 JedisConnectionFactory connectionFactory = new JedisConnectionFactory(clusterConfiguration,poolConfig());
                 connectionFactory.setTimeout(3600);
                 return connectionFactory;
             } else {          	 
            		 logger.info("redis sever enable single model");
                     JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig());
                     String redisUrl = clusterProperties.getNodesByno().get(0);
                     jedisConnectionFactory.setPort(Integer.parseInt(redisUrl.split(":")[1]));
                     jedisConnectionFactory.setHostName(redisUrl.split(":")[0]);
                     jedisConnectionFactory.setTimeout(3600);
                try {
                     return jedisConnectionFactory;
				} catch (Exception e) {
					 logger.error("redis connection error");
				}
                 
             }
         } catch (Exception e) {
             logger.error("redis connection error");
         }
         return null;
    }
    

    /**
     * JedisPoolConfig 配置
     *
     * 配置JedisPoolConfig的各项属性
     *
     * @return
     */
    private JedisPoolConfig poolConfig(){
        JedisPoolConfig jedisPoolConfig= new JedisPoolConfig();
        //连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(true);
        
        //是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        
        //jedis调用returnObject方法时,是否进行有效检查
        jedisPoolConfig.setTestOnReturn(true);
        
        //最大空闲连接数, 默认8个
        jedisPoolConfig.setMaxIdle(8);
        
        //最大连接数, 默认8个
        jedisPoolConfig.setMaxTotal(8);
        
        //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        jedisPoolConfig.setMaxWaitMillis(-1);
        
        //逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
        jedisPoolConfig.setMinEvictableIdleTimeMillis(1800000);
        
        //最小空闲连接数, 默认0
        jedisPoolConfig.setMinIdle(0);
        
        //每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
        jedisPoolConfig.setNumTestsPerEvictionRun(3);
        
        //对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断  (默认逐出策略)  
        jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(1800000);
        
        //在获取连接的时候检查有效性, 默认false
        jedisPoolConfig.setTestOnBorrow(false);
        
        //在空闲时检查有效性, 默认false
        jedisPoolConfig.setTestWhileIdle(false);
        
        //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(-1);

        return jedisPoolConfig;
    }



    /**
     * RedisTemplate配置
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(
                Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);// 如果key是String
        // 需要配置一下StringSerializer,不然key会乱码
        // /XX/XX
        template.afterPropertiesSet();
        return template;
    }
    /**
     * 管理缓存
     *
     * @param redisTemplate
     * @return
     */
       @SuppressWarnings("rawtypes")
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        CustomRedisCacheManager cacheManager = new CustomRedisCacheManager(
                redisTemplate);
        // rcm.setCacheNames(cacheNames)
        // 设置缓存过期时间
        // rcm.setDefaultExpiration(60);//秒
        // 设置value的过期时间
        Map expiresMap = new ConcurrentHashMap();
        // map.put("test", 60L);
        Set cacheNames = new HashSet<>();
        cacheNames.add("device-data");
        cacheNames.add("alarm-event-data");
        cacheNames.add("gps-data");
        cacheNames.add("alarm-event-new-data");
        cacheNames.add("relation-organ-data");
        cacheNames.add("relation-police-data");
        cacheNames.add("platform-config-data");
        cacheNames.add("organ-data");
        cacheNames.add("intercom-platform-data");
        cacheNames.add("alarm-seat-data");
        expiresMap.put(
                "alarm-seat-data",
                Long.parseLong(systemConfigRepository.findByKey(
                        "expires_alarm-seat-data").getValue()));

        expiresMap.put("alarm-event-new-data", 120L);
        // 设置 by chen
        cacheNames.add("relation-organ-data-new");
        expiresMap.put("relation-organ-data-new", 600L);
        // end
        cacheManager.setCacheNames(cacheNames);
        cacheManager.setExpires(expiresMap);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }
    public static void main(String[] args) {  
        Jedis jedis = new Jedis("25.30.9.4",6379);  
        //ping通显示PONG  
        System.out.println(jedis.ping());//去ping我们redis的主机所在ip和端口  
    }

} 
  

注入springsession bean 和 spring -session-redis 的配置 


package com.tianyi.bph.cg.web.cache;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.Assert;

/**
 * 
 * on 2017/11/28
 */
public class CustomRedisCacheManager extends RedisCacheManager {
    private static Logger logger = LoggerFactory.getLogger(CustomRedisCacheManager.class);

    public CustomRedisCacheManager(RedisOperations redisOperations) {
        super(redisOperations);
    }

    @Override
    public Cache getCache(String name) {
        return new CustomRedisCacheManager.RedisCacheWrapper(super.getCache(name));
    }

    protected static class RedisCacheWrapper implements Cache {

        private final Cache delegate;

        public RedisCacheWrapper(Cache redisCache) {
            Assert.notNull(redisCache, "delegate cache must not be null");
            this.delegate = redisCache;
        }

        @Override
        public String getName() {
            try {
                return delegate.getName();
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public Object getNativeCache() {
            try {
                return delegate.getNativeCache();
            } catch (Exception e) {
                return handleException(e);
            }
        }

        @Override
        public Cache.ValueWrapper get(Object key) {
            try {
                return delegate.get(key);
            } catch (Exception e) {
                return handleException(e);
            }
        }




        @Override
        public void put(Object key, Object value) {
            try {
                delegate.put(key, value);
            } catch (Exception e) {
                handleException(e);
            }
        }



        @Override
        public void evict(Object o) {
            try {
                delegate.evict(o);
            } catch (Exception e) {
                handleException(e);
            }
        }

        @Override
        public void clear() {
            try {
                delegate.clear();
            } catch (Exception e) {
                handleException(e);
            }
        }

        private  T handleException(Exception e) {
            logger.error("redis连接异常", e);
            return null;
        }
    }
}

redis 生成key 的规则代码!

在spring 里面,spring-session 和 spring-session-data-redis 结合让项目平滑升级与redis 缓存的一些运用_第1张图片  redis 的key 是随需要定义的

在spring 里面,spring-session 和 spring-session-data-redis 结合让项目平滑升级与redis 缓存的一些运用_第2张图片这个是springsession 自动生成 纪录每一个登录人信息

在spring 里面,spring-session 和 spring-session-data-redis 结合让项目平滑升级与redis 缓存的一些运用_第3张图片

redis存入缓存  key 得 和 配置里面的一样
在spring 里面,spring-session 和 spring-session-data-redis 结合让项目平滑升级与redis 缓存的一些运用_第4张图片

你可能感兴趣的:(redis,初入csdn)