Commit 40fe6771 by tangzy

添加redis高可用机制

parent f9c83778
package org.sss.presentation.noui.redis;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.StringJoiner;
@Component("redisProperties")
@PropertySource({"classpath:redis.properties"})
public class RedisBalanceProperties implements Serializable {
@Value("${redis.ip1}")
private String ip1;
@Value("${redis.port1}")
private Integer port1;
@Value("${redis.passWord1}")
private String passWord1;
@Value("${redis.timeout1}")
private Integer timeout1;
@Value("${redis.ip2}")
private String ip2;
@Value("${redis.port2}")
private Integer port2;
@Value("${redis.passWord2}")
private String passWord2;
@Value("${redis.timeout2}")
private Integer timeout2;
@Value("${sessionTimeOut}")
private Integer sessionTimeOut;
@Value("${redis.encrypt.passwd}")
private Boolean encryptPasswd;
@Value("${redis.master.node}")
private String masterNode;
public RedisBalanceProperties() {
}
public String getIp1() {
return ip1;
}
public void setIp1(String ip1) {
this.ip1 = ip1;
}
public Integer getPort1() {
return port1;
}
public void setPort1(Integer port1) {
this.port1 = port1;
}
public String getPassWord1() {
return passWord1;
}
public void setPassWord1(String passWord1) {
this.passWord1 = passWord1;
}
public Integer getTimeout1() {
return timeout1;
}
public void setTimeout1(Integer timeout1) {
this.timeout1 = timeout1;
}
public String getIp2() {
return ip2;
}
public void setIp2(String ip2) {
this.ip2 = ip2;
}
public Integer getPort2() {
return port2;
}
public void setPort2(Integer port2) {
this.port2 = port2;
}
public String getPassWord2() {
return passWord2;
}
public void setPassWord2(String passWord2) {
this.passWord2 = passWord2;
}
public Integer getTimeout2() {
return timeout2;
}
public void setTimeout2(Integer timeout2) {
this.timeout2 = timeout2;
}
public Integer getSessionTimeOut() {
return sessionTimeOut;
}
public void setSessionTimeOut(Integer sessionTimeOut) {
this.sessionTimeOut = sessionTimeOut;
}
public Boolean getEncryptPasswd() {
return encryptPasswd;
}
public void setEncryptPasswd(Boolean encryptPasswd) {
this.encryptPasswd = encryptPasswd;
}
public String getMasterNode() {
return masterNode;
}
public void setMasterNode(String masterNode) {
this.masterNode = masterNode;
}
@Override
public String toString() {
return new StringJoiner(", ", RedisBalanceProperties.class.getSimpleName() + "[", "]")
.add("ip1='" + ip1 + "'")
.add("port1=" + port1)
.add("passWord1='" + passWord1 + "'")
.add("timeout1=" + timeout1)
.add("ip2='" + ip2 + "'")
.add("port2=" + port2)
.add("passWord2='" + passWord2 + "'")
.add("timeout2=" + timeout2)
.toString();
}
}
package org.sss.presentation.noui.redis;
import log.Log;
import log.LogFactory;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Service;
import org.sss.presentation.noui.common.Constants;
import org.sss.module.hibernate.HibernateUtils;
import org.sss.presentation.noui.jwt.RedisLoginInfo;
import org.sss.presentation.noui.util.RedisUtil;
@Service
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
protected static final Log log = LogFactory.getLog(RedisKeyExpirationListener.class);
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
//获取过期的key
String expireKey = message.toString();
log.debug("expireKey is:"+ expireKey);
if(expireKey.startsWith(Constants.SESSION)){
String[] arrayKey = expireKey.split("\\.");
if(arrayKey.length>2){
String userId = arrayKey[1];
Session session = HibernateUtils.openSession(null);
Transaction transaction = session.beginTransaction();
session.createSQLQuery("delete from lck where nam='"+userId+"'").executeUpdate();
transaction.commit();
session.close();
log.info("clear expire user "+userId+" session success");
}
}
}
}
...@@ -4,27 +4,73 @@ import log.Log; ...@@ -4,27 +4,73 @@ import log.Log;
import log.LogFactory; import log.LogFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
@Configuration @Configuration
public class RedisListenerConfig { public class RedisListenerConfig {
@Resource
private RedisBalanceProperties redisProperties;
@Resource
private StringRedisSerializer keySerializer;
@Resource
private GenericJackson2JsonRedisSerializer valueSerializer;
@Resource
private RedisStandaloneConfigurationExt1 redisStandaloneConfigurationExt1;
@Resource
private RedisStandaloneConfigurationExt2 redisStandaloneConfigurationExt2;
protected static final Log log = LogFactory.getLog(RedisListenerConfig.class); protected static final Log log = LogFactory.getLog(RedisListenerConfig.class);
@Bean @Bean("connectionFactory1")
RedisMessageListenerContainer listenerContainer(RedisConnectionFactory connectionFactory) { public JedisConnectionFactory connectionFactory1()
RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer(); {
listenerContainer.setConnectionFactory(connectionFactory); return new JedisConnectionFactory(redisStandaloneConfigurationExt1);
return listenerContainer;
} }
@Bean @Bean("connectionFactory2")
KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { public JedisConnectionFactory connectionFactory2()
log.debug("init redisKeyExpirationListener"); {
return new RedisKeyExpirationListener(listenerContainer); return new JedisConnectionFactory(redisStandaloneConfigurationExt2);
} }
@Bean("redisAPA")
public RedisTemplate redisAPA()
{
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory1());
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setValueSerializer(valueSerializer);
redisTemplate.setHashKeySerializer(keySerializer);
redisTemplate.setHashValueSerializer(valueSerializer);
return redisTemplate;
}
@Bean("redisAPB")
public RedisTemplate redisAPB()
{
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory2());
redisTemplate.setKeySerializer(keySerializer);
redisTemplate.setValueSerializer(valueSerializer);
redisTemplate.setHashKeySerializer(keySerializer);
redisTemplate.setHashValueSerializer(valueSerializer);
return redisTemplate;
}
@Bean("redisPassword")
public RedisPassword redisPassword()
{
return RedisPassword.of(redisProperties.getPassWord1());
}
} }
...@@ -4,46 +4,47 @@ import log.Log; ...@@ -4,46 +4,47 @@ import log.Log;
import log.LogFactory; import log.LogFactory;
import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder; import sun.misc.BASE64Decoder;
import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
@Service("redisStandaloneConfigurationExt1")
public class RedisStandaloneConfigurationExt1 extends RedisStandaloneConfiguration {
public class RedisStandaloneConfigurationExt extends RedisStandaloneConfiguration { protected static final Log log = LogFactory.getLog(RedisStandaloneConfigurationExt1.class);
protected static final Log log = LogFactory.getLog(RedisStandaloneConfigurationExt.class); @Resource
private RedisStandaloneConfiguration redisStandaloneConfiguration1;
private RedisStandaloneConfiguration redisStandaloneConfiguration; @Resource
private RedisPassword redisPassword;
public RedisStandaloneConfigurationExt(RedisStandaloneConfiguration redisStandaloneConfiguration){ @Resource
this.redisStandaloneConfiguration = redisStandaloneConfiguration; private RedisBalanceProperties redisProperties;
}
public RedisStandaloneConfiguration getRedisStandaloneConfiguration() {
return redisStandaloneConfiguration;
}
public void setRedisStandaloneConfiguration(RedisStandaloneConfiguration redisStandaloneConfiguration) {
this.redisStandaloneConfiguration = redisStandaloneConfiguration;
}
@Override @Override
public String getHostName() { public String getHostName() {
return redisStandaloneConfiguration.getHostName(); return redisStandaloneConfiguration1.getHostName();
} }
@Override @Override
public int getPort() { public int getPort() {
return redisStandaloneConfiguration.getPort(); return redisStandaloneConfiguration1.getPort();
} }
@Override @Override
public int getDatabase() { public int getDatabase() {
return redisStandaloneConfiguration.getDatabase(); return redisStandaloneConfiguration1.getDatabase();
} }
@Override @Override
public RedisPassword getPassword() { public RedisPassword getPassword() {
String miwen = String.valueOf(redisStandaloneConfiguration.getPassword().get()); if(Boolean.FALSE == redisProperties.getEncryptPasswd())
{
return RedisPassword.none();
}
String miwen = String.valueOf(redisPassword.get());
try { try {
String mingwen = new String(new BASE64Decoder().decodeBuffer(miwen), "utf-8"); String mingwen = new String(new BASE64Decoder().decodeBuffer(miwen), "utf-8");
return RedisPassword.of(mingwen); return RedisPassword.of(mingwen);
......
package org.sss.presentation.noui.redis;
import log.Log;
import log.LogFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;
import javax.annotation.Resource;
import java.io.IOException;
@Service("redisStandaloneConfigurationExt2")
public class RedisStandaloneConfigurationExt2 extends RedisStandaloneConfiguration {
protected static final Log log = LogFactory.getLog(RedisStandaloneConfigurationExt2.class);
@Resource
private RedisStandaloneConfiguration redisStandaloneConfiguration2;
@Resource
private RedisPassword redisPassword;
@Resource
private RedisBalanceProperties redisProperties;
@Override
public String getHostName() {
return redisStandaloneConfiguration2.getHostName();
}
@Override
public int getPort() {
return redisStandaloneConfiguration2.getPort();
}
@Override
public int getDatabase() {
return redisStandaloneConfiguration2.getDatabase();
}
@Override
public RedisPassword getPassword() {
if(Boolean.FALSE == redisProperties.getEncryptPasswd())
{
return RedisPassword.none();
}
String miwen = String.valueOf(redisPassword.get());
try {
String mingwen = new String(new BASE64Decoder().decodeBuffer(miwen), "utf-8");
return RedisPassword.of(mingwen);
} catch (IOException e) {
log.error("base64 解密 error",e);
}
return null;
}
}
package org.sss.presentation.noui.util; package org.sss.presentation.noui.util;
import java.util.Properties; import log.Log;
import log.LogFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.sss.presentation.noui.redis.RedisBalanceProperties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
/** /**
* Redis连接池工具类 * Redis连接池工具类
*/ */
public class RedisUtil { public class RedisUtil {
private static RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class); private static RedisTemplate redisAPA = SpringContextHolder.getBean("redisAPA");
private static RedisTemplate redisAPB = SpringContextHolder.getBean("redisAPB");
private static String redisConfigFile = "redis.properties"; private static RedisBalanceProperties redisProperties = SpringContextHolder.getBean("redisProperties");
private static String master = "redisAPA";
private static int sessionTimeOut = 1800; private static int sessionTimeOut = 1800;
protected static final Log log = LogFactory.getLog(RedisUtil.class);
static { static {
init(); sessionTimeOut = redisProperties.getSessionTimeOut();
master = redisProperties.getMasterNode();
} }
public static void setSessionTimeOut(int time){
public static void setSessionTimeOut(int time) {
sessionTimeOut = time; sessionTimeOut = time;
} }
...@@ -27,31 +35,77 @@ public class RedisUtil { ...@@ -27,31 +35,77 @@ public class RedisUtil {
return sessionTimeOut; return sessionTimeOut;
} }
private static void init() { public static String getMaster() {
return master;
}
public static void setMaster(String node) {
master = node;
}
public static RedisTemplate<String, Object> getRedisConnection() {
if (master.equals("redisAPA")) {
log.info("getRedisMaster redisAPA1");
if (getRedisMaster(redisAPA)) {
log.info("getRedisMaster redisAPA");
setMaster("redisAPA");
return redisAPA;
} else {
log.info("getRedisMaster redisAPB");
setMaster("redisAPB");
}
}
if (master.equals("redisAPB")) {
log.info("getRedisMaster redisAPB1");
if (getRedisMaster(redisAPB)) {
setMaster("redisAPB");
log.info("getRedisMaster redisAPB");
return redisAPB;
} else {
setMaster("redisAPA");
log.info("getRedisMaster redisAPA");
}
}
return null;
}
public static boolean getRedisMaster(RedisTemplate<String, Object> redisTemplate) {
try { try {
Properties props = new Properties(); redisTemplate.opsForValue().get("aa");
// 加载配置文件 return true;
props.load(RedisUtil.class.getClassLoader().getResourceAsStream(redisConfigFile)); } catch (Exception ex) {
sessionTimeOut = Integer.valueOf(props.getProperty("sessionTimeOut")); log.error(ex.getMessage());
} catch (Exception e) { return false;
e.printStackTrace();
} }
} }
public static void set(String key, Object value) { public static void checkRedisNodeAvailable() throws Exception {
redisTemplate.opsForValue().set(key,value); if (ObjectUtils.isEmpty(getRedisConnection())) {
redisTemplate.expire(key,sessionTimeOut, TimeUnit.SECONDS); throw new Exception("没有用redis节点可以用");
} }
}
public static void set(String key, Object value) throws Exception {
public static Object get(String key) { checkRedisNodeAvailable();
return redisTemplate.opsForValue().get(key); getRedisConnection().opsForValue().set(key, value);
getRedisConnection().expire(key, sessionTimeOut, TimeUnit.SECONDS);
} }
public static Boolean delete(String key){ public static Object get(String key) throws Exception {
return redisTemplate.delete(key); checkRedisNodeAvailable();
return getRedisConnection().opsForValue().get(key);
}
public static Boolean delete(String key) throws Exception {
checkRedisNodeAvailable();
return getRedisConnection().delete(key);
} }
public static Set keys(String key){ public static Set keys(String key) throws Exception {
return redisTemplate.keys(key+"*"); checkRedisNodeAvailable();
return getRedisConnection().keys(key + "*");
} }
} }
\ No newline at end of file
<beans xmlns="http://www.springframework.org/schema/beans" <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/context/spring-context-4.2.xsd">
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<bean id="annotationPropertyConfigurerRedis" <bean id="annotationPropertyConfigurerRedis"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
...@@ -23,40 +17,20 @@ ...@@ -23,40 +17,20 @@
</property> </property>
</bean> </bean>
<!--redis连接密码-->
<bean id="redisPassword" class="org.springframework.data.redis.connection.RedisPassword">
<constructor-arg name="thePassword" value="${redis.passWord}"></constructor-arg>
</bean>
<!--spring-data-redis2.0以上的配置--> <!--spring-data-redis2.0以上的配置-->
<bean id="redisStandaloneConfiguration" class="org.springframework.data.redis.connection.RedisStandaloneConfiguration"> <bean id="redisStandaloneConfiguration1" class="org.springframework.data.redis.connection.RedisStandaloneConfiguration">
<property name="hostName" value="${redis.ip}"/> <property name="hostName" value="${redis.ip1}"/>
<property name="port" value="${redis.port}"/> <property name="port" value="${redis.port1}"/>
<property name="password" ref="redisPassword" />
</bean>
<bean id="redisStandaloneConfigurationExt" class="org.sss.presentation.noui.redis.RedisStandaloneConfigurationExt">
<property name="redisStandaloneConfiguration" ref="redisStandaloneConfiguration"/>
</bean> </bean>
<bean id="redisStandaloneConfiguration2" class="org.springframework.data.redis.connection.RedisStandaloneConfiguration">
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.ip2}"/>
<constructor-arg name="standaloneConfig" ref="redisStandaloneConfigurationExt"></constructor-arg> <property name="port" value="${redis.port2}"/>
</bean> </bean>
<!--手动设置 key 与 value的序列化方式--> <!--手动设置 key 与 value的序列化方式-->
<bean id="keySerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean id="keySerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="valueSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> <bean id="valueSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
<!--配置jedis模板 -->
<bean id = "redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="keySerializer" ref="keySerializer" />
<property name="valueSerializer" ref="valueSerializer" />
<property name="hashKeySerializer" ref="keySerializer" />
<property name="hashValueSerializer" ref="valueSerializer" />
</bean>
<bean id="springContextHolder" class="org.sss.presentation.noui.util.SpringContextHolder" /> <bean id="springContextHolder" class="org.sss.presentation.noui.util.SpringContextHolder" />
<context:component-scan base-package="org.sss.presentation.noui.redis"></context:component-scan> <context:component-scan base-package="org.sss.presentation.noui.redis"></context:component-scan>
</beans> </beans>
\ No newline at end of file
#*****************jedis\u8FDE\u63A5\u53C2\u6570\u8BBE\u7F6E********************* #*****************jedis\u8FDE\u63A5\u53C2\u6570\u8BBE\u7F6E*********************
#redis\u670D\u52A1\u5668ip #redis\u670D\u52A1\u5668ip
redis.ip=172.17.2.110 redis.ip1=127.0.0.1
#redis\u670D\u52A1\u5668\u7AEF\u53E3\u53F7 #redis\u670D\u52A1\u5668\u7AEF\u53E3\u53F7
redis.port=6379 redis.port1=7480
#redis\u8BBF\u95EE\u5BC6\u7801 #redis\u8BBF\u95EE\u5BC6\u7801
redis.passWord= redis.passWord1=RVNGRWRsYzQ1Xg==
#\u4E0E\u670D\u52A1\u5668\u5EFA\u7ACB\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4 #\u4E0E\u670D\u52A1\u5668\u5EFA\u7ACB\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4
redis.timeout=3000 redis.timeout1=3000
#redis\u670D\u52A1\u5668ip
redis.ip2=127.0.0.1
#redis\u670D\u52A1\u5668\u7AEF\u53E3\u53F7
redis.port2=7481
#redis\u8BBF\u95EE\u5BC6\u7801
redis.passWord2=RVNGRWRsYzQ1Xg==
#\u4E0E\u670D\u52A1\u5668\u5EFA\u7ACB\u8FDE\u63A5\u7684\u8D85\u65F6\u65F6\u95F4
redis.timeout2=3000
redis.encrypt.passwd=true
redis.master.node=redisAPA
#************************jedis\u6C60\u53C2\u6570\u8BBE\u7F6E******************* #************************jedis\u6C60\u53C2\u6570\u8BBE\u7F6E*******************
#jedis\u7684\u6700\u5927\u6D3B\u8DC3\u8FDE\u63A5\u6570 #jedis\u7684\u6700\u5927\u6D3B\u8DC3\u8FDE\u63A5\u6570
jedis.pool.maxActive=100 jedis.pool.maxActive=100
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment