复习电商笔记-35-常见问题、RedisCluster和Spring框架整合

常见问题

  1. another app is currently holding the yum….
    直接 ps –ef|grep yum 杀掉就行了

  2. ERR Slot 5798 is already busy
     

    Can I set the above configuration? (type 'yes' to accept): yes
    /usr/lib/ruby/gems/1.8/gems/redis-3.3.2/lib/redis/client.rb:121:in `call': ERR Slot 5798 is already busy (Redis::CommandError)
    	from /usr/lib/ruby/gems/1.8/gems/redis-3.3.2/lib/redis.rb:2705:in `method_missing'
    	from /usr/lib/ruby/gems/1.8/gems/redis-3.3.2/lib/redis.rb:58:in `synchronize'
    	from /usr/lib/ruby/1.8/monitor.rb:242:in `mon_synchronize'
    	from /usr/lib/ruby/gems/1.8/gems/redis-3.3.2/lib/redis.rb:58:in `synchronize'
    	from /usr/lib/ruby/gems/1.8/gems/redis-3.3.2/lib/redis.rb:2704:in `method_missing'
    	from ./src/redis-trib.rb:212:in `flush_node_config'
    	from ./src/redis-trib.rb:776:in `flush_nodes_config'
    	from ./src/redis-trib.rb:775:in `each'
    	from ./src/redis-trib.rb:775:in `flush_nodes_config'
    	from ./src/redis-trib.rb:1296:in `create_cluster_cmd'
    	from ./src/redis-trib.rb:1701:in `send'
    	from ./src/redis-trib.rb:1701
    


    解决办法:删除之前配置产生的文件,nodes-7000.conf
     

  3. no reachable node in cluster
    redis.clients.jedis.exceptions.JedisConnectionException: no reachable node in cluster
    	at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnection(JedisSlotBasedConnectionHandler.java:48)
    	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:53)
    	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:70)
    	at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:32)
    	at redis.clients.jedis.JedisCluster.get(JedisCluster.java:92)
    	at httpclient.TestCluster.test(TestCluster.java:19)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    

    解决办法:检查haps集合是否为空,当配置的节点不正确时无法得到
    public void afterPropertiesSet() throws Exception {
    		Set<HostAndPort> haps = this.parseHostAndPort();
    		jedisCluster = new JedisCluster(haps, timeout, maxRedirections, poolConfig);
    	}
    
  4. Could not get a resource from the pool
    redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    	at redis.clients.util.Pool.getResource(Pool.java:50)
    	at redis.clients.jedis.JedisPool.getResource(JedisPool.java:88)
    	at redis.clients.jedis.JedisClusterConnectionHandler.renewSlotCache(JedisClusterConnectionHandler.java:70)
    	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:78)
    	at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:70)
    	at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:32)
    	at redis.clients.jedis.JedisCluster.get(JedisCluster.java:92)
    	at httpclient.TestCluster.test(TestCluster.java:19)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect
    	at redis.clients.jedis.Connection.connect(Connection.java:148)
    	at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:75)
    	at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1572)
    	at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:69)
    	at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:819)
    	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:429)
    	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:360)
    	at redis.clients.util.Pool.getResource(Pool.java:48)
    	... 30 more
    Caused by: java.net.ConnectException: Connection refused: connect
    	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
    	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
    	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
    	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
    	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    	at java.net.Socket.connect(Socket.java:579)
    	at redis.clients.jedis.Connection.connect(Connection.java:142)
    	... 37 more
    
    解决办法:关闭防火墙

RedisCluster和Spring框架整合

Maven依赖

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

applicationContext-rediscluster.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">  
    
    <!-- jedis 配置-->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >  
        <!--最大空闲数-->  
        <property name="maxIdle" value="${redis.maxIdle}" />  
        <!--最大建立连接等待时间-->  
        <property name="maxWaitMillis" value="${redis.maxWait}" />  
        <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
        <property name="maxTotal" value="${redis.maxTotal}" />  
        <property name="minIdle" value="${redis.minIdle}" />  
    </bean>
    
    <bean id="jedisCluster"  class="com.jt.common.util.RedisCluster" >  
        <property name="addressConfig">
            <value>classpath:redis.properties</value>  
        </property>  
        <property name="addressKeyPrefix" value="redis.cluster" />   <!--  属性文件里  key的前缀 -->  
        <property name="timeout" value="${redis.timeout}" />  
        <property name="maxRedirections" value="6" />  
 <property name="genericObjectPoolConfig" ref="poolConfig" />  
    </bean>  
</beans>  

redis.properties

#最小空闲数
redis.minIdle=100
#最大空闲数
redis.maxIdle=300
redis.maxActive=300
#最大连接数
redis.maxTotal=1000
#客户端超时时间单位是毫秒 
redis.timeout=1000
#最大建立连接等待时间  
redis.maxWait=1000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个  
redis.testOnBorrow=true

redis.node1.ip=192.168.163.200
redis.node1.port=6379

redis.node2.ip=192.168.163.200
redis.node2.port=6380

redis.node3.ip=192.168.163.200
redis.node3.port=6381

#redis cluster
redis.cluster0.host.port=192.168.163.201:7000
redis.cluster1.host.port=192.168.163.201:7001
redis.cluster2.host.port=192.168.163.201:7002
redis.cluster3.host.port=192.168.163.201:7003
redis.cluster4.host.port=192.168.163.201:7004
redis.cluster5.host.port=192.168.163.201:7005
redis.cluster6.host.port=192.168.163.201:7006
redis.cluster7.host.port=192.168.163.201:7007
redis.cluster8.host.port=192.168.163.201:7008

com.jt.common.util.RedisCluster

package com.jt.common.util;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class RedisCluster implements FactoryBean<JedisCluster>, InitializingBean {

	private Resource addressConfig;
	private String addressKeyPrefix;
	private JedisCluster jedisCluster;
	private Integer timeout;
	private Integer maxRedirections;
	private GenericObjectPoolConfig poolConfig;
	private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

	public JedisCluster getObject() throws Exception {
		return jedisCluster;
	}

	public Class<? extends JedisCluster> getObjectType() {
		return (this.jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class);
	}

	public boolean isSingleton() {
		return true;
	}

	private Set<HostAndPort> parseHostAndPort() {
		try {
			Properties prop = new Properties();
			prop.load(this.addressConfig.getInputStream());

			Set<HostAndPort> haps = new HashSet<HostAndPort>();
			for (Object key : prop.keySet()) {

				if (!((String) key).startsWith(addressKeyPrefix)) {
					continue;
				}

				String val = (String) prop.get(key);

				boolean isIpPort = p.matcher(val).matches();

				if (!isIpPort) {
					throw new IllegalArgumentException("ip 或 port 不合法");
				}
				String[] ipAndPort = val.split(":");

				HostAndPort hap = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
	haps.add(hap);
			}

			return haps;
		} catch (IllegalArgumentException ex) {
			ex.printStackTrace();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	public void afterPropertiesSet() throws Exception {
		Set<HostAndPort> haps = this.parseHostAndPort();
		jedisCluster = new JedisCluster(haps, timeout, maxRedirections, poolConfig);
	}

	public void setAddressConfig(Resource addressConfig) {
		this.addressConfig = addressConfig;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public void setMaxRedirections(int maxRedirections) {
		this.maxRedirections = maxRedirections;
	}

	public void setAddressKeyPrefix(String addressKeyPrefix) {
		this.addressKeyPrefix = addressKeyPrefix;
	}

	public void setGenericObjectPoolConfig(GenericObjectPoolConfig poolConfig) {
		this.poolConfig = poolConfig;
	}
}

     

业务调用

package com.jt.web.service;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.common.service.HttpClientService;
import com.jt.common.service.RedisService;
import com.jt.web.pojo.Item;

import redis.clients.jedis.JedisCluster;

@Service
public class ItemService {
	@Autowired  
    private JedisCluster jedisCluster;
	
	public String ITEM_KEY = "ITEM_";
	@Autowired
	private RedisService redisService;
	@Autowired
	private HttpClientService httpClientService;
	private static final ObjectMapper MAPPER = new ObjectMapper();
	
	public Item getItemById(Long itemId) throws Exception{
		//增加缓存
		try{
			String jsonData = jedisCluster.get(ITEM_KEY+itemId);
			if(StringUtils.isNotEmpty(jsonData)){
				Item item = MAPPER.readValue(jsonData, Item.class);
				return item;
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		//通过httpClient发起http请求,请求后台
		String url = "http://manage.jt.com/web/item/"+itemId;
		//注意有超时的问题,
		String jsonData = httpClientService.doGet(url, "utf-8");
		//把json串转成单个pojo对象
		Item item = MAPPER.readValue(jsonData, Item.class);
		
		//写缓存
		try{
			jedisCluster.set(ITEM_KEY+itemId, jsonData);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return item;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40680190/article/details/84261563
今日推荐