周六生产服务器出现redis服务器不可用状态,错误信息为:

状态不可用,等待后台检查程序恢复方可使用。Unexpected end of stream; expected type 'Status'

如下图所示,下图6300就是我们redis服务器运行的端口。

头一次碰到此类问题,心想难道是redis挂掉了,随即通过telnet ip+端口。发现运行正常,然后就想着进入redis看下目前连接情况。一看发现竟然高达1903条这么多。

然后想着应该是代码创建redis连接过多导致的,查看代码。

发现redis创建只有这一个地方有,这里也是服务注册时才执行。也就是应用程序启动时才被执行一次。然后整个项目查找,没有其他地方再有调用redis初始化。

心有不甘,难道是每次在redis读写数据时都会创建连接吗?会和读写频繁有关系吗?总感觉不会啊,随即创建测试代码进行测试一番。

在本地搭建了一个redis环境,测试之前先看看接数多少,目前看只有1个,也就是目前的cmd连接客户端,这个属于正常的了。

开始测试,运行程序。代码是创建一个连接对象,并一共测试1000次写,和1000次读。

不管我怎么测试连接都是6个,那么也就是说我们程序最多创建了5个连接,当然主要有线程池在里面。

所以基本的存储读取这块代码肯定是没问题。

但代码这块也没算完全放弃排查,因为生产服务器通过docker运行着大约6个应用程序。都是连接的同一个redis,会不会是其他应用程序导致的?

然后就想直接通过redis 连接列表里的中随便一个端口来查询对应的进程信息就可以知道是哪些应用程序了。

Linux 中通过查询网络端口号显示进程信息。

netstat -atunlp | grep 60852 

首先看这端口对应的IP,比如这里第一个是172.17.0.1。熟悉docker的同学应该知道这个ip是docker网关IP。我们容器中的程序都是通过这个网关IP来和我们宿主主机来通讯的。我们通过ifconfig就能发现docker这个网关IP,第二个172.17.0.3:6379这个一看就是redis的容器IP,

这样一看确实无法找到具体对应哪个容器中的程序和我们建立连接的。

有一个最笨的办法就是挨个进入容器里面。即docker exec –it test /bin/bash 然后查看当前容器的网络连接情况。这样非常麻烦,并且需要安装很多组件才能执行一系列命令。

另外一个办法lsof命令,如果没有则需要安装。我们可以通过进程去找所有网络连接情况。

比如我们刚发现我们的进程主要是docker,他的pid是582251。

lsof -i |grep 582251或者 lsof -i -p 582251

结果如下图,右边其实出现了具体IP,这个IP就是docker容器具体的IP地址。

现在知道所有IP和端口了,我们将命令执行结果下载下来。

首先找到自己每个容器对应的IP。

docker inspect name |grep IPAddress    //name 容器名称或者id

找到每个ip后然后根据刚下载的所有网络连接信息进行统计,看哪个IP连接最多,最多的一个肯定有问题。

然后我就找到这个IP对应的容器部署的程序,然后看redis配置。发现线程池设为200。

另外我通过github,发现CSRedisCore还有个预热机制,也就是preheat,他默认值就是5个预热连接。

我们线程池设置的是200加上本身有个预热机制5个连接,我不知道是不是会创建200*5=1000个。这个有时间再好好研究下源代码,目前只是猜测。

我现在已经将redis修改为poolsize=5, preheat=false。线程池5个,并且关闭预热机制。

修改我们连接配置,并重启应用服务器和redis服务器(为了彻底清除已建立的连接)后发现连接数有减少,但没有很多。后来查询发现,是redis的idle空闲时长太长,导致连接池维持太多连接,没有被释放。

我们设置下超时为30s

执行CONFIG SET timeout 30 (单位是秒,此种方式只是临时修改,针对当前运行有效。长效记得修改redis配置文件)

然后再看下连接数多少,这样一下子就减少了很多。

总结:

1、 redis连接暴增,首先从自身应用程序出发去寻找问题,比如我这边发现的连接池设置过大,加上默认的预热机制等。还有尽可能的看代码层面在创建连接是否会被多次触发,如果有就必须要改正。现在都是通过注入的方式创建实例,要看该地方是存在被多次调用。

2、修改redis服务器配置,比如连接空闲超时时间。包括也可也看下最大连接数多少,默认值。

记一次Docker中Redis连接暴增的问题排查的更多相关文章

  1. 【docker】【redis】2.docker上设置redis集群---Redis Cluster部署【集群服务】【解决在docker中redis启动后,状态为Restarting,日志报错:Configured to not listen anywhere, exiting.问题】【Waiting for the cluster to join...问题】

    参考地址:https://www.cnblogs.com/zhoujinyi/p/6477133.html https://www.cnblogs.com/cxbhakim/p/9151720.htm ...

  2. 《高并发下的.NET》第2季 - 《memcached连接暴增案》第1集:问题表现

    在<.NET 5.0 背锅案>第7集-大结局之后,园子和 .NET 继续过上了幸福生活...剧情很美好,现实很残酷...现实是旧案刚结,新案立至,而且新案与旧案有关联,被迫继续拍剧,并对该 ...

  3. 数据库实战案例—————记一次TempDB暴增的问题排查

    前言 很多时候数据库的TempDB.日志等文件的暴增可能导致磁盘空间被占满,如果日常配置不到位,往往会导致数据库故障,业务被迫中断. 这种文件暴增很难排查,经验不足的一些运维人员可能更是无法排查具体原 ...

  4. 记一个在docker中运行多线程event_loop.run_forever()的bug

    问题简介 我写爬虫,用到了asyncio相关的事件循环,新建了一个线程去run_forever(),在docker中运行.后来程序有异常,主线程挂了,但是竟然不报错.查了很久,才找出来. 如果你新建一 ...

  5. 记一次Docker中部署Asp.Net Core 3.0的踩坑过程

    最近公司打算重构目前直销报单系统到微信小程序中,目前的系统只能在PC上面使用,这两年也搞过App端,但是由于人员流动和公司架构调整最后都不了了之,只留下一堆写了一半的接口.以前的接口依然是使用Asp. ...

  6. docker启动redis并使用java连接

    一.先查找镜像 docker search redis 二.拉取镜像 docker pull redis三.等待拉取完毕 四.查看拉去的镜像 docker iamges 五.运行redis 连接1:h ...

  7. Oracle归档日志暴增排查优化

    1.ORACLE归档日志介绍 归档日志暴增是oracle比较常见的问题,遇到归档日志暴增,我们该如何排查: 归档日志暴增一般都是应用或者人为引起的 理解归档日志存储的是什么 如何排查归档日志暴增原因 ...

  8. 故障排查实战案例——某电器ERP系统日志暴增

    前言 本篇文章写在新春佳节前夕,也是给IT运维朋友一个警醒,在春节长假前请妥善体检自己的系统安心过个年. 千里之堤毁于蚁穴,一条看似简单的语句就能拖垮整个系统,您的SQL Server很久没体检了吧? ...

  9. Docker中使用redis

    项目中频繁使用Redis,为了不用每次打开Redis目录去启动Redis想到了Docker可以作为Redis的容器 直接下载使用就行 把Docker使用Redis的过程分享下:   1.     拉取 ...

随机推荐

  1. luoguP3121解题报告

    p3121 本题首先利用一个手写栈,使元素可以快速出栈,再利用栈快速查询上一个元素在trie中的位置.

  2. 我的linux学习日记day3

    ifconfig  查看网卡信息 uname 查看系统内核.版本信息 cat /etc/redhat-release uptime 查看系统负载信息 top命令的第一行信息 free 查看内存信息 f ...

  3. Apache Hudi典型应用场景知多少?

    1.近实时摄取 将数据从外部源如事件日志.数据库提取到Hadoop数据湖 中是一个很常见的问题.在大多数Hadoop部署中,一般使用混合提取工具并以零散的方式解决该问题,尽管这些数据对组织是非常有价值 ...

  4. 【python代码】 最大流问题+最小花费问题+python(ortool库)实现

    目录 基本概念 图 邻接矩阵 最大流问题 python解决最大流问题 python解决最大流最小费用问题 基本概念 图 定义: 图G(V,E)是指一个二元组(V(G),E(G)),其中: V(G)={ ...

  5. PAT-1064 Complete Binary Search Tree(完全二叉树)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  6. C#日志记录类

    public class WriteLog { /// <summary> /// 将错误写入文件中 /// </summary> /// <param name=&qu ...

  7. MySQL常见6个考题在实际工作中的运用

    题目一 MyISAM和InnoDB的区别,什么时候选择MyISAM 参考回答 InnoDB是目前MySQL主流版本(5.6.5.7.8.0)默认的存储引擎,支持事务.外键.行级锁,对于并发条件下要求数 ...

  8. 获取cookie里面的sessionid

    做接口的时候我们需要获取一个令牌,类似于token以及sessionid这样的签名,也可以说是一个令牌. import urllib.request, urllib.parse, urllib.err ...

  9. 一文带你了解nginx基础

    学习nginx,就要先了解什么是nginx,为什么使用nginx,最后才是了解怎么使用nginx nginx简介 nginx安装 一.Linux中安装nginx 二.Docker中安装nginx 三. ...

  10. MySQL递归查询

    MySQL8.0已经支持CTE递归查询,举例说明 CREATE TABLE EMP (EMPNO integer NOT NULL, ENAME ), JOB ), MGR integer, HIRE ...