参考文章:https://blog.csdn.net/justlpf/article/details/80350943
一. zuul微服务网关sring session配置
1.pom.xml文件配置
<!--增加spring session-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--增加redis的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.application.yml文件配置
2.1 redis单数据源配置
spring:
application:
name: zuul-srv #ServiceId, 配置服务命名,不区分大小写,在注册中心管理界面默认大写显示
redis:
host: 10.101.15.59 # Redis服务器地址
database: 8 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口, 默认6379
password: 123abc
timeout: 0ms # 连接超时时间(毫秒)
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
min-idle: 1 # 连接池中的最小空闲连接
max-idle: 1 # 连接池中的最大空闲连接
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
2.2 redis多数据源配置
redis:
host: 10.101.115.159
spring:
# ========================== redis配置 ========================== #
redis:
host: ${redis.host}
database: 8 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口, 默认6379
password: 123abc
timeout: 200ms # 连接超时时间(0毫秒), 生产环境下建议配置200ms以上
lettuce: # 线程安全 基于Netty连接 性能更优
shutdown-timeout: 200
pool:
max-active: 500 # 连接池最大连接数(使用负值表示没有限制)
min-idle: 1 # 连接池中的最小空闲连接
max-idle: 100 # 连接池中的最大空闲连接
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# 多数据源
redis2:
host: ${redis.host}
database: 3 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口, 默认6379
password: 123abc
timeout: 200ms # 连接超时时间(0毫秒), 生产环境下建议配置200ms以上
lettuce: # 线程安全 基于Netty连接 性能更优 old
shutdown-timeout: 200
pool:
max-active: 500 # 连接池最大连接数(使用负值表示没有限制)
min-idle: 1 # 连接池中的最小空闲连接
max-idle: 100 # 连接池中的最大空闲连接
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
BaseDataConfig:
package com.cloud.config.redis.datasource;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* @author langpf 2018/12/28
*/
public class BaseDataConfig {
RedisTemplate<String, String> redisTemplateSerializerConstructor(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jacksonSerial = getJackson2JsonRedisSerializer();
// 值采用json序列化
template.setValueSerializer(jacksonSerial);
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSerial);
template.afterPropertiesSet();
// template.setKeySerializer(new JdkSerializationRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
StringRedisTemplate stringRedisTemplateSerializerConstructor(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jacksonSerial = getJackson2JsonRedisSerializer();
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setValueSerializer(jacksonSerial); // 值采用json序列化
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSerial);
template.afterPropertiesSet();
return template;
}
private Jackson2JsonRedisSerializer getJackson2JsonRedisSerializer() {
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
return jacksonSeial;
}
RedisConnectionFactory getLettuceConnectionFactory(RedisProperties redisProperties) {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(redisProperties.getHost());
configuration.setPort(redisProperties.getPort());
configuration.setDatabase(redisProperties.getDatabase());
configuration.setPassword(RedisPassword.of(redisProperties.getPassword()));
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// commons-pool2 2.4.1, 修改 maxActive ==> maxTotal, maxWait ==> maxWaitMillis
poolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
poolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
poolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
LettuceClientConfiguration lettuceClientConfiguration = applyProperties(redisProperties, poolConfig);
LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration, lettuceClientConfiguration);
factory.setValidateConnection(true);
return factory;
}
private LettuceClientConfiguration applyProperties(RedisProperties redisProperties, GenericObjectPoolConfig poolConfig) {
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = LettucePoolingClientConfiguration
.builder()
.poolConfig(poolConfig)
.shutdownTimeout(Duration.ZERO);
if (redisProperties.isSsl()) {
builder.useSsl();
}
if (redisProperties.getTimeout() != null) {
builder.commandTimeout(redisProperties.getTimeout());
}
if (redisProperties.getLettuce() != null) {
RedisProperties.Lettuce lettuce = redisProperties.getLettuce();
if (lettuce.getShutdownTimeout() != null && !lettuce.getShutdownTimeout().isZero()) {
builder.shutdownTimeout(redisProperties.getLettuce().getShutdownTimeout());
}
}
return builder.build();
}
}
数据源一:
由于存在多个 RedisConnectionFactory beans 必须,因此必须在一个factory上设置 @Primary注解
package com.cloud.config.redis.datasource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* postgresql data source config
*
* @author langpf
* /12/5
*/
@Configuration
public class RedisDataSource extends BaseDataConfig {
@Bean(name = "redisTemplate")
public RedisTemplate<String, String> redisTemplate2(@Qualifier("lettuceConnectionFactory")
RedisConnectionFactory redisConnectionFactory) {
return redisTemplateSerializerConstructor(redisConnectionFactory);
}
@Bean(name = "stringRedisTemplate")
public StringRedisTemplate stringRedisTemplate2(
@Qualifier("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
return stringRedisTemplateSerializerConstructor(redisConnectionFactory);
}
@Primary // 为了配合spring session的使用
@Bean(name = "lettuceConnectionFactory")
public RedisConnectionFactory lettuceConnectionFactory(@Qualifier("redisProperties") RedisProperties redisProperties) {
return getLettuceConnectionFactory(redisProperties);
}
@Primary
@Bean(name = "redisProperties")
@ConfigurationProperties(prefix = "spring.redis")
public RedisProperties myRedisProperties() {
return new RedisProperties();
}
}
数据源二:
package com.cloud.config.redis.datasource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* @author langpf 2018/12/25
*/
@Configuration
public class RedisDataSource2 extends BaseDataConfig {
@Bean(name = "redisTemplate2")
public RedisTemplate<String, String> redisTemplate2(@Qualifier("lettuceConnectionFactory2")
RedisConnectionFactory redisConnectionFactory) {
return redisTemplateSerializerConstructor(redisConnectionFactory);
}
@Bean(name = "stringRedisTemplate2")
public StringRedisTemplate stringRedisTemplate2(
@Qualifier("lettuceConnectionFactory2")RedisConnectionFactory redisConnectionFactory) {
return stringRedisTemplateSerializerConstructor(redisConnectionFactory);
}
@Bean(name = "lettuceConnectionFactory2")
public RedisConnectionFactory lettuceConnectionFactory2(@Qualifier("redisProperties2") RedisProperties redisProperties) {
return getLettuceConnectionFactory(redisProperties);
}
@Bean(name = "redisProperties2")
@ConfigurationProperties(prefix = "spring.redis2")
public RedisProperties myRedisProperties() {
return new RedisProperties();
}
}
3.configure文件配置
除非像下面一样需要个性化设置,否则不必添加下面的配置
package com.cloud.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
/**
* @author fiend 2018/12/20
*/
@Configuration
// @EnableRedisHttpSession // 开启spring session支持
@EnableRedisHttpSession( // 开启spring session支持
maxInactiveIntervalInSeconds = Constants.SESSION_TIMOUT, // session过期时间配置
// redis session刷新模式。
// 配置为RedisFlushMode.IMMEDIATE,可以确保zuul存储到redis的session对象在请求到micro service中能立即被获取
redisFlushMode = RedisFlushMode.IMMEDIATE
)
public class RedisSessionConfig {
}
4.controller文件
package com.cloud.controller;
import com.cloud.service.ZuulSrvService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author Administrator 2018/10/29
*/
@RestController
@RequestMapping(value = "zuulsrv")
public class ZuulSrvController {
@Autowired
ZuulSrvService zuulSrvService;
/***
* session共享测试
*/
@RequestMapping("/testSessionId")
@ResponseBody
public Map<String, Object> testSessionId(HttpServletRequest request) {
Map<String, Object> map = zuulSrvService.testSessionId();
// 获取sessionId
String strSessionId = request.getSession().getId();
int iPort = request.getServerPort();
map.put("zuul服务器端口:", iPort);
map.put("zuul sessionId:", strSessionId);
return map;
}
}