• redis客户端连接异常


    本文参考:http://mdba.cn/2015/04/02/redistwemproxy-%e5%ae%a2%e6%88%b7%e7%ab%af%e8%bf%9e%e6%8e%a5%e5%bc%82%e5%b8%b8/

    对于一个DBA,客户端连接异常问题可以说是家常便饭的事情,处理多了都想吐。

    root cause无疑发生在三个地方,先找自身的原因,依次排查下去:
    1)服务器端db的负载,如果负载太高,创建socket太慢引起超时。另外服务器端socket的个数太多,也可以导致创建连接需要很长的时间或者创建连接不成功。
    2)网络是够有抖动,包括lvs/twemproxy重启操作。
    3)客户端的连接配置参数是否合理,连接池的大小,超时参数大小。还有客户端服务器的状态,负载和tcp连接状况。
    下面是近三个工作日碰到的redis/twemproxy连接问题。

    1、不合理的jedispool配置,连接池设置的太小
    错误信息:

    daemon prio=10 tid=0x00002ab367888000 nid=0x1881 in Object.wait()
    [0x00002ab3e5754000] java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
    ...

    监控的连接数显示:redis的连接数每秒维持在200+个, 比较正常。
    jedispool配置:最大允许创建的连接个数为50个,相比连接数,这个值偏小。

    解决方法:
    1)增大连接池的大小,但是不要太大,避免客户端和服务器端维持大量的空闲了连接。
    2)可以设置minIdle和EvictIdle的时间,加快获取连接对象和释放空闲的连接。
    3)设置testOnBorrow=True参数,每次get连接时候进行连接有效性检测。
    ps:jedis/jedispool的很多默认参数配置并不适合用,需要按照应用需求何求调整。

    下面提供一个供参考的redis配置文件:

    <bean name="poolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
            <property name="maxTotal" value="500"/>
            <property name="maxIdle" value="200"/>
            <property name="minIdle" value="50"/>
            <property name="testOnBorrow" value="true" /> 
        </bean>
    
        <bean name="jedisCluster" class="redis.clients.jedis.JedisCluster" scope="singleton">
            <constructor-arg index="0">
                <!-- 配置redis集群节点地址 -->
                <set>
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg index="0" value="${redis.ip1}"/>
                        <constructor-arg index="1" value="${redis.port1}" type="int"/>
                    </bean>
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg index="0" value="${redis.ip2}"/>
                        <constructor-arg index="1" value="${redis.port2}" type="int"/>
                    </bean>
                    <bean class="redis.clients.jedis.HostAndPort">
                        <constructor-arg index="0" value="${redis.ip3}"/>
                        <constructor-arg index="1" value="${redis.port3}" type="int"/>
                    </bean>
                </set>
            </constructor-arg>
            <!-- timeout: 超时时间 -->
            <constructor-arg index="1" value="3000"/>
            <!-- maxRedirections: 最大重定向 -->
            <constructor-arg index="2" value="5"/>
            <!-- 连接池 -->
            <constructor-arg index="3" ref="poolConfig"/>
        </bean>

    2、没有返回连接对象
    错误信息:
    an error occurred when executing function getJedis(): Could not get a resource from the pool
    jedispool连接池的使用方式:
    Jedis jedis = JedisFactory.jedisPool.getResource();
    try{
    jedis.set("key","val");
    }
    finally {
    JedisFactory.jedisPool.returnResource(jedis);
    }
    连接使用完之后,需要归还到连接池中。

    3、容错处理
    网络链路并不能保证绝对的稳定,db服务也不能提供99.999%的可靠服务。代码需要能够捕获异常和异常处理,而不是应用程序报错。

  • 相关阅读:
    [转]面向对象的三个基本特征
    C#验证Email
    天气预报
    【原】c#实现数字金额转换成大写金额
    C#发送Email
    DIV 显示最上层
    ArrayList 与 String[] 之间的转换
    Flex与.NET互操作(五):FileReference+HttpHandler实现上传/下载
    Flex与.NET互操作(三):基于WebService的数据访问(下)
    Flex与.NET互操作(六):Flex和.NET协同开发利器FluorineFx
  • 原文地址:https://www.cnblogs.com/janehoo/p/6123008.html
Copyright © 2020-2023  润新知