这个问题在我购买的腾讯云轻量应用服务器上频繁出现,往往是粘贴一个屏幕截图或者手机端上传一个图片时,服务器突然卡死,需要好一会儿才能恢复。轻量应用服务器的配置真的很一般,不过我仅是用作博客记录,所以应该是够用的,至少在之前使用lnmp框架时,几乎没有出什么问题。但是换用docker之后,就频繁出现了上述的情况,使我一度怀疑遭受了黑客的攻击。

经过查询得知应该是MariaDB对内存资源占用太高导致的,因为轻量服务器的内存实在是太小了只有1GB,所以即便是开一个站点其资源消耗就已经够呛了。因此解决方案在于如何优化Mariadb的内存占用。
限定容器(Container)的资源消耗
Docker中的每一个容器都可以设定其对内存资源和CPU的消耗上限,在使用docker compose工具的情况下其设置返利如下:
service:
image: nginx
mem_limit: 512m
mem_reservation: 128M
cpus: 0.5
ports:
- "80:80"
对于1GB的可怜内存,我将Mariadb的内存设定在了200MB,保留内存(mem_reservation)设置为其一半。经过测试如果限定内存为128MB时,数据库服务不会成功启动。同时我们也需要按照同样方法对wordpress容器做出限制,我将其内存限制设定在了256MB。
最低配置Mariadb
如果使用数据库默认配置,其对CPU和内存的占用要求数倍于当前的配置,因此我们需要修改/etc/mysql/my.cnf降低(minimum)其配置。因此我们需要建立一个.cnf文件匹配容器中的配置文件。
my_app_db:
image: mariadb:latest
mem_limit: 200M
mem_reservation: 100M
cpus: 0.5
container_name: app_db
volumes:
- ./mysql:/var/lib/mysql
- ./my.cnf:/etc/mysql/my.cnf
restart: always
至于.cnf文件中的内容,我们可以配置如下:
# The MariaDB configuration file
#
# The MariaDB/MySQL tools read configuration files in the following order:
# 0. "/etc/mysql/my.cnf" symlinks to this file, reason why all the rest is read.
# 1. "/etc/mysql/mariadb.cnf" (this file) to set global defaults,
# 2. "/etc/mysql/conf.d/*.cnf" to set global options.
# 3. "/etc/mysql/mariadb.conf.d/*.cnf" to set MariaDB-only options.
# 4. "~/.my.cnf" to set user-specific options.
#
# If the same option is defined multiple times, the last one will apply.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# If you are new to MariaDB, check out https://mariadb.com/kb/en/basic-mariadb-articles/
#
# This group is read both by the client and the server
# use it for options that affect everything
#
[client-server]
# Port or socket location where to connect
# port = 3306
socket = /run/mysqld/mysqld.sock
# Import all .cnf files from configuration directory
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mariadb.conf.d/
# /etc/my.cnf:
# http://www.tocker.ca/2014/03/10/configuring-mysql-to-use-minimal-memory.html
innodb_buffer_pool_size=5M
innodb_log_buffer_size=256K
query_cache_size=0
max_connections=10
key_buffer_size=8
thread_cache_size=0
host_cache_size=0
innodb_ft_cache_size=1600000
innodb_ft_total_cache_size=32000000
# per thread or per operation settings
thread_stack=131072
sort_buffer_size=32K
read_buffer_size=8200
read_rnd_buffer_size=8200
max_heap_table_size=16K
tmp_table_size=1K
bulk_insert_buffer_size=0
join_buffer_size=128
net_buffer_length=1K
innodb_sort_buffer_size=64K
#settings that relate to the binary log (if enabled)
binlog_cache_size=4K
binlog_stmt_cache_size=4K
在StackOverflow相关问题中,有提到关闭 performance_schema
,但是很遗憾我没有找到进行修改的位置。一说应该如上在/etc/mysql/my.cnf
中设置,但是我无论添加performance_schema=off
还是performance_schema=0
都会导致数据库服务启动不成功。不过目前看似问题已经解决,留待以后遇到问题再行调整。
Docker查看容器状态
通过docker stats
可以查看各个容器对资源的消耗情况。

@2022.10.06 问题并没有解决,当我从手机端上传图片的时候
文件上传未提示成功且服务器处于卡死状态:一开始我以为只有手机端才会有这个问题,后来发现从浏览器网页端同样会出现这个问题。查看系统日志:var/log/syslog
,没发现明确提示,但是总在宕机时间段附近有几个反复出现的字符qcloud
、YunJing
,于是一番搜索原来这是腾讯云的云服务器安全监控组件,搜索资料查证其对服务器资源的消耗着实影响不小。于是使用下述代码进行卸载:
/usr/local/qcloud/stargate/admin/uninstall.sh
/usr/local/qcloud/YunJing/uninst.sh
/usr/local/qcloud/monitor/barad/admin/uninstall.sh
或者使用如下的代码
chmod +x /usr/local/qcloud/YunJing/YDService
/usr/local/qcloud/YunJing/YDService stop
rm -rf /usr/local/qcloud
然后验证是否卸载干净,使用下述代码如无任何输出返回则表明已经卸载干净。
ps -A | grep agent
但是我使用了上面的代码仍然有一行返回值,不过通过登录后台法先确已关闭云监控。
root@VM-8-2-debian:~# ps -A | grep agent
660 ? 00:00:00 tat_agent

将腾讯云监控的组件关闭后,终于,上传媒体文件就不再引发宕机现象了。不过在手机端上传一些尺寸大于2mb的图片仍然提示失败,说明不能顺利上传图片不仅仅是因为腾讯云监控组件对资源的消耗。


WordPress ios APP上传文件提示失败,但是到wordpress的uploads文件中查看,该文件确实已经传上去了,但是却没有产生任何尺寸的缩略图,这意味着在php发挥作用裁切图片之前该服务就已经停止了。查看手机端,报错提示为http 502
。

于是又去翻查系统日志,在错误出现的时间给出了 Memory cgroup out of memery
提示,这意思就是内存不够了。

出现该问题的原因,是实际内存超出了容器内存的限制,一想起之前对wordpress的服务内存限制在256MB,于是赶紧修改调整到512MB,重启容器在上传手机拍摄的图片就没有上传失败的提示了
mem_limit: 512M
mem_reservation: 256M
那么将限制内存调整到了512MB,可以上传的最大文件大小是多少呢?在网页端上传100MB左右的视频都没有问题,但在手机端上传HLG格式视频无法成功(在网页端是可以成功上传的,但是默认播放器只闻其声而无法播放画面)。
参考资料: