SpringBoot+redis clusterクラスタ構築
83584 ワード
SpringBoot+redis clusterクラスタ構築
前言:本文はもう一つのRedisクラスタポリシーとクラスタインスタンス(クラスタノードの追加、削除、再割り当てslot実戦)の博文に対して構築したJavaプロジェクトはredisクラスタの完全なプロセスの学習に用いられ、参考に供する.本明細書のコードはコードクラウドオープンソースプロジェクトに関する資料1を参照する.環境(1).springboot 2.0 (2).redis 4.0.10 2.関連コード1,pom.xmlファイル
二、プロファイルアプリケーション.properties
三、redisプロファイルredis.properties
三、フォルダredis構成を作成し、それに従ってredis初期化構成RedisConfiguration、JedisClusterFactoryファクトリクラス、カスタムキャッシュインタフェースICacheManager及びredisクライアント実装クラスJedisCacheManagerを作成する
(一)redis初期化構成RedisConfiguration
(二)JedisClusterFactory工場類
(三)カスタムキャッシュ操作インタフェースICacheManager
(四)redisクライアント実装クラスJedisCacheManager
(五)シーケンス化ツールクラス
(五)テストクラス
これでredisクラスタコードレベルが基本的に実現し、参考にして、ご指導を歓迎します!!!
前言:本文はもう一つのRedisクラスタポリシーとクラスタインスタンス(クラスタノードの追加、削除、再割り当てslot実戦)の博文に対して構築したJavaプロジェクトはredisクラスタの完全なプロセスの学習に用いられ、参考に供する.本明細書のコードはコードクラウドオープンソースプロジェクトに関する資料1を参照する.環境(1).springboot 2.0 (2).redis 4.0.10 2.関連コード1,pom.xmlファイル
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.4.RELEASE
spring.boot
demo
0.0.1-SNAPSHOT
jar
jpa
Demo project for Spring Boot
UTF-8
org.tdcg.Application
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
com.alibaba
druid
1.1.6
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
org.projectlombok
lombok
1.18.10
org.bgee.log4jdbc-log4j2
log4jdbc-log4j2-jdbc4.1
1.16
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-data-redis
io.lettuce
lettuce-core
redis.clients
jedis
com.alibaba
fastjson
1.2.31
org.springframework
spring-context
5.2.3.RELEASE
log4j
log4j
1.2.17
junit
junit
4.12
test
org.springframework.boot
spring-boot-maven-plugin
SpringBootJap
二、プロファイルアプリケーション.properties
#datasource#mysql #
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/study-jpa?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
# server
server.port: 8081
三、redisプロファイルredis.properties
# redis ip , “,” 。
spring.redis.cluster.nodes=192.168.0.108:8001,192.168.0.108:8002,192.168.0.108:8003,192.168.0.108:8004,192.168.0.108:8005,192.168.0.108:8006
# ( , )
#
spring.redis.cluster.timeout=5000
#
spring.redis.cluster.max-attempts=3
#
spring.redis.cluster.soTimeout=3000
spring.redis.cluster.max-redirects=3
三、フォルダredis構成を作成し、それに従ってredis初期化構成RedisConfiguration、JedisClusterFactoryファクトリクラス、カスタムキャッシュインタフェースICacheManager及びredisクライアント実装クラスJedisCacheManagerを作成する
(一)redis初期化構成RedisConfiguration
package spring.boot.jpa.redis;
import com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import java.util.Collections;
import java.util.Set;
/**
* @Title: RedisConfiguration
* @Description: redis
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
@Configuration
@PropertySource("classpath:redis.properties")
public class RedisConfiguration extends CachingConfigurerSupport {
@Bean(name = "jedisCluster")
public JedisClusterFactory jedisCluster(
@Value("${spring.redis.cluster.nodes}") String host,
@Value("${spring.redis.cluster.timeout}") int connectionTimeout,
@Value("${spring.redis.cluster.soTimeout}") int soTimeout) {
JedisClusterFactory jedisClusterFactory = new JedisClusterFactory();
jedisClusterFactory.setConnectionTimeout(connectionTimeout);
// jedisClusterFactory.setMaxRedirections(maxRedirections);
jedisClusterFactory.setSoTimeout(soTimeout);
String[] split = host.split(",");
Set<String> hosts = Sets.newHashSet();
Collections.addAll(hosts, split);
jedisClusterFactory.setJedisClusterNodes(hosts);
return jedisClusterFactory;
}
}
(二)JedisClusterFactory工場類
package spring.boot.jpa.redis;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Set;
/**
* @Title: JedisClusterFactory
* @Description:
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
public class JedisClusterFactory implements FactoryBean<JedisCluster>, InitializingBean {
private GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
private JedisCluster jedisCluster;
private int connectionTimeout = 2000;
private int soTimeout = 3000;
private int maxRedirections = 5;
private Set<String> jedisClusterNodes;
@Override
public void afterPropertiesSet() throws Exception {
if (jedisClusterNodes == null || jedisClusterNodes.size() == 0) {
throw new NullPointerException("jedisClusterNodes is null.");
}
Set<HostAndPort> haps = new HashSet<HostAndPort>();
for (String node : jedisClusterNodes) {
String[] arr = node.split(":");
if (arr.length != 2) {
throw new ParseException("node address error !",node.length()-1);
}
haps.add(new HostAndPort(arr[0], Integer.valueOf(arr[1])));
}
jedisCluster = new JedisCluster(haps, connectionTimeout, soTimeout, maxRedirections, genericObjectPoolConfig);
}
@Override
public JedisCluster getObject() throws Exception {
return jedisCluster;
}
@Override
public Class<?> getObjectType() {
return (this.jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class);
}
@Override
public boolean isSingleton() {
return true;
}
public GenericObjectPoolConfig getGenericObjectPoolConfig() {
return genericObjectPoolConfig;
}
public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) {
this.genericObjectPoolConfig = genericObjectPoolConfig;
}
public JedisCluster getJedisCluster() {
return jedisCluster;
}
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getSoTimeout() {
return soTimeout;
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
public int getMaxRedirections() {
return maxRedirections;
}
public void setMaxRedirections(int maxRedirections) {
this.maxRedirections = maxRedirections;
}
public Set<String> getJedisClusterNodes() {
return jedisClusterNodes;
}
public void setJedisClusterNodes(Set<String> jedisClusterNodes) {
this.jedisClusterNodes = jedisClusterNodes;
}
}
(三)カスタムキャッシュ操作インタフェースICacheManager
package spring.boot.jpa.redis;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @Title: ICacheManager
* @Description: ,
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
public interface ICacheManager {
/**
* key
*
* @param cacheKey
* @return
*/
public Object getCache(Serializable cacheKey);
/**
* key-value, ,
*
* @param cacheKey
* @param objValue
* @param expiration
* @return
*/
public boolean putCache(Serializable cacheKey, Object objValue, int expiration);
/**
*
*
* @param cacheKey
*/
public Long removeCache(Serializable cacheKey);
/**
* list , list
*
* @param cacheKey
* @param objValue
* @return
*/
public boolean putListCache(Serializable cacheKey, Object objValue);
/**
* list ,
*
* @param cacheKey
* @param objValue
* @param index
* @return
*/
public boolean putListCache(Serializable cacheKey, Object objValue, int index);
/**
* ,
*
* @param cacheKey
* @param start 0
* @param end -1
* @return
*/
public List<Object> getListCache(Serializable cacheKey, int start, int end);
/**
*
*
* @param cacheKey
* @return
*/
public List<Object> getListCache(Serializable cacheKey);
/**
* list
*
* @param cacheKey
* @param start
* @param end
* @return
*/
public boolean trimListCache(Serializable cacheKey, int start, int end);
/**
* map
*
* @param cacheKey
* @param map
* @return
*/
public boolean putMapCache(Serializable cacheKey, Map<Object, Object> map);
/**
* map
*
* @param cacheKey
* @param mapKey
* @return
*/
public boolean deleteMapCache(Serializable cacheKey, Serializable mapKey);
/**
* map
*
* @param cacheKey
* @param mapKey
* @return
*/
public Object getMapValueCache(Serializable cacheKey, Serializable mapKey);
}
(四)redisクライアント実装クラスJedisCacheManager
package spring.boot.jpa.redis.impl;
import com.alibaba.druid.util.StringUtils;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;
import spring.boot.jpa.redis.ICacheManager;
import spring.boot.jpa.redis.SerializingUtil;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* @Title: JedisCacheManager
* @Description:
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
@Service("iCacheManager")
public class JedisCacheManager implements ICacheManager {
private static final String JEDIS_SET_RETURN_OK = "OK";
@Resource
private JedisCluster jedisCluster;
@Override
public Object getCache(Serializable cacheKey) {
return SerializingUtil.deserialize((byte[]) jedisCluster.get(SerializingUtil.serialize(cacheKey)));
}
@Override
public boolean putCache(Serializable cacheKey, Object objValue, int expiration) {
String result = jedisCluster.setex(SerializingUtil.serialize(cacheKey), expiration, SerializingUtil.serialize(objValue));
if (StringUtils.equals(JEDIS_SET_RETURN_OK, result)) {
return true;
}
return false;
}
@Override
public Long removeCache(Serializable cacheKey) {
return jedisCluster.del(SerializingUtil.serialize(cacheKey));
}
@Override
public boolean putListCache(Serializable cacheKey, Object objValue) {
Long num = jedisCluster.rpush(SerializingUtil.serialize(cacheKey), SerializingUtil.serialize(objValue));
if (num > 0) {
return true;
}
return false;
}
@Override
public boolean putListCache(Serializable cacheKey, Object objValue, int index) {
String result = jedisCluster.lset(SerializingUtil.serialize(cacheKey), index, SerializingUtil.serialize(objValue));
if (StringUtils.equals(JEDIS_SET_RETURN_OK, result)) {
return true;
}
return false;
}
@Override
public List<Object> getListCache(Serializable cacheKey, int start, int end) {
List<byte[]> list = jedisCluster.lrange(SerializingUtil.serialize(cacheKey), start, end);
if (null != list && list.size() > 0) {
List<Object> objList = new ArrayList<Object>();
for (byte[] b : list) {
objList.add(SerializingUtil.deserialize(b));
}
return objList;
}
return null;
}
@Override
public List<Object> getListCache(Serializable cacheKey) {
return getListCache(cacheKey, 0, -1);
}
@Override
public boolean trimListCache(Serializable cacheKey, int start, int end) {
String result = jedisCluster.ltrim(SerializingUtil.serialize(cacheKey), start, end);
if (StringUtils.equals(JEDIS_SET_RETURN_OK, result)) {
return true;
}
return false;
}
@Override
public boolean putMapCache(Serializable cacheKey, Map<Object, Object> map) {
if (null != map && !map.isEmpty()) {
Map<byte[], byte[]> byteMap = new HashMap<byte[], byte[]>();
for (Entry<Object, Object> entry : map.entrySet()) {
byteMap.put(SerializingUtil.serialize(entry.getKey()), SerializingUtil.serialize(entry.getValue()));
}
String result = jedisCluster.hmset(SerializingUtil.serialize(cacheKey), byteMap);
if (StringUtils.equals(JEDIS_SET_RETURN_OK, result)) {
return true;
}
return true;
}
return false;
}
@Override
public boolean deleteMapCache(Serializable cacheKey, Serializable mapKey) {
Long result = jedisCluster.hdel(SerializingUtil.serialize(cacheKey), SerializingUtil.serialize(mapKey));
if (result > 0) {
return true;
}
return false;
}
@Override
public Object getMapValueCache(Serializable cacheKey, Serializable mapKey) {
List<byte[]> list = jedisCluster.hmget(SerializingUtil.serialize(cacheKey), SerializingUtil.serialize(mapKey));
if (null != list && list.size() > 0) {
return SerializingUtil.deserialize(list.get(0));
}
return null;
}
}
(五)シーケンス化ツールクラス
package spring.boot.jpa.redis;
import org.apache.log4j.Logger;
import org.springframework.cache.CacheManager;
import java.io.*;
/**
* @Title: SerializingUtil
* @Package: org.tdcg.util
* @Description: , byte[] Object .
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
public class SerializingUtil {
private static final Logger logger = Logger.getLogger(CacheManager.class);
/**
* : Bean .
*
* @param source
* @return
* @throws Exception
*/
public static byte[] serialize(Object source) {
ByteArrayOutputStream byteOut = null;
ObjectOutputStream ObjOut = null;
try {
byteOut = new ByteArrayOutputStream();
ObjOut = new ObjectOutputStream(byteOut);
ObjOut.writeObject(source);
ObjOut.flush();
} catch (IOException e) {
logger.error(source.getClass().getName() + " serialized error !", e);
} finally {
try {
if (null != ObjOut) {
ObjOut.close();
}
} catch (IOException e) {
ObjOut = null;
}
}
return byteOut.toByteArray();
}
/**
* : Bean.
*
* @param source
* @return Bean
* @throws Exception
*/
public static Object deserialize(byte[] source) {
ObjectInputStream ObjIn = null;
Object retVal = null;
try {
ByteArrayInputStream byteIn = new ByteArrayInputStream(source);
ObjIn = new ObjectInputStream(byteIn);
retVal = ObjIn.readObject();
} catch (Exception e) {
logger.error("deserialized error !", e);
} finally {
try {
if (null != ObjIn) {
ObjIn.close();
}
} catch (IOException e) {
ObjIn = null;
}
}
return retVal;
}
}
(五)テストクラス
package spring.boot.jpa;
import com.google.common.collect.Maps;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import spring.boot.jpa.entity.User;
import spring.boot.jpa.redis.impl.JedisCacheManager;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* @Title: JedisCacheManagerTest
* @Description: ,
* @FixMethodOrder(MethodSorters.NAME_ASCENDING)
* @Author: zyq
* @date: 2020/02/12
* @Version: V1.0
*/
//Junit4
@RunWith(SpringJUnit4ClassRunner.class)
// SpringBoot ( )
@SpringBootTest(classes={JpaApplication.class})//
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
// Web ,Junit ServletContext web
//@WebAppConfiguration
public class JedisCacheManagerTest {
private final int expiration = 3600;
@Resource
private JedisCacheManager jedisCacheManager;
@Test
public void testAPutCache() throws Exception {
boolean test = jedisCacheManager.putCache("test", "welocme redis cluster! created by tdcg!", expiration);
assert(test);
}
@Test
public void testBGetCache() throws Exception {
Object test = jedisCacheManager.getCache("test");
System.out.println(test);
assert(test.equals("welocme redis cluster! created by tdcg!"));
}
@Test
public void testCRemoveCache() throws Exception {
Long test = jedisCacheManager.removeCache("test");
assert(test == 1L);
}
}
これでredisクラスタコードレベルが基本的に実現し、参考にして、ご指導を歓迎します!!!