出现这种问题从以下几个方面排查:
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数据库等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)