Archive for 六月, 2014

Redis异常JedisConnectionException:Read timed out解决笔记

星期三, 六月 25th, 2014 21,504 views

笔记①

异常如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at redis.clients.jedis.Protocol.process(Protocol.java:131)
    at redis.clients.jedis.Protocol.read(Protocol.java:187)
    at redis.clients.jedis.Connection.getIntegerReply(Connection.java:200)
    at redis.clients.jedis.BinaryJedis.incrBy(BinaryJedis.java:633)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at redis.clients.util.RedisInputStream.fill(RedisInputStream.java:109)
    at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:45)
    at redis.clients.jedis.Protocol.process(Protocol.java:116)
    ... 8 more

在服务器运行中突发异常,当时对Redis的操作并不频繁,大概一分钟一次的写数据,初步分析排除了资源竞争照成的Redis超时异常。
之后ping -t 远程Redis主机,发现当出现Read timed out异常时经常伴有ping超时情况,初步判定为网络不稳定照成。

临时解决办法是在new JedisPool(config, host, port, timeout) 初始化时,将timeout设置成更大的值(默认是2000)以便应对极端网络情况下的读取流异常情况。更进一步的分析还有待发掘,本篇未完待续。

笔记②
之前Read timed out的异常并未在修改了配置文件后有太大的改善,在外网环境下,当用户基数增长到一定量级时,再次出现Read timed out异常。

这种现象太容易让服务端程序将焦点集中在Redis的并发处理能力及连接池数量上,因此特意打印了Redis的慢查询日志,发现并无明显异常,之后观察了Redis的连接数,也不过几十个client而已,并未超过设置上限,在Jedis方面,按照网上其他朋友的建议修改了maxIdle、maxActive和maxWait的值,但问题依旧。

因此开始将排查重点放到了网络底层上,检查了与Redis主机的线路ping值,出现Read timed out的时候,并未出现延迟情况,网络ping值一直<1ms。

继续观察,这个时候注意到偶尔出现了带宽峰值突破30MB/s的情况,多亏了服务器上开启的流量监控浮动,否则很难捕捉到这一瞬间。

通过与机房确认,确定两台机器走的是外网IP,因此访问Redis时走的带宽为外网带宽,那么势必会受到机房防火墙的限制,因此出现了Jedis无法读取到后续数据流的问题。

找到根源之后,问题就很好解决了,在业务机与Redis服务器上各加了一块千兆网卡,通过内网进行直连。重新开机,导用户,测试,加大用户量,一切正常。同时实时流量显示最高峰值达到了100MB/s。

因为Redis是基于TCP连接的,而海量的数据反复交互相当于远程读写内存的操作,势必会造成带宽的使用紧张,那么在带宽吃紧的情况下,Redis客户端即Jedis拿不到连接或拿不到后续数据包也是很正常的了。

但考虑到峰值交互量有点高的可怕,针对这一问题,对并发交互数据的频率进行调整,对数据量进行精减才是解决这一问题的最佳方案。

关于redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out的这一问题我们暂且解决到这里,目前暂未再次出现。
大家如果遇到此类问题,在修改Jedis参数的情况下依旧无法解决,可以考虑一下是否是硬件及网络问题造成的。

本篇到此,欢迎交流讨论。谢谢。

Beitown
2015.04.07

在IE8下DIV margin:0 auto不居中的解决办法

星期四, 六月 5th, 2014 25 views

RT,用<center>标签完美解决

1
2
3
4
5
6
7
8
9
 <center>
      <div style="margin:0 auto;">
        <p>[ 我为痴狂 ]</br>
        </p>
        <p><a href="http://creater.beitown.com/?cat=3" >Creater 创世记</a></p>
        <p><a href="http://coder.beitown.com" >Coder 编码之源</a></p>
        <p style="text-align:right">—— BeiTown-北呈-2014-星夜河殿下</p>
      </div>
 </center>

BeiTown
2014-06-05

Java正则表达式取目标字符串简单范例

星期二, 六月 3rd, 2014 111 views

本篇只讲述JAVA正则表达式类java.util.regex的取字符串的使用方法,关于正则表达式的语法及使用不在本篇的描述之中,若有需要可参看《正则表达式30分钟入门教程》

首先做完范例需要一个待解析字符串,这里顺带把最近一个项目中的jdbcUrl拿来解析好了,字符串如下

1
jdbc:mysql://127.0.0.1:3306/test

这里说下目标需求,即把这段jdbcUrl分解成IP(127.0.0.1)、端口号(3306)以及数据库名(test),现将Java中的操作分为以下几步:

①书写正则表达式

正则表达式分别如下:

IP:(?<=//).*(?=:)取”//”和” :”之间的内容
PORT:(?<=\d:).*(?=/)取”数字+:”和” /”之间的内容
DBNAME:(?<=\d/).*”)取”数字+/”后面的内容

这里用正则表达式测试工具可以实时看到效果。
(更多…)