1.先来一个单机版redis使用连接池操作redis队列
@Test
public void testJedisPool()throws Exception {
// 第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。
JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
// 第二步:从JedisPool中获得Jedis对象。
Jedis jedis = jedisPool.getResource();
// 第三步:使用Jedis操作redis队列,左推右取,阻塞队列
jedis.lpush(key,value); //左推
String result = jedis.brpop(time,key); //右取,time表示超时时间,设置成0表示一直阻塞,直到队列中数据取完
System.out.println(result);
// 第四步:操作完毕后关闭jedis对象,连接池回收资源。
jedis.close();
// 第五步:关闭JedisPool对象。
jedisPool.close();
}
2.spring集成jedisCluster,异步阻塞队列
(1)redis-config.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 连接池基本参数配置,类似数据库连接池 --> <!-- redis连接池 --> <bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxActive}"/> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="minIdle" value="${redis.minIdle}" /> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <!-- jedis集群版配置 --> <bean id="hostport1" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host1}"/> <constructor-arg name="port" value="${redis.port1}"/> </bean> <bean id="hostport2" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host1}"/> <constructor-arg name="port" value="${redis.port2}"/> </bean> <bean id="hostport3" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host2}"/> <constructor-arg name="port" value="${redis.port1}"/> </bean> <bean id="hostport4" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host2}"/> <constructor-arg name="port" value="${redis.port2}"/> </bean> <bean id="hostport5" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host3}"/> <constructor-arg name="port" value="${redis.port1}"/> </bean> <bean id="hostport6" class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="${redis.host3}"/> <constructor-arg name="port" value="${redis.port2}"/> </bean> <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster"> <constructor-arg name="jedisClusterNode"> <set> <ref bean="hostport1"/> <ref bean="hostport2"/> <ref bean="hostport3"/> <ref bean="hostport4"/> <ref bean="hostport5"/> <ref bean="hostport6"/> </set> </constructor-arg> <constructor-arg name="connectionTimeout" value="${redis.connectionTimeout}"/> <constructor-arg name="soTimeout" value="${redis.soTimeout}"/> <constructor-arg name="maxAttempts" value="${redis.maxAttempts}"/> <constructor-arg name="password" value="${redis.password}"/> <constructor-arg name="poolConfig" > <ref bean="jedisConfig"/> </constructor-arg> </bean> </beans>
(2)将redis-config.xml注入spring 核心配置文件 applicationContext.xml中,交给spring容器管理
(3)在实现类中注入jedisCluster对象
@Service public class A0010032ServiceImpl implements IA0010032Service { private Logger LOGGER = Logger.getLogger(A0010032ServiceImpl.class); //指定redis队列的key值 private static final String key = "redis_orbit_test"; //注入redis集群操作模板对象 @Autowired JedisCluster jedisCluster;
//将json格式转换成字符串入队列 String str = json.toString(); //使用左推右取,将数据推入redis队列中 Long lpush = jedisCluster.lpush(key, str); //获得的lpush是当前队列list的长度 if (lpush<=0){ throw new Exception("数据存入redis队列异常"); } //开启异步线程,从队列中取出数据,使用brpop阻塞队列,并存入ES中去 brpopRedisToEs();
//开启异步线程 private void brpopRedisToEs(){ brpopRedisThread thread = new brpopRedisThread(); thread.start(); } //定义异步线程 private class brpopRedisThread extends Thread{ private brpopRedisThread (){ } @Override public void run() { try { brpopRedis(); } catch (Exception e) { LOGGER.error("### A0010032ServiceImpl.brpopRedis exception! ###", e); } } }
/** * 从redis队列中取出 * */ private void brpopRedis() throws Exception { JSONObject json = new JSONObject(); List<String> brpop = jedisCluster.brpop(0, key); String msg=""; if (brpop != null){ msg = brpop.get(1); } //将字符串转换成json格式 if (!StringUtils.isEmpty(msg)){ json = JSONObject.parseObject(msg); } //将数据存入ES中 if (json != null){ LOGGER.info(json.toString()); savePosition2ElasticSearch(json); } }
总结:使用了jedisCluster开启异步线程从队列中取值,解决了接口并发问题,如需转载,请注明出处