今天重新部署了一个项目,该项目启动的时候会访问MongoDB获取一些数据,一个蛮简单的项目,从前发布都没问题,这次启动的时候直接就是Socekt Exception:
nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: socket exception [SEND_ERROR] for x.x.x.x:xx
第一反应是内网网络不太好,网络波动嘛,经查有的事儿。
解决办法:多试几次……
很明显,这个办法没解决问题(这要是解决了就不会在这儿写这个了)。同时ping mong实例所在的主机,0.3ms之内就返回了,也没有丢包。
然后去mongo那边看了看,也没啥问题,运行的很正常,log里也没什么错误。 而且Mongo这边配置的最大连接数是2W,这连接现在才用了不到9000啊。
这事情就比较奇怪了,以前从来没遇到,既然是Socekt Exception只能继续忘网络方向想了。
首先查看一下tcp连接中各个状态的连接数:
admin@linux:~> netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 3615
CLOSE_WAIT 130
FIN_WAIT1 11
FIN_WAIT2 69
ESTABLISHED 1983
SYN_RECV 7
CLOSING 23
LAST_ACK 39
LISTEN 30
这个命令呢,我也是搜来的,上面显示的是一台服务运行正常的机器上面的结果,而出问题那台呢,ESTABLISHED有6000多,这明显不科学呀,就业务层面来看,它的压力应该更小点才对。
这得看一下这多出来的连接是和哪台机器建立的,继续:
netstat -an |grep ESTA |awk '{print$5 "\n"}' |awk 'BEGIN {FS=":"} {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a]}' |sort -k 2 -nr
打印出来所有和该机器建立连接的IP以及连接数,一看果不其然是跟mongo所在的机器建立的连接超多,占到了ESTABLISHED连接的绝大部分。
这得看一下是哪个进程出的问题,继续:
netstat -anp |grep ESTA |awk '{print$7 }' |awk ' {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a]}' |sort -k 2 -nr
这样看一下到底哪些进程占用的ESTABLISHED连接多,拿到进程号之后,很容易找到对应的服务,结果呢另外一个服务占用了很多ESTABLISHED连接。
netstat -anp | grep {pid}| grep ESTA |awk '{print$5 "\n"}' |awk 'BEGIN {FS=":"} {COUNT[$1]++}END{for(a in COUNT) print a, COUNT[a] }'
跟据pid反过来可以查看此进程和哪些机器建立了连接,以及建立了多少连接。
这个服务居然占用了5000个mongo连接,太夸张了!!大概就是它把连接占完了,这就是罪魁祸首了!
等等,我们的mongo不是最大有2w个连接吗?就算这个出奇的占了这么多也不至于让别的起不来呀!先把5000这个错误修正让服务跑起来再说,检查了一下,这是配置上的问题,
connections-per-host
这个参数配置成了500,改成一个合理的值比如100,所有都恢复正常了,原先的服务也能起来了。
接下来分析两个问题:
-
connections-per-host
这个参数是什么意思
-
mongo的最大连接数怎么没生效
先说第二个,这个比较简单。
主要原因在于,即使mongo的配置里面最大连接数是2w,系统里面每个进程的最大打开文件数(open files)只有65535,所以mongo的最大连接数其实也只有65535。连接数有问题的那个服务占掉了5000个,剩下的被其他服务占用了,所以重新部署的那个服务无法再获得新的连接了。
这个地方唯一比较让人郁闷的是mongo这边log里也没报错……
再说第一个问题。官方API中对这个参数的解释是这样的:
The maximum number of connections allowed per host for this Mongo instance.
。允许每个host对这个Mongo实例创建的最大连接数。 根据使用的情况,个人反倒觉得解释为允许每个process对这个Mongo实例创建的最大连接数更合适一些。如果是允许每个机器创建的最大连接数,那么同一台机器上不管部署多少个服务连接到这个Mongo上面,这个机器和Mongo之间的最大连接数都应该是设置的这个值,可实际情况并不是这样。
另外,也没发现Mongo连接池有回收的机制,依据个人使用经验,连接数目基本上只增不减(即使在不需要这么连接的时候),最多增至设置的
connections-per-host
。
上面这些分析是个人的一个见解,可能不准确,欢迎指正。
Spring Boot项目连接Redis报错
org
.
springframework
.
data
.redis.serializer.Serialization
Exception
: Cannot deserialize;
nested
exception
is
org
.
springframework
.core.serializer.support.SerializationFailed
Exception
: Failed to deserialize payload. Is the byte ar
出现了连接被拒绝,这个问题很简单,是因为
MongoDB
的配置文件默认是本地ip访问,需要改配置文件,而不是说在application启动类上去排除某些配置类。确保配置文件无错,还需要关闭主机的防火墙,如果是服务器不要忘记了开放27017的端口号。bindIp 改成 0.0.0.0。
报的异常如下
org
.
springframework
.
data
.
mongodb
.
Unc
ategorized
MongoDb
Exception
: Interrupted acquiring a permit to retrieve an item from the pool ;
nested
exception
is com.
mongodb
.MongoInterrupted
Exception
: Inte...
使用Studio3T或者Compass等
MongoDB
的GUI工具连接
MongoDB
不操作一段时间,就会掉线。但重连速度很快。
使用Java的Mongo连接驱动,也是一段时间不操作,再去操作会出现异常(
Socket
Tim...
org
.
springframework
.
data
.
mongodb
.
Unc
ategorized
MongoDb
Exception
: Query failed with error code 2 and error message 'Field 'locale' is invalid in: { locale: "message" }'...
org
.
springframework
.
data
.
mongodb
.
Unc
ategorized
MongoDb
Exception
:
Exception
authenticating MongoCredential
线上的列表在运行过程中突然爆出了一个
Mongodb
查询的BUG,错误如下:
“
exception
”:”
org
.
springframework
.
data
.
mongodb
.
Unc
ategorized
MongoDb
Exception
”,
“message”:”Query failed with error code 96 and error message ‘Executor...
线上跑批插入数据到mongo的过程中,会不定时的出现
Unc
ategorized
MongoDb
Exception
这个异常,发生的次数不是很多,但是看着很烦;于是乎查阅了一下资料;
spring整合mongo的时候
添加:max-connection-idle-time=“60000” 最大空闲连接时间属性后,该异常没有在发生;
报错 com.
mongodb
.Mongo
Socket
Open
Exception
:
Exception
opening
socket
发现原因 我们的项目是父子项目,父项目是别人建的 里面添加
mongodb
的 starter ,而我的子项目并不需要连接
mongodb
我也没有配置
mongodb
的信息。
解决办法,修改启动类注解
@SpringBootApplication...