springboot整合redis-sentinel哨兵模式集群

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();
		}
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值