最近项目一直在使用redis,首次用redis,随便从网上找了例子就用了,一开始用的还挺正常,后来发现,当客户端访问量一上来,redis的连接数居高不下,一开始以为是客户端没有关闭,开始怀疑redis-pool有问题,就修改了/etc/redis/6379.cnf中的timeout=5(默认是0,服务端不主动关闭连接),修改之后发现close_wait批量出现。
经过分析,肯定不是redis的问题了,肯定是自己代码有的逻辑是没有关闭redis的,经过排查,果然有很多redis因为逻辑关系没有关闭,所以建议大家如果并发量不是很大的话,还是直接在操作redis的时候重新获取redis,然后关闭redis即可,这样就不会出现没有关闭redis的情况了。
对了,使用的redis版本也要对应呦,比如服务端装的是3.0.2,引入的jedis.jar的版本就不能太低,之前我们用的2.1,就经常出现类型转换错误(其实代码中的转换没有问题),我们换成最新的2.7之后,就不报类型转换错误了。
1 package com.jovision.redisDao; 2 3 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Set; 7 8 import org.apache.log4j.Logger; 9 10 import redis.clients.jedis.Jedis; 11 import redis.clients.jedis.JedisPool; 12 import redis.clients.jedis.JedisPoolConfig; 13 14 import com.jovision.Exception.RedisException; 15 import com.jovision.system.ConfigBean; 16 /** 17 * 18 * @Title: redisFactory.java 19 * @Package com.jovision.redisDao 20 * @author Joker(张凯) 21 * @Description: TODO() 22 * @date 2015-9-30 上午11:49:09 23 */ 24 public class redisFactory { 25 private static Logger logger = Logger.getLogger(redisFactory.class); 26 27 public static ConfigBean configBean; 28 public static String redisIP ; 29 public static String redisPort ; 30 public static JedisPool pool; 31 static 32 { 33 //连接redis,连接失败时抛异常 34 try 35 { 36 configBean = ConfigBean.getInstace(); 37 redisIP = configBean.getRedisIP(); 38 redisPort = configBean.getRedisPort(); 39 if (pool == null) 40 { 41 JedisPoolConfig config = new JedisPoolConfig(); 42 config.setMaxIdle(10); 43 config.setMaxTotal(200); 44 config.setMaxWaitMillis(1000 * 10); 45 config.setTestOnBorrow(true); 46 pool = new JedisPool(config, redisIP, Integer.parseInt(redisPort),10000); 47 } 48 } 49 catch (Exception e) 50 { 51 e.printStackTrace(); 52 logger.error("redis配置异常", e); 53 //throw new RedisException("redis异常!"); 54 } 55 56 } 57 58 /** 59 * 初始化Redis连接池 60 *//* 61 private static void initialPool(){ 62 try { 63 configBean = ConfigBean.getInstace(); 64 redisIP = configBean.getRedisIP(); 65 redisPort = configBean.getRedisPort(); 66 JedisPoolConfig config = new JedisPoolConfig(); 67 config.setMaxTotal(10); 68 config.setMaxIdle(5); 69 config.setMaxWaitMillis(1000*10); 70 config.setTestOnBorrow(true); 71 pool = new JedisPool(config,redisIP, Integer.parseInt(redisPort)); 72 } catch (Exception e) { 73 logger.error("create JedisPool error : "+e); 74 } 75 } 76 77 public synchronized static Jedis getJedis() { 78 if (pool == null) { 79 poolInit(); 80 } 81 Jedis jedis = null; 82 try { 83 if (pool != null) { 84 jedis = pool.getResource(); 85 } 86 } catch (Exception e) { 87 logger.error("Get jedis error : "+e); 88 }finally{ 89 returnResource(pool, jedis); 90 } 91 System.out.println("pool:---------------------------------"+pool); 92 return jedis; 93 } 94 95 *//** 96 * 在多线程环境同步初始化 97 *//* 98 private static synchronized void poolInit() { 99 if (pool == null) { 100 initialPool();101 }102 }*/103 104 public static void main(String[] args) throws Exception {105 /*System.out.println(redisIP);106 setSingleData("123","123");107 System.out.println(getSingleData("123"));*/108 //put2Set(0,"test11", "123","456","789");109 //System.out.println(getOneSetData("test","123"));110 //dev_type dev_version dev_username dev_password111 /*hset(8, "B176218924", "dev_type", "2");112 hset(8, "B176218924", "dev_version", "v1.1");113 hset(8, "B176218924", "dev_username", "abc");114 hset(8, "B176218924", "dev_password", "123");115 hset(8, "B176218924", "dev_nickname", "B176218924");*/116 //setTimeOut(0, "zk", 100);117 118 119 120 /*for(int i=0;i<20;i++)121 {122 123 new Thread(new Runnable() {124 public void run() {125 126 // TODO Auto-generated method stub127 for(int j=0;j<100000;j++) {128 try {129 Jedis jedis = redisFactory.getJedis();130 jedis.close();131 //pool.returnResource(jedis);132 System.out.println(jedis.isConnected());133 } catch (Exception e) {134 e.printStackTrace();135 }136 }137 138 }139 }).start();140 }141 for(int i=0;i<100;i++)142 {143 144 //Jedis jedis = redisFactory.getJedis();145 Jedis jedis = new Jedis(redisIP, Integer.parseInt(redisPort),10000);146 System.out.println(jedis);147 jedis.close();148 System.out.println("jedis.isConnected()-------------"+jedis.isConnected());149 }*/150 System.out.println(System.currentTimeMillis());151 }152 153 /**154 * 返还到连接池155 * 156 * @param pool 157 * @param redis158 */159 public static void returnResource(JedisPool pool, Jedis redis) {160 if (redis != null) {161 pool.returnResource(redis);162 }163 }164 165 166 /**167 * 将数据存到集合168 * 169 * @param key170 * @return171 */172 public static boolean put2Set(int index,String key , String... value){173 Jedis jedis = null;174 try {175 jedis = pool.getResource();176 jedis.select(index);177 jedis.sadd(key, value);178 return true;179 } catch (Exception e) {180 //失败就返回jedis181 pool.returnBrokenResource(jedis);182 e.printStackTrace();183 return false;184 } finally {185 //释放jedis资源186 returnResource(pool, jedis);187 }188 189 }190 191 192 /**193 * 194 * @author Hellon(刘海龙) 195 * @param jedis196 * @param index197 * @param key198 * @param value199 * @return200 */201 public static boolean put2Set(Jedis jedis,int index,String key , String... value ){202 try {203 jedis.select(index);204 jedis.sadd(key, value);205 return true;206 } catch (Exception e) {207 //失败就返回jedis208 e.printStackTrace();209 return false;210 } 211 212 }213 214 /**215 * @Title: 带jedis和有效期216 * @Package com.jovision.redisDao217 * @author Joker(张凯)218 * @Description: TODO() 219 * @date 2015-11-18 下午02:42:04220 * @param jedis221 * @param seconds222 * @param index223 * @param key224 * @param value225 * @return226 */227 public static boolean put2Set(Jedis jedis,int seconds,int index,String key , String... value ){228 try {229 jedis.select(index);230 jedis.sadd(key, value);231 jedis.expire(key, seconds);232 return true;233 } catch (Exception e) {234 //失败就返回jedis235 e.printStackTrace();236 return false;237 } 238 239 }240 241 /**242 * 获取集合数据243 * 244 * @param key245 * @return246 * @throws RedisException 247 */248 public static SetgetSet(int index,String key) throws RedisException{249 Jedis jedis = null;250 try {251 jedis = pool.getResource();252 jedis.select(index);253 return jedis.smembers(key);254 } catch (Exception e) {255 //失败就返回jedis256 pool.returnBrokenResource(jedis);257 //e.printStackTrace();258 logger.error("getSet异常", e);259 throw new RedisException("redis异常!"+e.getMessage());260 } finally {261 //释放jedis资源262 returnResource(pool, jedis);263 }264 }265 266 267 public static Set getSet(Jedis jedis,int index,String key) {268 try {269 jedis.select(index);270 return jedis.smembers(key);271 } catch (Exception e) {272 logger.error("getSet异常", e);273 } 274 return null;275 }276 277 /**278 * @Title: hget279 * @Package com.jovision.redisDao280 * @author Joker(张凯)281 * @Description: TODO() 282 * @date 2015-9-30 上午11:44:58283 * @param index284 * @param key285 * @param field286 * @return287 * @throws RedisException288 */289 public static String hget(int index,String key,String field) throws RedisException{290 Jedis jedis = null;291 try {292 jedis = pool.getResource();293 jedis.select(index);294 return jedis.hget(key, field);295 } catch (Exception e) {296 //失败就返回jedis297 pool.returnBrokenResource(jedis);298 //e.printStackTrace();299 logger.error("getSet异常", e);300 throw new RedisException("redis异常!"+e.getMessage());301 } finally {302 //释放jedis资源303 returnResource(pool, jedis);304 }305 }306 307 public static String hget(Jedis jedis,int index,String key,String field){308 try {309 jedis.select(index);310 return jedis.hget(key, field);311 } catch (Exception e) {312 logger.error(e, e);313 }314 return null;315 }316 317 /**318 * @Title: hset 319 * @Package com.jovision.redisDao320 * @author Joker(张凯)321 * @Description: TODO() 322 * @date 2015-9-30 上午11:45:06323 * @param index324 * @param key325 * @param field326 * @param value327 * @throws RedisException328 */329 public static void hset(int index,String key,String field,String value) throws RedisException{330 Jedis jedis = null;331 try {332 jedis = pool.getResource();333 jedis.select(index);334 jedis.hset(key, field,value);335 } catch (Exception e) {336 //失败就返回jedis337 pool.returnBrokenResource(jedis);338 //e.printStackTrace();339 logger.error("getSet异常", e);340 throw new RedisException("redis异常!"+e.getMessage());341 } finally {342 //释放jedis资源343 returnResource(pool, jedis);344 }345 }346 347 public static void hset(Jedis jedis,int index,String key,String field,String value) {348 try {349 jedis.select(index);350 jedis.hset(key, field,value);351 } catch (Exception e) {352 logger.error(e,e);353 } 354 }355 356 /**357 * @Title: 带jedis和seconds358 * @Package com.jovision.redisDao359 * @author Joker(张凯)360 * @Description: TODO() 361 * @date 2015-11-18 下午02:45:09362 * @param jedis363 * @param seconds364 * @param index365 * @param key366 * @param field367 * @param value368 */369 public static void hset(Jedis jedis,int seconds,int index,String key,String field,String value) {370 try {371 jedis.select(index);372 jedis.hset(key, field,value);373 jedis.expire(key, seconds);374 } catch (Exception e) {375 logger.error(e,e);376 } 377 }378 379 /**380 * 获取单个数据381 * 382 * @param key383 * @return384 */385 public static String getSingleData(int index,String key){386 Jedis jedis = null;387 try {388 jedis = pool.getResource();389 jedis.select(index);390 return jedis.get(key);391 } catch (Exception e) {392 //失败就返回jedis393 pool.returnBrokenResource(jedis);394 e.printStackTrace();395 } finally {396 //释放jedis资源397 returnResource(pool, jedis);398 }399 return null;400 401 }402 403 public static String getSingleData(Jedis jedis,int index,String key){404 try {405 jedis = pool.getResource();406 jedis.select(index);407 return jedis.get(key);408 } catch (Exception e) {409 //失败就返回jedis410 logger.error(e,e);411 }412 return null;413 }414 415 /**416 * 存入单个简单数据417 * 418 * @param key419 * @return420 */421 public static boolean setSingleData(int index,String key ,String value){422 Jedis jedis = null;423 try {424 jedis = pool.getResource();425 jedis.select(index);426 jedis.set(key, value);427 return true;428 } catch (Exception e) {429 //失败就返回jedis430 pool.returnBrokenResource(jedis);431 e.printStackTrace();432 return false;433 } finally {434 //释放jedis资源435 returnResource(pool, jedis);436 }437 438 }439 440 public static void setSingleData(Jedis jedis,int seconds,int index,String key ,String value){441 try {442 jedis.select(index);443 jedis.set(key, value);444 jedis.expire(key, seconds);445 } catch (Exception e) {446 logger.error(e,e);447 } 448 449 }450 451 /**452 * 删除set中单个value453 * 454 * @param key455 * @return456 */457 public static boolean del1SetValue(int index,String key ,String value){458 Jedis jedis = null;459 try {460 jedis = pool.getResource();461 jedis.select(index);462 jedis.srem(key, value); 463 return true;464 } catch (Exception e) {465 pool.returnBrokenResource(jedis);466 e.printStackTrace();467 return false;468 } finally {469 returnResource(pool, jedis);470 }471 472 }473 474 475 public static boolean del1SetValue(Jedis jedis,int index,String key ,String value){476 try {477 jedis.select(index);478 jedis.srem(key, value); 479 return true;480 } catch (Exception e) {481 logger.error(e,e);482 return false;483 } 484 }485 486 /**487 * 删除key对应整个set488 * 489 * @param key490 * @return491 */492 public static boolean del(int index ,String key){493 Jedis jedis = null;494 try {495 jedis = pool.getResource();496 jedis.select(index);497 jedis.del(key);498 return true;499 } catch (Exception e) {500 pool.returnBrokenResource(jedis);501 e.printStackTrace();502 return false;503 } finally {504 returnResource(pool, jedis);505 }506 507 }508 509 public static boolean del(Jedis jedis,int index ,String key){510 try {511 jedis.select(index);512 jedis.del(key);513 return true;514 } catch (Exception e) {515 logger.error(e,e);516 return false;517 } 518 }519 520 /**521 * 设置key失效时间 522 * @param key 523 * @param seconds524 * @throws Exception525 */526 public static void setTimeOut(int index,String key,int seconds) throws Exception{527 Jedis jedis = null;528 try {529 jedis = pool.getResource();530 jedis.select(index);531 jedis.expire(key, seconds);532 } catch (Exception e) {533 pool.returnBrokenResource(jedis);534 logger.error("redis数据库出现异常", e);535 throw e;536 } finally {537 returnResource(pool, jedis);538 }539 }540 541 /**542 * @Title: redisFactory.java 543 * @Package com.jovision.redisDao544 * @author Joker(张凯)545 * @Description: TODO() 546 * @date 2015-10-29 下午03:54:21547 * @param jedis548 * @param index549 * @param key550 * @param seconds551 * @throws Exception552 */553 public static void setTimeOut(Jedis jedis,int index,String key,int seconds){554 try {555 jedis.select(index);556 jedis.expire(key, seconds);557 } catch (Exception e) {558 logger.error(e, e);559 } 560 }561 562 public static byte[] getBytes(int index,byte[] key) throws Exception563 {564 Jedis jedis = null;565 try {566 jedis = pool.getResource();567 jedis.select(index);568 return jedis.get(key);569 } catch (Exception e) {570 pool.returnBrokenResource(jedis);571 logger.error("redis数据库出现异常", e);572 throw e;573 } finally {574 returnResource(pool, jedis);575 }576 }577 578 public static byte[] getBytes(Jedis jedis,int index,byte[] key) 579 {580 try {581 jedis.select(index);582 return jedis.get(key);583 } catch (Exception e) {584 // pool.returnBrokenResource(jedis);585 logger.error("redis数据库出现异常", e);586 //throw e;587 } 588 return null;589 }590 591 public static Map hgetAll(Jedis jedis,int index,String key) 592 {593 try {594 jedis.select(index);595 return jedis.hgetAll(key);596 } catch (Exception e) {597 // pool.returnBrokenResource(jedis);598 logger.error("redis数据库出现异常", e);599 }600 return null;601 }602 603 public static void hmset(Jedis jedis,int index,String key, Map map) 604 {605 try {606 jedis.select(index);607 jedis.hmset(key, map);608 } catch (Exception e) {609 //pool.returnBrokenResource(jedis);610 logger.error("redis数据库出现异常", e);611 }612 }613 614 public static void hmset(Jedis jedis,int seconds,int index,String key, Map map) 615 {616 try {617 jedis.select(index);618 jedis.hmset(key, map);619 jedis.expire(key, seconds);620 } catch (Exception e) {621 // pool.returnBrokenResource(jedis);622 logger.error("redis数据库出现异常", e);623 }624 }625 626 public static void setBytes(int index,byte[] key,byte[] value) throws Exception627 {628 Jedis jedis = null;629 try {630 jedis = pool.getResource();631 jedis.select(index);632 jedis.set(key, value);633 } catch (Exception e) {634 pool.returnBrokenResource(jedis);635 logger.error("redis数据库出现异常", e);636 throw e;637 } finally {638 returnResource(pool, jedis);639 }640 }641 642 public static void setBytes(Jedis jedis,int index,byte[] key,byte[] value) 643 {644 try {645 jedis.select(index);646 jedis.set(key, value);647 } catch (Exception e) {648 //pool.returnBrokenResource(jedis);649 logger.error("redis数据库出现异常", e);650 } 651 }652 653 /**654 * 655 * @author Hellon(刘海龙) 656 * @param key key值657 * @return 该key值存储的长度658 * @throws Exception659 */660 public static Long getLLength(int index,String key) throws Exception{661 Jedis jedis = null;662 try {663 jedis = pool.getResource();664 jedis.select(index);665 Long len = jedis.llen(key);666 return len;667 } catch (Exception e) {668 pool.returnBrokenResource(jedis);669 logger.error("redis数据库出现异常", e);670 throw e;671 } finally {672 returnResource(pool, jedis);673 }674 }675 676 /**677 * 从list获取数据678 * @author Hellon(刘海龙) 679 * @param key 字节byte680 * @param start 查询的开始位置681 * @param end 查询的结束位置 -1 代表查询所有682 * @return 返回字节list列表683 * @throws Exception684 */685 public static List lrange(int index,byte[] key,int start,int end) throws Exception{686 Jedis jedis = null;687 try {688 jedis = pool.getResource();689 jedis.select(index);690 List list = jedis.lrange(key, start, end);691 return list;692 } catch (Exception e) {693 pool.returnBrokenResource(jedis);694 logger.error("redis数据库出现异常", e);695 throw e;696 } finally {697 returnResource(pool, jedis);698 }699 }700 701 /**702 * @Title: 是否存在703 * @Package com.jovision.redisDao704 * @author Joker(张凯)705 * @Description: TODO() 706 * @date 2015-9-30 下午02:09:25707 * @param index708 * @param key709 * @return710 * @throws Exception711 */712 public static boolean isExist(int index,String key) throws Exception{713 Jedis jedis = null;714 try {715 jedis = pool.getResource();716 jedis.select(index);717 return jedis.exists(key);718 } catch (Exception e) {719 pool.returnBrokenResource(jedis);720 logger.error("redis数据库出现异常", e);721 throw e;722 } finally {723 returnResource(pool, jedis);724 }725 }726 727 public static Boolean isExist(Jedis jedis,int index,String key){728 try {729 jedis.select(index);730 return jedis.exists(key);731 } catch (Exception e) {732 logger.error(e,e);733 } 734 return null;735 }736 737 /**738 * 向list添加数据739 * @author Hellon(刘海龙) 740 * @param key741 * @param strings742 * @return743 * @throws Exception744 */745 public static Long lpush(int index,byte[] key,byte[]... strings) throws Exception{746 Jedis jedis = null;747 try {748 jedis = pool.getResource();749 jedis.select(index);750 Long len = jedis.lpush(key, strings);751 return len;752 } catch (Exception e) {753 pool.returnBrokenResource(jedis);754 logger.error("redis数据库出现异常", e);755 throw e;756 } finally {757 returnResource(pool, jedis);758 }759 }760 761 /**762 * 保留指定key 的值范围内的数据763 * @author Hellon(刘海龙) 764 * @param key 指定的key值765 * @param start 开始位置766 * @param end 结束位置767 * @throws Exception 768 */769 public static void ltrim(int index,byte[] key,int start,int end) throws Exception{770 Jedis jedis = null;771 try {772 jedis = pool.getResource();773 jedis.select(index);774 jedis.ltrim(key, start, end);775 } catch (Exception e) {776 logger.error("redis数据库出现异常", e);777 throw e;778 } finally {779 returnResource(pool, jedis);780 }781 }782 783 public static Jedis getJedis()784 {785 logger.info("publicService redis数据库连接活跃数--<"+pool.getNumActive()+786 ">--空闲连接数--<"+pool.getNumIdle()+787 ">--等待连接数--<"+pool.getNumWaiters()+">");788 return pool.getResource();789 }790 791 public static void releaseJedis(Jedis jedis)792 {793 if (jedis != null) {794 jedis.close();795 }796 }797 }