zoukankan      html  css  js  c++  java
  • Redis Sentinel Plugin For JFinal

    我先在开发本地搭Redis主从服务器,各自在redis.windows.conf中进行配置。

    主服务器:192.168.6.88:6379 开启requirepass 服务器密码,masterauth 服务器密码,maxmemory 209715200,maxheap 314572800

    从服务器:192.168.6.88:6380 开启requirepass 服务器密码,masterauth 服务器密码,maxmemory 209715200,maxheap 314572800

    从服务器比主服务器多一行配置:slaveof 192.168.6.88 6379。

    分别启动redis-server redis.windows.conf,启动成功。

    可以通过info Replication命令查看一下主从服务连接状态

    如果在使用中如下报错信息:BeginForkOperation: system error caught. error code=0x000005af 。是maxmemory和maxheap没有设置的原因。可以在启动参数中加入,也可以如上在配置文件中配置。

    好了,接下来该Redis sentinel上场了。先要作成sentinel.conf文件

    启动master-sentinel

    下面开始对JFinal开始扩展。

    1、作成RedisSentinelPlugin。代码见http://www.oschina.net/code/snippet_2621890_57963

    2、com.jfinal.plugin.redis.Cache中的JedisPool类型修正为Pool<Jedis>

    3、启动时配置插件

    			String redisIp = getProperty(ConstantInit.config_redis_ip);
    			Integer redisPort = getPropertyToInt(ConstantInit.config_redis_port);
    			String redisPassword = getProperty(ConstantInit.config_redis_password);
    			Set<HostAndPort> sentinels = new HashSet<HostAndPort>();
    			HostAndPort hostAndP = new HostAndPort(redisIp, redisPort);			
    			sentinels.add(hostAndP);
    			RedisSentinelPlugin redisSentinelPlugin = new RedisSentinelPlugin(ConstantCache.cache_name_redis_system, "mymaster",sentinels,redisPassword);		
    			plugins.add(redisSentinelPlugin);

    然后开始测试:关闭master。发现slave自动转为master。同时系统依旧可用。启动旧master,旧master成为新master的slave。

    至此开发环境中完成,可尝试在生产环境中配置多台slave和多台sentinel。

    附注:插件的代码:

    package com.jfinal.plugin.redis;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.JedisSentinelPool;
    import redis.clients.jedis.Protocol;
    
    import com.jfinal.kit.StrKit;
    import com.jfinal.plugin.IPlugin;
    import com.jfinal.plugin.redis.serializer.FstSerializer;
    import com.jfinal.plugin.redis.serializer.ISerializer;
    
    public class RedisSentinelPlugin implements IPlugin {
    
    	private String cacheName;
    
    	private String masterName = null;
    	private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
    	//下一jedis版本预留字段
    	//private int soTimeout = Protocol.DEFAULT_TIMEOUT;
    	private String password = null;
    	private int database = Protocol.DEFAULT_DATABASE;
    	//下一jedis版本预留字段
    	//private String clientName = null;
    	private Set<String> sentinels = new HashSet<String>();
    
    	private ISerializer serializer;
    	private IKeyNamingPolicy keyNamingPolicy;
    	private GenericObjectPoolConfig poolConfig;
    	
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig) {
    		this(cacheName, masterName, sentinels, poolConfig,
    				Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels) {
    		this(cacheName, masterName, sentinels, new GenericObjectPoolConfig(),
    				Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, String password) {
    		this(cacheName, masterName, sentinels, new GenericObjectPoolConfig(),
    				Protocol.DEFAULT_TIMEOUT, password);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			int timeout, final String password) {
    		this(cacheName, masterName, sentinels, poolConfig, timeout, password,
    				Protocol.DEFAULT_DATABASE);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			final int timeout) {
    		this(cacheName, masterName, sentinels, poolConfig, timeout, null,
    				Protocol.DEFAULT_DATABASE);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			final String password) {
    		this(cacheName, masterName, sentinels, poolConfig,
    				Protocol.DEFAULT_TIMEOUT, password);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			int timeout, final String password, final int database) {
    		this(cacheName, masterName, sentinels, poolConfig, timeout, timeout,
    				password, database);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			int timeout, final String password, final int database,
    			final String clientName) {
    		this(cacheName, masterName, sentinels, poolConfig, timeout, timeout,
    				password, database, clientName);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			final int timeout, final int soTimeout, final String password,
    			final int database) {
    		this(cacheName, masterName, sentinels, poolConfig, timeout, soTimeout,
    				password, database, null);
    	}
    
    	public RedisSentinelPlugin(String cacheName, String masterName,
    			Set<HostAndPort> sentinels, final GenericObjectPoolConfig poolConfig,
    			final int connectionTimeout, final int soTimeout,
    			final String password, final int database, final String clientName) {
    		if (StrKit.isBlank(cacheName))
    			throw new IllegalArgumentException("cacheName can not be blank.");
    		if (StrKit.isBlank(masterName))
    			throw new IllegalArgumentException("masterName can not be blank.");
    		if (null == sentinels || sentinels.isEmpty())
    			throw new IllegalArgumentException("sentinels can not be blank.");
    		if (null == poolConfig)
    			throw new IllegalArgumentException("poolConfig can not be null.");
    		for(HostAndPort hp : sentinels)
    		{
    			this.sentinels.add(hp.toString());
    		}
    		this.cacheName = cacheName.trim();
    		this.masterName = masterName.trim();
    		this.poolConfig = poolConfig;
    		this.connectionTimeout = connectionTimeout;
    		//this.soTimeout = soTimeout;
    		this.password = password;
    		this.database = database;
    		//this.clientName = clientName;
    
    	}
    
    	public boolean start() {
    		JedisSentinelPool jedisSentinelPool =new JedisSentinelPool(masterName, sentinels,
    			      poolConfig, connectionTimeout, password, database);
    		if (serializer == null)
    			serializer = FstSerializer.me;
    		if (keyNamingPolicy == null)
    			keyNamingPolicy = IKeyNamingPolicy.defaultKeyNamingPolicy;
    
    		Cache cache = new Cache(cacheName, jedisSentinelPool, serializer,
    				keyNamingPolicy);
    		Redis.addCache(cache);
    		return true;
    	}
    
    	public boolean stop() {
    		Cache cache = Redis.removeCache(cacheName);
    		if (cache == Redis.mainCache)
    			Redis.mainCache = null;
    		cache.jedisPool.destroy();
    		return true;
    	}
    
    	/**
    	 * 当RedisSentinelPlugin 提供的设置属性仍然无法满足需求时,通过此方法获取到 JedisPoolConfig 对象,可对 redis
    	 * 进行更加细致的配置
    	 * 
    	 * <pre>
    	 * 例如:
    	 * redisSentinelPlugin.getJedisPoolConfig().setMaxTotal(100);
    	 * </pre>
    	 */
    	public GenericObjectPoolConfig getGenericObjectPoolConfig() {
    		return poolConfig;
    	}
    
    	// ---------
    
    	public void setSerializer(ISerializer serializer) {
    		this.serializer = serializer;
    	}
    
    	public void setKeyNamingPolicy(IKeyNamingPolicy keyNamingPolicy) {
    		this.keyNamingPolicy = keyNamingPolicy;
    	}
    
    	// ---------
    
    	public void setTestWhileIdle(boolean testWhileIdle) {
    		poolConfig.setTestWhileIdle(testWhileIdle);
    	}
    
    	public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
    		poolConfig
    				.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    	}
    
    	public void setTimeBetweenEvictionRunsMillis(
    			int timeBetweenEvictionRunsMillis) {
    		poolConfig
    				.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    	}
    
    	public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
    		poolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
    	}
    
    	//提供懒初始化初始数据库,避免太多构造器
    	public void setDatabase(int database) {
    		this.database = database;
    	}
    	
    	
    	
    
    }
  • 相关阅读:
    基于阈值的图像分割
    boost_1_45_0安装
    分类后评价精度的几个因子的概念
    数字图像去噪典型算法及matlab实现
    返回数值类型
    C标准库之assert
    区域增长
    OTB Chapter 1
    win7下,如何在odbc数据源中添加access驱动的问题
    c语言文件操作模式大全
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13317493.html
Copyright © 2011-2022 走看看