WordPress报错:Error establishing a database connection
WordPress报错:Error establishing a database connection

WordPress报错:Error establishing a database connection

问题描述

在编写一篇文章并查看网站关于CloudKit文章时,发现服务器突然打不开。

并且网站报错为:Error establishing a database connection。

在尝试刷新页面后,网站直接显示nginx错误!

紧接着,我开始检查云服务器的状态,打开腾讯云页面,发现公网的带宽很高。

让我想起,上一次也是发现带宽很高的问题,那就是《服务器公网带宽达到上限排查问题》,当时也是很快的恢复了问题,没有检查到具体的报错原因,当时估计是某一个ip访问频率过高,爬虫或其他问题,导致的带宽达到上限,因此考虑封锁掉这一ip来解决问题,但排查的过程中,发现问题自动解决了,因此没有深入检查。

接着,我登陆到服务器,使用top命令,查看服务器的CPU、内存的状态。

这里,按M键隐藏/显示内存信息,按Shift + M键按内存排序。

截图中,可以看到服务器负载很高,特别是内存方面,下面。

KiB Mem :  2046504 total,    65564 free,  1746560 used,   234380 buff/cache

总内存为2046504KiB(约2GB),可用内存仅64MB,系统主要依赖于228MB的缓冲和缓存,因为没有启用Swap空间,导致内存耗尽时服务崩溃。

:KiB和MB的计算方式,可以通过KiB / 1024进行计算,例如2046504KiB / 1024 = 1998.53MB,所以是2GB的内存。

快速解决方案

在定位到问题为内存后,首先启用Swap:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

启用Swap后,使用free -m命令,检查是否启用成功:

free -m

持久化到系统启动:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

接着需要释放内存:

sudo sync; sudo sysctl -w vm.drop_caches=3

当启用Swap后,重新访问页面,发现问题已经得到解决。

检查腾讯云的监控系统,也可以看到内存已经逐渐恢复到正常的使用区间,而刚才出现问题时,内容使用量在监控是1.7GB。

返回到服务器上,使用top命令,检查内存使用情况:

内存已经恢复正常,现在Swap交换内存没有使用,同时内存也有470MB,缓冲和缓存是389MB。

问题原因

问题恢复后,我通过查看Shynet监控系统发现,当时有一个用户在访问我的文章时,出现了多次请求的情况,仅在Shyenet中,就出现了127次。因此,可能这个用户的网络环境不稳定,导致在访问同一个页面时,出现重复请求的情况。

最后,问题的定位就是这个用户在访问页面时,出现重复请求的情况,导致服务器的内存不足,从而引发WordPress和Nginx的崩溃。

总结

从复盘的角度来看,主要还是当前云服务器的2GB内存不足,无法满足现有的网站访问,一旦出现类似的重新请求问题,大概率就会直接挂掉。从硬件的角度考虑,后期有条件会自己搭建服务器并提高服务器的整体配置,目前的配置已经不足以满足网站的使用。

另一点就是,当存在重复访问的情况时,可以考虑阻止异常IP,例如通过下面的检查命令,来阻止异常IP:

网络连接检查

高负载可能来自外部流量。

netstat -ant | grep ESTABLISHED | wc -l

如果连接数异常高,进一步分析来源:

netstat -anp | grep :80

阻止异常 IP:

sudo iptables -A INPUT -s <IP地址> -j DROP

配置 Nginx/Apache 速率限制:

limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

如果有类似的监控系统,可以检查到异常IP,并添加到iptables中,暂时阻止其访问。如果你也是在Docker上部署的WordPress,可能无法从netstat上查看外部流量,因为只能查看到自身的ip。

这里,我使用了一个netstat命令检查外部连接到80端口的IP,但实际上只有自己的ip。

下面是这个检查命令:

netstat -anp | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

扩展知识

为什么启用Swap有帮助?

启用 Swap 的主要目的是在物理内存不足时,为系统提供额外的虚拟内存,避免因内存耗尽导致的进程被杀死(例如 OOM Killer)。但是,Swap 只是一种补救措施,性能远不如物理内存,因此需要优先排查和优化内存消耗的原因。

1、防止系统崩溃

当内存不足时,Swap 允许系统将部分不活跃的内存页(例如后台任务或缓存)移动到硬盘,释放物理内存给活跃的进程。

2、减少 OOM 风险

如果没有 Swap,当内存耗尽时,系统可能直接终止某些重要进程(通常由 OOM Killer 决定)。

3、优化性能

即使性能会有所下降,启用 Swap 能暂时缓解高负载场景,提供时间进行修复。

命令解析

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo sync; sudo sysctl -w vm.drop_caches=3

在前面提到两个命令,一个是持久化Swap,另一个是清除内存中的缓存命令。

1、echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab

作用

将一个用于启用 Swap 的配置行写入 /etc/fstab 文件中,从而让系统在每次启动时自动加载该 Swap 文件。

分解解释

echo ‘/swapfile none swap sw 0 0’

将字符串 ‘/swapfile none swap sw 0 0’ 输出到标准输出(通常是终端)。

这是一行 fstab 文件的配置,含义如下:

/swapfile: 指定 Swap 文件的路径。

none: 文件系统类型(Swap 文件没有挂载点,因此为 none)。

swap: 指定该条目用于 Swap 分区。

sw: 挂载选项,表示启用 Swap。

0 0: 不需要备份或检查该文件。

sudo tee -a /etc/fstab

tee 将输入内容(即 echo 输出的内容)同时写入文件 /etc/fstab。

-a 选项表示追加内容(append),不会覆盖文件中的现有内容。

sudo 提供管理员权限,因为 /etc/fstab 文件通常需要特权才能修改。

结果

修改后的 /etc/fstab 文件包含一行配置,用于在系统启动时自动加载 /swapfile 作为 Swap 空间。

2、sudo sync; sudo sysctl -w vm.drop_caches=3

作用

用于手动释放内存中的缓存,释放结果不会影响当前运行的程序。

分解解释

sudo sync

同步数据到磁盘。

将文件系统的所有挂起写操作(如写缓冲)立即写入硬盘,确保数据已保存到持久存储。

这是在清除缓存前的安全操作,避免因清理缓存导致数据丢失。

sudo sysctl -w vm.drop_caches=3

修改内核参数,手动清理内存中的缓存。

vm.drop_caches 是 Linux 内核的一个参数,用于释放不同类型的内存缓存:

1: 释放页面缓存(page cache)。

2: 释放目录项和 inode 缓存(dentry 和 inode cache)。

3: 同时释放页面缓存、目录项和 inode 缓存。

注意事项

清理缓存不会影响当前运行的程序,但可能会导致程序在下一次访问数据时性能下降(因为数据需要重新加载到缓存中)。

这是一个临时操作,缓存会在需要时重新增长。

结果

执行完后,系统的可用内存会暂时增加,因为缓存被释放掉了。这在排查内存问题或需要腾出内存时有用。

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注