docker中的archlinux运行springboot项目出现异常

今天用docker中的archlinux容器运行springboot项目出现了如下异常
[root@488da3419a79 data]# java -jar springboot_01_quick_start-1.0-SNAPSHOT.jar library initialization failed - unable to allocate file descriptor table - out of memoryAborted (core dumped)
虽然英语不太好但是看见了out of memory*字样总感觉像是内存溢出。
问了一下chatgpt,其回答如下:
这个错误信息表示在尝试运行 java -jar 命令时发生了内存不足错误。错误信息中的 “unable to allocate file descriptor table” 表示 JVM 无法为新的文件描述符分配足够的内存。

这可能是因为您的系统没有足够的内存来分配文件描述符表,或者您的系统可能已经达到了文件描述符的最大限制。文件描述符是操作系统用于跟踪打开的文件和网络连接的标识符。

如果您遇到这个错误,可以尝试以下几个解决方法:

增加系统内存:如果您的系统没有足够的内存来分配文件描述符表,您可以尝试增加系统内存,以便 JVM 可以分配更多的内存。

增加文件描述符限制:如果您的系统已经达到了文件描述符的最大限制,可以尝试增加文件描述符的限制。您可以使用 ulimit 命令来检查和更改文件描述符限制。例如,要将限制增加到 65536,可以运行以下命令:

Copy
ulimit -n 65536


关闭不必要的文件句柄:如果您的系统有太多打开的文件句柄,则可以尝试关闭不必要的文件句柄。您可以使用 lsof 命令来检查当前打开的文件句柄。例如,要查看当前打开的文件句柄数,可以运行以下命令:

Copy
lsof | wc -l

如果您发现有太多的文件句柄,可以尝试关闭不必要的文件句柄来释放文件描述符。

机器人说文件描述符的最大限制太小了于是我查看了一下:
[root@e9a2770c7e99 ~]# ulimit -a real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 27328 max locked memory (kbytes, -l) 8192 max memory size (kbytes, -m) unlimited open files (-n) 1073741816 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
很显然 open files显然不小,可以说是很大。
遂以为是容器的内存太小导致的
通过docker stats 查看了一下
CONTAINER I
NAME
CPU %
MEM USAGE / LIMIT MEM %
NET I/O
BLOCK I/O ize (6 PIDS-C) n inited
488da3419a79
arch1
0.08%
224.8MiB / 6.71GiB3.27%
10.3MB
284kB
86.2MB15MB38 initedschedulin
内存是6.71G,看来是和宿主机是共享的,应该也不是内存太小的问题。
然后百度了一下看到一篇文章说参数并不是越大越好。于是就把openfiles的参数调小了
命令
ulimit -n 65536
然后再次启动,成功了。
看来真是open files的值默认设置的太大了,仔细数了一下10亿。。。。。。
至于为什么docker默认的openfiles的默认值为什么这么大以及这么大为什么报错,暂时也不得而知。


重启容器发现open files的值又恢复到了以前需要重新设置。
编辑/usr/lib/systemd/system/docker.service

sudo nano /usr/lib/systemd/system/docker.service

注意不同的系统可能服务配置文件路径不同
原ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock修改为:
ExecStart=/usr/bin/dockerd --default-ulimit nofile=65535:65535 -H fd:// --containerd=/run/containerd/containerd.sock

重新载入配置:
❯ systemctl daemon-reload

参考文章:http://www.dtmao.cc/Html5/88136.html

你可能感兴趣的:(docker,spring,boot,容器,linux)