Java客户端Sentinel的配置

发表时间:2018-03-16 15:52:35 浏览量( 28 ) 留言数( 0 )

学习目标:

1、了解Sentine机制的原理

2、掌握Sentine的搭建


学习过程:

一、直接使用JRedis的实现Sentine

   其实直接使用,感觉比使用Spring整合的方式还要简单一点,我们只需要连接Sentine的配置信息就可以了,代码如下。在运行下面的代码是你可以尝试一下把其中一个redis服务器停了。代码如下;

/**
 * 不适用spring集成
 * @author liubao
 * dddd
 */
public class JedisSentinelTest {
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub

		Set<String> sentinels = new HashSet<String>();
		sentinels.add("192.168.8.234:26379");
		sentinels.add("192.168.8.235:26379");
		sentinels.add("192.168.8.236:26379");

		JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels);
		Jedis jedis = null;
        int i=0;
		while (true) {
			Thread.sleep(1000);
            i++;
			try {
				jedis = jedisSentinelPool.getResource();

				Date now = new Date();
				SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
				String format_now = dateFormat.format(now);

				jedis.set("hello"+i, "world"+i);
				String value = jedis.get("hello"+i);
				System.out.println(format_now + ' ' + value);

			} catch (Exception e) {
				System.out.println(e);
			} finally {
				if (jedis != null)
					try {
						jedis.close();
					} catch (Exception e) {
						System.out.println(e);
					}
			}
		}

	}
}


二、整合Spring

1、redis.properties配置文件

#访问地址   使用sentinel后,这个就不需要了。
#redis.host=192.168.8.234
#访问端口  
#redis.port=6379  
#注意,如果没有password,此处不设置值,但这一项要保留  
#redis.password=  
  
#最大闲置连接数  
redis.maxIdle=500  
#最大连接数,超过此连接时操作redis会报错  
redis.maxTotal=5000  
redis.maxWaitTime=1000  
redis.testOnBorrow=true  
#最小闲置连接数,spring启动的时候自动建立该数目的连接供应用程序使用,不够的时候会申请。  
redis.minIdle=300    
  
# Redis settings  
#sentinel1的IP和端口  
redis.sentinel1.host=192.168.8.234
redis.sentinel1.port=26379
#sentinel2的IP和端口  
redis.sentinel2.host=192.168.8.235
redis.sentinel2.port=26379
#sentinel3的IP和端口  
redis.sentinel3.host=192.168.8.236
redis.sentinel3.port=26379

#sentinel的鉴权密码  
redis.sentinel.masterName=mymaster
redis.sentinel.password=

2、redisContext.xml配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd     http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- scanner redis properties -->
	<context:property-placeholder location="classpath:redis.properties"
		ignore-unresolvable="true" />

	 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
        <property name="maxTotal" value="${redis.maxTotal}" />  
        <property name="minIdle" value="${redis.minIdle}" />  
        <property name="maxWaitMillis" value="${redis.maxWaitTime}" />  
        <property name="maxIdle" value="${redis.maxIdle}" />  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
        <property name="testOnReturn" value="true" />  
        <property name="testWhileIdle" value="true" />  
    </bean>  
  
    <bean id="sentinelConfiguration"  
        class="org.springframework.data.redis.connection.RedisSentinelConfiguration">  
        <property name="master">  
            <bean class="org.springframework.data.redis.connection.RedisNode">  
                <property name="name" value="${redis.sentinel.masterName}"></property>  
            </bean>  
        </property>  
        <property name="sentinels">  
            <set>  
                <bean class="org.springframework.data.redis.connection.RedisNode">  
                    <constructor-arg name="host"  
                        value="${redis.sentinel1.host}"></constructor-arg>  
                    <constructor-arg name="port"  
                        value="${redis.sentinel1.port}"></constructor-arg>  
                </bean>  
                <bean class="org.springframework.data.redis.connection.RedisNode">  
                    <constructor-arg name="host"  
                        value="${redis.sentinel2.host}"></constructor-arg>  
                    <constructor-arg name="port"  
                        value="${redis.sentinel2.port}"></constructor-arg>  
                </bean> 
                <bean class="org.springframework.data.redis.connection.RedisNode">  
                    <constructor-arg name="host"  
                        value="${redis.sentinel3.host}"></constructor-arg>  
                    <constructor-arg name="port"  
                        value="${redis.sentinel3.port}"></constructor-arg>  
                </bean>   
            </set>  
        </property>  
    </bean>  
  
    <bean id="connectionFactory"  
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:password="${redis.sentinel.password}">  
        <constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg>  
        <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>  
    </bean>  
  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
        <property name="connectionFactory" ref="connectionFactory" />  
    </bean>  
</beans>

3、测试类

@RunWith(SpringJUnit4ClassRunner.class) // 

@ContextConfiguration(locations = { "classpath:applicationContext.xml" }) // 

public class RedisTest {

@Resource(name = "redisTemplate")

private RedisTemplate  template;

@Test  

    public void testSpringRedis() {  

template.opsForValue().set("spring", "springredissentinel");

}

@Test  

    public void testgetRedis() {  

String temp=(String) template.opsForValue().get("spring");

System.out.println(temp);

}

}


三、使用Spring Boot整合

Spring Boot非常容易使用

1、修改application.properteis

spring.redis.pool.max-idle=8    
spring.redis.pool.min-idle=0    
spring.redis.pool.max-active=8    
spring.redis.pool.max-wait=-1   
  
#哨兵监听redis server名称  
spring.redis.sentinel.master=mymaster
#哨兵的配置列表  
spring.redis.sentinel.nodes=192.168.8.234:26379,192.168.8.235:26379,192.168.8.236:26379

2、导入相关的包。修改pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>

3、类封装

@Service
public class RedisService {
	@Autowired // 操作字符串的template,StringRedisTemplate是RedisTemplate的一个子集
	private StringRedisTemplate stringRedisTemplate;

	@Autowired // RedisTemplate,可以进行所有的操作
	private RedisTemplate<Object, Object> redisTemplate;

	public void set(String key, String value) {
		stringRedisTemplate.opsForValue().set(key, value);
	}


	public String get(String key) {
		return stringRedisTemplate.opsForValue().get(key);
	}

}


4、测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringfirstApplicationTests {

	@Autowired
	private RedisService service;

	@Test
	public void testResis() {
		service.set("name", "liubaospringboot");

		String name = service.get("name");
		System.out.println("name:" + name);

	}

}


几乎不用写什么代码,直接使用就可以了。


   Redis的HA(高可用性)我们就讲到这里,但是也留下了一些问题,就是高可用性和分片如何一起使用呢?在官方的JRedis居然没有好的解决方案。也就是说主从模式下,通过哨兵配置,单个集群数据无法分片(备复制->主的数据,备无写权限),然然我们可以使用Redis Cluster,它是Redis的集群实现,内置数据自动分片机制和主备模式。而且客户端的支持也非常好。

   当然如果你就是要配置sentinel和ShardedJedisPool结合使用。也就是结合分片的技术,同事每一个分片又是主从模式,也有一些第三方的人写了一些插件。可以参考一下下面的开源项目

https://github.com/warmbreeze/sharded-jedis-sentinel-pool