最近遇到的连接问题我准备从重构的几个程序(redis和mysql)长连接和短连接,以及连接池和单连接等问题用几篇博客来总结下。

这个问题的具体发生在java原生程序和redis的交互中。这个问题对我最深刻的教训就是说明获取连接不能迷信连接池和原封不动的搬运以前代码的utils。在连接的建立的一开始就应该思考连接的稳定性和是否应该关闭连接。否则这些问题在线上运行十几个小时可能才会暴露,即使知道了问题反过来的排查和修改也会很困难。甚至在重构之前用一种勉强凑合的方式掩盖问题(给自己挖坑)

应用场景

java原生程序,内部写多个线程,定时循环监测(一小时一次),使用了redis连接。

最开始是采用长连接的方式,在main方法中用连接池获取连接后分配到各线程,这种方式虽然只创建一次连接,但在长时间的程序休眠中,仍然会产生对连接的占用,也会导致掉连接的问题,以下是从连接池获取连接的代码(也可拆分成获取连接池和通过连接池单独获取连接):


public Jedis createJedisCluterInstance(Map<String, Object> props){
  String[] hostPortStr = String.valueOf(this.config.getOrDefault(REDIS_CLUSTER_NODE_PORT,props.get(REDIS_CLUSTER_NODE_PORT))).split(":");
  GenericObjectPoolConfig config = new GenericObjectPoolConfig();
  config.setMaxTotal(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_TOTAL,props.get(REDIS_MAX_TOTAL)))));
  config.setMaxIdle(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_IDLE,props.get(REDIS_MAX_IDLE)))));
  config.setMaxWaitMillis(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_WAIT_MILLIS,props.get(REDIS_MAX_WAIT_MILLIS)))));

  JedisPool jedisPool = new JedisPool(config,hostPortStr[0],Integer.valueOf(hostPortStr[1]));

  final Jedis[] jedis= {null};

  Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
          .retryIfException()
          .withWaitStrategy(WaitStrategies.fixedWait(1000, TimeUnit.MILLISECONDS))
          .withStopStrategy(StopStrategies.stopAfterAttempt(10))
          .build();
  try {
      retryer.call(() -> {
          jedis[0] = jedisPool.getResource();
          jedis[0].auth("123");
          String value = jedis[0].ping();
          return StringUtils.isNotBlank(value);
      });
  } catch (Exception e) {
      LOGGER.error("多次获取Redis连接失败!");
  }
  return jedis[0];
}

当时处理掉连接的方式是采用了定时任务按每分钟一次的频率监测,对异常trycatch后直接退出程序。

这种方法产生了很大的资源消耗,也对业务造成影响,主要原因是盲目使用连接池造成的。

修改后采用传入配置到线程中,在线程中启动连接,同时修改连接池连接为直接获取连接。减少了资源消耗,同时也处理了掉连接的问题。并在每次循环结束后关闭redis连接 :关闭方法redis.close();  并在下次循环开始后重新初始化,直接获取redis对象代码:


public Jedis getJedis(Map<String, Object> props){
  String[] hostPortStr = String.valueOf(this.config.getOrDefault(REDIS_CLUSTER_NODE_PORT, props.get(REDIS_CLUSTER_NODE_PORT))).split(":");
  Jedis jedis = new Jedis(hostPortStr[0],Integer.valueOf(hostPortStr[1]),Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_WAIT_MILLIS, props.get(REDIS_MAX_WAIT_MILLIS)))));
  jedis.auth("123");
  return jedis;
}

来源:https://blog.csdn.net/jyj1100/article/details/86499547

java原生程序redis连接(连接池/长连接和短连接)选择问题的更多相关文章

  1. [转载] http长连接和短连接

    转载自http://blog.csdn.net/shine0181/article/details/7799754/ HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP ...

  2. mysql长连接与短连接

    什么是长连接? 其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态. 通常的短连接操作步骤是: 连接->数据传输->关闭连接: 而长连接通常就是: 连接-> ...

  3. TCP/IP,http,socket,长连接,短连接——小结。

    来源:http://blog.chinaunix.net/uid-9622484-id-3392992.html TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. ...

  4. http的长连接和短连接(数据库也一样)

    长连接与短连接 所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持. 短连接是指通信双方有数据交互时 ...

  5. TCP/IP,http,socket,长连接,短连接——小结(转)

    概要: 之前对这几个概念有点糊涂,查阅了些资料,稍微概括下他们的区别吧.如有错误,请拍~~~ 先看图: TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.    在 ...

  6. [转]TCP(HTTP)长连接和短连接区别和怎样维护长连接

    原文链接 一.HTTP协议和TCP协议 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议.IP协议主要解决网络路由和寻址问题, ...

  7. TCP/IP,http,socket,长连接,短连接 —— 小结

    TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.    在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议.    在传输层中有TCP协议 ...

  8. Socket 长连接与短连接,心跳

    长连接与短连接 所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持. 短连接是指通信双方有数据交互时 ...

  9. 长连接、短连接、长轮询和WebSocket

    //转发,格式待整理 2017-08-0519784View0 对这四个概念不太清楚,今天专门搜索了解一下,总结一下: 长连接:在HTTP 1.1,客户端发出请求,服务端接收请求,双方建立连接,在服务 ...

随机推荐

  1. 数组的三种方式总结 多维数组的遍历 Arrays类的常用方法总结

    一.数组的三种声明方式总结 public class WhatEver { public static void main(String[] args) { //第一种 例: String[] tes ...

  2. 一次完整的JVM堆外内存泄漏故障排查记录

    前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助. 在整个排查过程中,我也走了不少弯路,但是在文章中我 ...

  3. ent orm笔记2---schema使用(下)

    Indexes 索引 在前两篇的文章中,其实对于索引也有一些使用, 这里来详细看一下关于索引的使用 Indexes方法可以在一个或者多个字段上设置索引,以提高数据检索的速度或者定义数据的唯一性 在下面 ...

  4. Java8中的Stream API

    本篇文章继续介绍Java 8的另一个新特性——Stream API.新增的Stream API与InputStream和OutputStream是完全不同的概念,Stream API是对Java中集合 ...

  5. JS深浅拷贝及其实现

    基本数据类型和引用数据类型 JS数据分为基本数据类型和引用数据类型.基本数据类型的变量存储在栈中,引用数据类型则存储在堆中,引用数据类型的存储地址则保存在栈中. 下面来看一个小例子 // 基本数据类型 ...

  6. android开发之java JDK环境变量配置的信息代码 附详细教程。

    java环境变量配置: [用户变量]class_path    .;%JAVA_HOME%\lib\tools;%JAVA_HOME%\jre PATH           ;%JAVA_HOME%\ ...

  7. LightOJ - 1214-Large Division(c++取模 + java的两种写法)

    Given two integers, a and b, you should check whether a is divisible by b or not. We know that an in ...

  8. WPF实现手势解锁

    桌面程序的解锁方式一般是账号密码,互联网的可以使用扫码解锁,甚至人脸识别.但扫码需要网络,人脸识别又较复杂.所以就想把安卓常用的手势解锁移植到桌面程序上. 先来张效果图,有兴趣的往下看,没兴趣的打扰了 ...

  9. SqlAnalyzer1.01 源码

    源码下载:https://files.cnblogs.com/files/heyang78/SqlAnalyzer-20200529-2.rar 现有功能:不带函数允许嵌套的select ...fro ...

  10. Mybatis-多对一和一对多

    多对一和一对多 目录 多对一和一对多 1. 复杂表的构建 2. 测试环境搭建 1. 导入Lombok 2. 新建实体类 3. 建立Mapper接口 4. 建立Mapper.xml文件 5. 在核心配置 ...