ICAT技术 阅读:1987评论: 0 2018-08-21

jFinal整合eids集群,jFinal自带的redis插件只支持单机模式,不支持集群,我写了个支持集群模式的插件,并且支持密码的,原本集群不能设置密码,所以,需要先把集群创建完成,在去设置密码。需要重新创建集群,就先把密码取消,然后在创建集群,在设置密码。没错,设置密码就是这么蛋疼。

下面需要导入jedis的包

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

第一步:创建一个对集群操作的RedisCluster类

package com.icat.blog.redis;

import java.util.concurrent.ConcurrentHashMap;
import redis.clients.jedis.JedisCluster;
import com.jfinal.kit.StrKit;

public class RedisCluster {
	// 主集群缓存
	static JedisCluster mainCache = null;

	// 集群缓存集合
	private static final ConcurrentHashMap<String, JedisCluster> cacheMap = new ConcurrentHashMap<String, JedisCluster>();

	/**
	 * 插入新集群缓存
	 * 
	 * @param cacheName
	 *            集群缓存名称
	 * 
	 * @param cache
	 *            集群缓存
	 */
	public static void addCache(String cacheName, JedisCluster cache) {

		if (cache == null)
			throw new IllegalArgumentException("cache can not be null");
		if (cacheMap.containsKey(cacheName))
			throw new IllegalArgumentException("The cache name already exists");

		cacheMap.put(cacheName, cache);
		if (mainCache == null)
			mainCache = cache;

	}

	/**
	 * 
	 * 删除集群缓存
	 * 
	 * @param cacheName
	 *            集群缓存名称
	 * 
	 * @return JedisCluster
	 * 
	 */
	public static JedisCluster removeCache(String cacheName) {

		return cacheMap.remove(cacheName);

	}

	/**
	 * 提供一个设置设置主集群缓存 mainCache 的机会,否则第一个被初始化的 Cache 将成为 mainCache
	 */
	public static void setMainCache(String cacheName) {

		if (StrKit.isBlank(cacheName))
			throw new IllegalArgumentException("cacheName can not be blank");
		cacheName = cacheName.trim();
		JedisCluster cache = cacheMap.get(cacheName);
		if (cache == null)
			throw new IllegalArgumentException("the cache not exists: " + cacheName);

		RedisCluster.mainCache = cache;

	}

	/**
	 * 
	 * 使用主集群缓存
	 * 
	 * @return JedisCluster
	 */
	public static JedisCluster use() {
		return mainCache;
	}

	/**
	 * 
	 * 使用指定名称集群缓存
	 * 
	 * @param cacheName
	 *            集群缓存名称
	 * 
	 * @return JedisCluster
	 */
	public static JedisCluster use(String cacheName) {
		return cacheMap.get(cacheName);
	}

}

第二步:创建Redis集群插件类

package com.icat.blog.redis;
import java.io.IOException;
import java.util.Set;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.IPlugin;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
/**
 * redis集群插件
 * 
 * @ClassName: RedisClusterPlugin
 * @Description: TODO
 * @author icat
 * @date 2018年8月20日 下午2:21:49
 *
 */
public class RedisClusterPlugin implements IPlugin {
	// 集群名称
	String clusterName = null;

	// 集群对象
	JedisCluster jedisCluster = null;

	// 超时时间
	Integer timeout = null;

	// 连接池
	GenericObjectPoolConfig poolConfig = null;

	// 最多重定向次数
	Integer maxRedirections = null;

	// 用户密码
	String password = null;

	// 集群地址集合
	Set<HostAndPort> redisClusterNodes;

	/**
	 * 
	 * 传入集群信息
	 *
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes) {

		// 检查数据
		this.isRightHostAndPortSet(clusterName, redisClusterNodes);

		// 绑定集群名称
		this.clusterName = clusterName;

		// 绑定地址集合
		this.redisClusterNodes = redisClusterNodes;

	}

	/**
	 * 
	 * 传入集群信息
	 *
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param password
	 *            密码
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes, String password, int timeout,
			int maxRedirections, GenericObjectPoolConfig poolConfig) {

		// 检查数据
		this.isRightHostAndPortSet(clusterName, redisClusterNodes);
		this.timeout = timeout;
		this.maxRedirections = maxRedirections;
		this.poolConfig = poolConfig;
		// 绑定集群名称
		this.clusterName = clusterName;

		// 绑定密码
		this.password = password;

		// 绑定地址集合
		this.redisClusterNodes = redisClusterNodes;

	}

	/**
	 * 
	 * 传入集群信息
	 * 
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param timeout
	 *            超时时间
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes, Integer timeout) {

		// 复用传入集群方法
		this(clusterName, redisClusterNodes);

		// 超时时间绑定
		this.timeout = timeout;

	}

	/**
	 * 
	 * 传入集群信息
	 * 
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param poolConfig
	 *            连接池对象
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes,
			GenericObjectPoolConfig poolConfig) {

		// 复用传入集群方法
		this(clusterName, redisClusterNodes);

		// 连接池绑定
		this.poolConfig = poolConfig;

	}

	/**
	 * 
	 * 传入集群信息
	 * 
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param timeout
	 *            超时时间
	 * @param poolConfig
	 *            连接池配置
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes, Integer timeout,
			GenericObjectPoolConfig poolConfig) {

		// 复用传入集群方法
		this(clusterName, redisClusterNodes, timeout);

		// 连接池绑定
		this.poolConfig = poolConfig;

	}

	/**
	 * 
	 * 传入集群信息
	 * 
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param poolConfig
	 *            连接池对象
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes, Integer timeout,
			Integer maxRedirections) {

		// 复用传入集群方法
		this(clusterName, redisClusterNodes, timeout);

		// 连接池绑定
		this.maxRedirections = maxRedirections;

	}

	/**
	 * 
	 * 传入集群信息
	 * 
	 * @param clusterName
	 *            集群名称
	 * @param redisClusterNodes
	 *            集群地址集合
	 * @param poolConfig
	 *            连接池对象
	 * 
	 */
	public RedisClusterPlugin(String clusterName, Set<HostAndPort> redisClusterNodes, Integer timeout,
			Integer maxRedirections, GenericObjectPoolConfig poolConfig) {

		// 复用传入集群方法
		this(clusterName, redisClusterNodes, timeout, maxRedirections);

		// 连接池绑定
		this.poolConfig = poolConfig;

	}

	@Override
	public boolean start() {
		if (timeout != null && maxRedirections != null && poolConfig != null && password != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, timeout, timeout, maxRedirections, password, poolConfig);
		} else if (timeout != null && maxRedirections != null && poolConfig != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, timeout, maxRedirections, poolConfig);
		} else if (timeout != null && maxRedirections != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, timeout, maxRedirections);
		} else if (timeout != null && poolConfig != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, timeout, poolConfig);
		} else if (timeout != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, timeout);
		} else if (poolConfig != null) {
			jedisCluster = new JedisCluster(redisClusterNodes, poolConfig);
		} else {
			jedisCluster = new JedisCluster(redisClusterNodes);
		}
		// 加入集群集合
		RedisCluster.addCache(clusterName, jedisCluster);

		return true;
	}

	@Override
	public boolean stop() {

		// 清除出集群集合
		JedisCluster removeRedisCluster = RedisCluster.removeCache(clusterName);

		// 关闭集群链接
		try {
			removeRedisCluster.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;

	}

	// 判断传入的集群位置资料是否正确
	private void isRightHostAndPortSet(String clusterName, Set<HostAndPort> redisClusterNodes) {

		// 集群名称不能为空
		if (StrKit.isBlank(clusterName)) {
			throw new IllegalArgumentException("clusterName can not be blank.");
		}

		// 检查集群具体地址和端口号是否正常
		if (redisClusterNodes != null && redisClusterNodes.size() > 0) {
			for (HostAndPort hap : redisClusterNodes) {

				// 获取主机ip
				String host = hap.getHost();

				// 空字符串
				if (StrKit.isBlank(host)) {
					throw new IllegalArgumentException("host can not be blank.");
				}
			}
		} else {

			// 集群集合数据为空
			throw new IllegalArgumentException("redisClusterNodes can not be blank.");

		}

	}

}

第三步:在JFinal的AppConfig中添加Redis插件

public void configPlugin(Plugins me) {
	//配置集群节点
	Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
	jedisClusterNode.add(new HostAndPort("192.168.1.136", Integer.parseInt("7000")));
	jedisClusterNode.add(new HostAndPort("192.168.1.136", Integer.parseInt("7001")));
	jedisClusterNode.add(new HostAndPort("192.168.1.136", Integer.parseInt("7002")));
	jedisClusterNode.add(new HostAndPort("192.168.1.112", Integer.parseInt("7003")));
	jedisClusterNode.add(new HostAndPort("192.168.1.112", Integer.parseInt("7004")));
	jedisClusterNode.add(new HostAndPort("192.168.1.112", Integer.parseInt("7005")));
	//配置连接池,最大连接数等...
	GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
	poolConfig.setLifo(true);
	poolConfig.setBlockWhenExhausted(true);
	// 创建插件对象replicas
	//test 自定义的集合的名字  1212 密码 需要所有节点的密码一致  30000超时时间   6最多重定向次数
	RedisClusterPlugin redisClusterPlugin = new RedisClusterPlugin("test", jedisClusterNode, "1212", 30000, 6,
			poolConfig);
	me.add(redisClusterPlugin);
}

第四步:开始使用

//保存键为参数传过来的code
@ActionKey("/testsave")
public void testsave() {
    //这里的test是Appconfig中配置的那个test名字
    JedisCluster redis = RedisCluster.use("test");
    redis.set(getPara("code"), "1234");
    renderJson();
}

调用接口需要自己传入code参数

//查询参数为code的键的值
@ActionKey("/test")
public void test() {
    JedisCluster redis = RedisCluster.use("test");
    renderJson(redis.get(getPara("code")));
}

简单的Jfinal整合就做好了。以上集群插件类我是在网上找到的,博主只是二次封装了下。有问题,可以在下方留言,博主第一时间回复!

转载请注明来源:

评论