1. pom.xml 添加Redis依赖
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.application.properties 添加Redis配置
redis.cluster="192.168.74.142:7000,192.168.74.142:7001,192.168.74.142:7002,192.168.74.130:7003,192.168.74.130:7004,192.168.74.130:7005"#集群地址
redis.masterName="xxx"
redis.password="***"
3. 配置RedisSentinelConfig
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
@Configuration
public class RedisSentinelConfig {
@Value("${redis.cluster}")
private String nodesStr;
@Value("${redis.masterName}")
private String masterName;
private static final String COLON = ",";
private static final String COMMA=":";
@RefreshScope
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration(){
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
String[] host = nodesStr.split(COLON);
for (String redisHost : host) {
String[] item = redisHost.split(COMMA);
String ip = item[0];
String port = item[1];
configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
}
configuration.setMaster(masterName);
return configuration;
}
}
4.配置redis连接池JedisSentinelPoolConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class JedisSentinelPoolConfig {
@Bean
public JedisPoolConfig jedisSentinelPoolConfiggg() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//最大连接数,默认为8个
jedisPoolConfig.setMaxTotal(3);
//最大空闲连接数,默认为8个,控制一个pool最多有多少个状态为idle的jedis实例
jedisPoolConfig.setMaxIdle(1);
//JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
//jedisConnectionFactory.set
jedisPoolConfig.setMinIdle(0);
//表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
jedisPoolConfig.setMaxWaitMillis(2 * 1000L);
//连接耗尽时否阻塞,false报异常,true阻塞直到超时,默认为true
jedisPoolConfig.setBlockWhenExhausted(true);
//设置的逐出策略类名,默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数据超过最大空闲连接数)
jedisPoolConfig.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
//是否启用Pool的JMX管理功能,默认为true
jedisPoolConfig.setJmxEnabled(true);
//在borrow一个jedis实例时,是否提前进行validate操作,如果为true,则得到的jedis实例均是可用的;
//在获取连接的时候检查有效性, 默认false
jedisPoolConfig.setTestOnBorrow(true);
return jedisPoolConfig;
}
}
5.配置redis连接工厂jedisConnectionFactry
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class JedisSentinelConnectionFactory {
@Value("${redis.password}")
private String password;
@Bean
@RefreshScope
public JedisConnectionFactory jedisConnectionFactry(@Autowired RedisSentinelConfiguration configuration, @Autowired JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(configuration, jedisPoolConfig);
jedisConnectionFactory.setPassword(password);
return jedisConnectionFactory;
}
}
6.RedisTemplate配置类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisSentinelTemplate {
@Bean
@Autowired
public StringRedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
// key采用String的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
// valuevalue采用String序列化方式
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
7.redis操作类RedisCommand
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
@Service
public class RedisCommand {
@Autowired
StringRedisTemplate stringRedisTemplate;
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "callrecordscache",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_set",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
threadPoolKey = "redis", commandProperties = {
// 超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000") }, threadPoolProperties = {
// 调整coreSize(线程池并发度)
// 这个值的估算公式为 (最坏情况下时延的99th分位数(单位为秒) * 每秒的请求数)
// 比如这个方法的请求时延99th分位数为500ms,每秒有100次请求。0.5 * 100 = 50
@HystrixProperty(name = "coreSize", value = "50"),
// 调整maximumSize
// 这个值要比coreSize大。即使线程不够用超过了coreSize,也可以再“借”一些线程(总数不能超过maximumSize),但最终会还回去。
@HystrixProperty(name = "maximumSize", value = "100"),
@HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"),
// 调整maxQueueSize
// 在线程不够用时,可以采用排队的方式,因为排队增加了延时,所以此方式的副作用是会增加请求的延时。
@HystrixProperty(name = "maxQueueSize", value = "6"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "6") })
public void set(String groupName, String key, String value) throws Exception {
stringRedisTemplate.opsForHash().put(groupName, key, value);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "callrecordscache",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_setGroupName",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
threadPoolKey = "redis", commandProperties = {
// 超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000") }, threadPoolProperties = {
// 调整coreSize(线程池并发度)
// 这个值的估算公式为 (最坏情况下时延的99th分位数(单位为秒) * 每秒的请求数)
// 比如这个方法的请求时延99th分位数为500ms,每秒有100次请求。0.5 * 100 = 50
@HystrixProperty(name = "coreSize", value = "50"),
// 调整maximumSize
// 这个值要比coreSize大。即使线程不够用超过了coreSize,也可以再“借”一些线程(总数不能超过maximumSize),但最终会还回去。
@HystrixProperty(name = "maximumSize", value = "100"),
@HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"),
// 调整maxQueueSize
// 在线程不够用时,可以采用排队的方式,因为排队增加了延时,所以此方式的副作用是会增加请求的延时。
@HystrixProperty(name = "maxQueueSize", value = "6"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "6") })
public void setGroupName(String key, String groupName) {
stringRedisTemplate.opsForList().leftPush(key, groupName);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "callrecordscache",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_getGroupName",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
threadPoolKey = "redis", commandProperties = {
// 超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000") }, threadPoolProperties = {
// 调整coreSize(线程池并发度)
// 这个值的估算公式为 (最坏情况下时延的99th分位数(单位为秒) * 每秒的请求数)
// 比如这个方法的请求时延99th分位数为500ms,每秒有100次请求。0.5 * 100 = 50
@HystrixProperty(name = "coreSize", value = "50"),
// 调整maximumSize
// 这个值要比coreSize大。即使线程不够用超过了coreSize,也可以再“借”一些线程(总数不能超过maximumSize),但最终会还回去。
@HystrixProperty(name = "maximumSize", value = "100"),
@HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "true"),
// 调整maxQueueSize
// 在线程不够用时,可以采用排队的方式,因为排队增加了延时,所以此方式的副作用是会增加请求的延时。
@HystrixProperty(name = "maxQueueSize", value = "6"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "6") })
public List<String> getGroupName(String key) {
return stringRedisTemplate.opsForList().range(key, 0, -1);
}
}
7. 编写测试controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.unicom.microserv.cap.redis.RedisCommand;
@RestController
@RequestMapping("/test")
public class Test {
@Autowired
RedisCommand cahe;
@RequestMapping(value = "/", method = RequestMethod.POST)
public void test() {
try {
cahe.getGroupName("callrecord.groupname.11-201910141128");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}