1. 添加依赖
org.springframework.boot
spring-boot-starter-data-redis
2. 配置application.properties文件
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"#集群地址
3. 配置RedisCluster
import java.util.ArrayList;
import java.util.Collection;
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.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class RedisClusterConfig {
@Value("${redis.cluster}")
String cap_cache;
@RefreshScope // 使用了分布式配置中心中的配置,加此注解可以在不重启的情况下更新配置信息
@Bean
public RedisConnectionFactory connectionFactory() {
Collection redisNodes = new ArrayList<>();
JedisConnectionFactory jedisConnectionFactory = null;
try {
if (null == cap_cache || "".equals(cap_cache)) {
// 没有redis节点信息。
return null;
}
for (String hostAndPort : cap_cache.split(",")) {
String[] detail = hostAndPort.split(":");
redisNodes.add(new RedisNode(detail[0], Integer.parseInt(detail[1])));
}
/**
* 配置redis集群信息
*/
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
redisClusterConfiguration.setClusterNodes(redisNodes);
redisClusterConfiguration.setMaxRedirects(3);
System.out.println(redisClusterConfiguration.getClusterNodes());
/**
* 配置jedis链接池信息
*/
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大连接数,默认为8个
jedisPoolConfig.setMaxTotal(3);
// 最大空闲连接数,默认为8个,控制一个pool最多有多少个状态为idle的jedis实例
jedisPoolConfig.setMaxIdle(1);
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);
/**
* 集群配置信息、jedis链接池配置信息 来 实例化jedis链接池
*/
jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
} catch (Exception e) {
return null;
}
return jedisConnectionFactory;
}
@Bean
public StringRedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
public String getNodes() {
return cap_cache;
}
public void setNodes(String nodes) {
this.cap_cache = nodes;
}
}
4.对RedisCluster操作
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class RedisCommand {
@Autowired
StringRedisTemplate stringRedisTemplate;
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "spmsconfirmnotify",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_get",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
threadPoolKey = "redis_get", commandProperties = {
// 超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "200") }, 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 String get(String key) throws Exception {
return stringRedisTemplate.opsForValue().get(key);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "spmsconfirmnotify",
// 所调用的服务名
// 依赖隔离:每个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 key, String value, int expireSeconds) throws Exception {
stringRedisTemplate.opsForValue().set(key, value, expireSeconds, TimeUnit.SECONDS);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "spmsconfirmnotify",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_expire",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用HystrixThreadPoolKey区分。
threadPoolKey = "redis", commandProperties = {
// 超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "200") }, 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 boolean expire(String key, int expireSeconds) throws Exception {
return stringRedisTemplate.expire(key, expireSeconds, TimeUnit.SECONDS);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "allrecordscache",
// 所调用的服务名
// 依赖隔离:每个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 = "callrecordsfile",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_get",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用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 String getGroupName(String key) {
return stringRedisTemplate.opsForList().rightPop(key);
}
@HystrixCommand(
// 最少配置的必选参数,统一为工程名。在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
groupKey = "callrecordsfile",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "redis_getGroupNameOver",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用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 getGroupNameOver(String key) {
return stringRedisTemplate.opsForList().range(key, 0, -1);
}
@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 = "callrecordsfile",
// 所调用的服务名
// 依赖隔离:每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。
commandKey = "deleteGroupName",
// 资源隔离:虽然在业务上都是相同的组,但是需要在资源上做隔离时,可以使用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 deleteGroupName(String key) {
stringRedisTemplate.delete(key);
}
}
5. 编写测试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.deleteGroupName("callrecord.groupname.11-201910141128");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}