java使用redis时不时的报没有可用的链接

java使用redis时不时的报没有可用的链接,第1张

出现这种问题从以下几个方面排查:

1、网络不稳定,这种情况只会出现在调用机器和redis服务器不在同一台机器的情况,如果调用本机redis请忽略。

2、使用了连接池,并发较大,连接池配置的最大连接数过小,客户端从连接池获取连接时,如果没有可用连接就阻塞当前线程直到有可用连接,等待时间超过配置的超时时间后会抛出连接超时异常。

3、同样是使用连接池的情况,从连接池获取连接,使用完成后没有释放连接,导致连接池链接耗尽。

4、还有可能是硬件性能瓶颈,比如单节点的redis,但是需要支持特别大的并发量,无论怎么优化配置都是徒劳的,这种情况就需要考虑做读写分离,搭建redis集群等,

public static void writeRedis(String inpath, int[] keyIndex) throws Exception {

InputStream in = new URL(inpath)openStream();// 输入流 ]

LineIterator br = orgapachecommonsioIOUtilslineIterator(in, "utf8");// 指定输入流与字符编码

JedisCluster cluster = RedisUtilsgetClusterConn();

String[] line = null;

while (brhasNext()) {

String s = brnext();

line = RedisUtilssplit(s);

String key = "";

for (int i = 0; i < keyIndexlength; i++) {

key += line[keyIndex[i]];// TODO:如果有必要,添加分隔符

}

clustersetnx(key, s);

}

RedisUtilsclusterClose(cluster);

1、在配置文件redisconf中把绑定的Ip注释掉 

 

2、在配置文件redisconf中把protected-mode 改为 no 

3、在配置文件redisconf中把requirepass 设置redis访问授权密码(自己随意设置就好),也可以登录redis客户端使用命令设置:如下: 

/redis-cli 

config set requirepass 123 //123是密码 

经过以上三步基本就可以了,不过也有特殊情况,访问的端口号6379有可能会被防火墙拦截,需要关闭系统的防火墙或取消对6379端口的拦截,这里不在细述。 

接下来就可以创建项目实现 *** 作redis数据库了。在这里我用的开发工具是eclipse,在eclipse中创建一个java Project项目如下图所示: 

项目创建完成后,在src同级目录下创建lib文件夹,导入 *** 作数据库所需jar包(晚上自行下载),jedis用来 *** 作数据库,commons-pool用来实现数据库连接池。 

启动redis服务器: 

创建RedisDemoSimplejava代码如下:

package comredisredisDb;

import redisclientsjedisJedis;public class RedisDemoSimple {    public static void main(String[] args) {        //ip地址为虚拟机Ip 端口为redis端口

        Jedis jedis = new Jedis("192168228129", 6379);        //redis访问权限 为redis配置文件中redisconf中配置的requirepass

        jedisauth("myredis");

        jedisset("redis_first", "hello");

        Systemoutprintln("key redis_first:"+jedisget("redis_first"));

    }

}

控制台打印如下:

启动redis客户端查询插入数据库的值: 

 

到此就连接成功了。

应该是redis本身的服务有问题了

本文所针对的连接超时问题所涉及的相关元素如下:

Redis客户端: Jedis (java)

Redis版本 :2812

Redis部署 *** 作系统类型:Linux

正文开始:

No 1Redis执行大命令(时间复杂度为O(N)的命令)

问题剖析:

aRedis服务器端通过单线程处理命令,一旦有大命令被执行,Redis将无法及时响应来自客户端的任何命令

关于Redis大命令的监控,可以查看slowlog来观察

b在使用jedis作为redis客户端时,当redis连接池的配置参数testOnBorrow=true时,默认会在获取redis连接

时,先执行redis的ping方法,而基于原因a,此时redis将无法及时响应,自然会报出time out异常

如何解决:

a尽量避免使用时间复杂度为O(N)的命令

b如果无法避免使用时间复杂度为O(N)的命令,则应降低其使用频率,避免在业务高峰期时使用

No 2Redis单次 *** 作数据包过大

问题分析

a单次 *** 作数据包过大,且 *** 作频繁,极有可能会导致网络拥堵

b在使用jedis作为redis客户端时,当redis连接池的配置参数testOnBorrow=true时,默认会在获取redis连接

时,先执行redis的ping方法,而基于原因a,此时redis将无法及时响应,自然会报出time out异常

如何解决:

a排查代码,确定是否存在大数据(数据条目过多/单条数据过大) *** 作,将其进行改造,改造方案有两个:

a1数据拆分,变更数据类型(常见的情况是将java中的collection类型序列化后存入redis的String数据

类型中),如将String数据类型调整为hash/list/set等,这常用于解决单条数据量过大的情况

a2调整业务逻辑,减少单次数据查询范围(常见的情况如将redis中的整个hash数据取回,在应用程序内存中获取需要的entry),如使用hget等单条查询命令替换hgetall命令

第一阶段,Java SE基础:

Java环境搭建、Java流程控制语句-for循环、switch选择判断、循环嵌套、数组拷贝、多维数组、final关键字、构造函数的调用、类的访问权限和路径、面向对象高级特性、Java异常处理、Set,Map,List接口及接口实现类、Java线程、同步阻塞、JavaIO流、文件的 *** 作,复制,读写,删除等。

第二阶段,JavaWeb:

MySQL安装、管理、创建数据库、MySQLUPDATE

查询、Mysql高级 *** 作、JDBC、JDBC数据库连接 *** 作,JDBC动态Sql处理、Servlet30 网页重定向、Servlet30

新增的注解支持、AJAX、responseText属性详解等。

第三阶段,Java高级框架-SSH:

Struts2异常处理、Struts2+Log4j集成、Struts2和JSON实例、Hibernate5、Hibernate集合映射、Hibernate组件映射、Spring40、SpringAOP+

AspectJ框架、Spring 与其它Web框架集成、Spring Hibernate支持等。

第四阶段,Java高级框架-SSM:

SpringMVC、Spring MVC生成JSON数据、MyBatis、MyBatis 环境配置及入门、Mybatis set标签、Mybatis trim标签、Shiro、Shiro快速入门教程、Shiro Web应用等。

第五阶段,SpringBoot+VUE全栈框架:

SpringBoot、全局异常处理、过滤器监听器、EHCache缓存、SpringBoot Quartz定时任务、Vue、Vuejs 安装、模板语法、计算属性、事件处理器、Vuejs 自定义指令、Vuejs 路由等

第六阶段,特色课程:

ActiveM环境搭建、生产者和消费者、消息持久化 *** 作、RSA数字加密算法、Codebar条形码生成器、zxing二维码生成器、HighCharts统计图、Echarts统计图、网络播放器ckplayer、嵌入式网络播放器,可以浏览器和移动端随意使用

第七阶段,互联网框架的高级应用1:

分布式服务框架的理解,Dubbo架构设计详解及其核心要点,框架运行原理分析、SpringData数据访问、Lucene搜索引擎、Lucene的全文搜索服务器介绍、索引建立方式、Solr海量数据搜索引擎、Socket网络通信、实现RMI远程对象通讯、使用JMS消息服务、Kafka分布式消息系统、WebService与RestfulWS等

第八阶段,互联网框架的高级应用2:

Spring Security安全框架、实现Web应用安全控制、缓存应用与EhCache框架、OSCache与JBossCache框架、MyBatis与Hibernate缓存机制、NoSQL应用与SQL调优、MongoDB

NoSQL数据库、Redis内存数据库、实现RedisSession共享、SQL语句的优化、实现数据库读写分离、WEB应用集群及性能优化、Maven项目管理工具、Web服务器负载均衡、实现Nginx与Tomcat集群、使用LoadRunner测试工具、性能优化之内存调优、代码优化与重构的方法等。

对java有兴趣的小伙伴们,不妨先从java入门开始!B站上有很多的java教学视频,从基础到高级的都有,还挺不错的,知识点讲的很细致,还有完整版的学习路线图。也可以自己去看看,下载学习试试。

redis客户端执行命令4个过程: 发送命令-〉命令排队-〉命令执行-〉返回结果

过程称为 Round trip time (简称RTT, 往返时间),mget mset有效节约RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量 *** 作,需要 消耗N次RTT ,pipeline解决

比逐条执行要快,特别是客户端与服务端的 网络延迟越大,体能越明显

原生批命令: 原子性 ,            pipeline: 非原子性

原生批命令: 一命令多个key    pipeline: 支持多命令(存在事务)

原生批命令: 服务端 实现,     pipeline:服务端与客户端 共同完成

pipeline组装命令不能太多,不然数据量过大,增加客户端的等待时间,造成网络阻塞,可将 大量命令的拆分多个小pipeline命令:

redis提供 mset 、 mget 方法,但没提供 mdel 方法,如想实现,可借助pipeline

mset: 同时设置一个或多个 key-value 对。redis 127001:6379> MSET key1 value1 key2 value2 keyN valueN

1)获取jedis对象 (一般从连接池中获取)

2) 获取jedis对象 的pipeline对象

3)添加、执行指令

用pipeline提交所有 *** 作并返回执行结果:

为了保证pipeline原子性,redis提供了简单的事务。

1、redis的简单事务 :放multi和exec命令之间,multi代表事务开始,exec代表事务结束

2、停止事务discard:

3、命令错误,语法不正确,导致 事务不能正常结束

4、运行错误,语法正确,但 类型错误,事务可以正常结束

5、watch命令:用watch后, multi失效,事务失效

WATCH机制: 事务EXEC执行时,Redis检查被WATCH的key,只有被WATCH的key从 WATCH起始时至今没有发生过变更,EXEC才会被执行 ,变化则失败。

小结:redis提供简单事务,不支持事务回滚

GC是有条件的,我们的确可以在一定硬件基础上配置这个条件让GC少发生,GC是耗资源性能的,

很多时候我们都是通过减少GC来提高系统的性能。

你说得对,对象池的大小不会造成内存紧张,基本上jvm是不会回收的,但是我们不能保证。

所以不要把这个放到你的业务逻辑里去,就像尽量不要把异常与业务逻辑挂钩。

如果在你的程序里,能找到这样的一条引用方向,那么这个单体类是不会被回收的。

main->实例A->->实例D->你所说的单体

GC发生时,判断对象是否需要回收不是看是否被调用,而是是否被引用。

比如,main函数所在的类中所引用的成员变量List是不会被回收的。直到程序结束。

如果你的单体类只有一个,相信这个单体类还是一直被引用这比较好。这样就不会被回收了。

-------------------------

java对象是否被垃圾回收不是看时间长短的,

是看是否被使用着,如果没有被使用,又到了垃圾回收的条件时,

就会被回收的。

如果是被使用的,那么不管怎么样都不会被回收的。

如果是静态变量的话,看这个类是否被使用了。

以上就是关于java使用redis时不时的报没有可用的链接全部的内容,包括:java使用redis时不时的报没有可用的链接、如何用java实现基于JedisCluster对象的连接池、如何连接redis数据库等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10184122.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存