搭建LNMP时,2G内存的服务器需要优化哪些配置?

2G 内存跑 LNMP(Linux + Nginx + MySQL/MariaDB + PHP),属于典型的“小马拉大车”。如果不做优化,稍微有点并发或者跑几个动态页面,服务器直接 OOM(Out of Memory)重启,或者 Swap 把磁盘 IO 打满导致响应极慢。

核心思路就两个:极致压缩数据库和 PHP-FPM 的资源占用,以及合理配置 Nginx 的缓冲。别想着加内存,先榨干这 2G 的每一滴性能。

以下是我在实际生产环境(特别是阿里云、腾讯云轻量应用服务器)中验证过的配置方案:

1. MySQL/MariaDB 优化(重中之重)

MySQL 是吃内存大户。默认配置在 2G 机器上基本就是自杀。你需要修改 my.cnf (或 mariadb.conf)。

关键参数调整:

[mysqld]
# 基础设置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# 连接数限制
# 2G 内存不要开太多连接,默认 151 太多了,设低一点防止瞬间爆内存
max_connections = 50 

# 关键:每连接变量
# thread_cache_size: 缓存线程,减少创建销毁开销
thread_cache_size = 8
# table_open_cache: 打开表的数量,根据站点大小调整,一般 200-500 足够
table_open_cache = 400

# 关键:InnoDB 缓冲池 (INNODB_BUFFER_POOL_SIZE)
# 这是最关键的参数。建议设置为物理内存的 30%-40%。
# 2G 内存的话,设 768M 到 1G 比较安全。
# 注意:如果同时跑其他服务,别给太大,否则系统本身会崩。
innodb_buffer_pool_size = 768M

# 日志相关
# 关闭二进制日志(如果是非主从架构,且对数据实时性要求不高,可考虑关闭以节省 IO 和内存)
# log-bin=mysql-bin 
# binlog_format=mixed

# 临时表
tmp_table_size = 64M
max_heap_table_size = 64M

# 查询缓存 (Query Cache)
# 注意:MySQL 5.7 之后 Query Cache 被标记为废弃,MariaDB 仍支持。
# 在高并发写场景下,Query Cache 反而成为瓶颈。
# 如果你的网站读多写少,可以开启;如果动静结合或写入频繁,建议关闭。
query_cache_type = 0
query_cache_size = 0

操作建议:

  • 使用 MariaDB 代替 MySQL:在 CentOS/RHEL 等系统中,MariaDB 通常更轻量,兼容性极好,且在相同硬件下性能往往略优。
  • 监控 QPS/TPS:优化后观察 show status like 'Threads_connected'; 和 show status like 'Created_tmp%';。如果 Created_tmp_disk_tables 很高,说明临时表落盘了,适当调大 tmp_table_size。

2. PHP-FPM 优化(控制并发进程数)

PHP-FPM 的每个子进程都会占用独立内存。2G 内存下,必须严格控制 pm.max_children。

找到 php-fpm.d/www.conf 文件,修改以下参数:

; 启动模式:static 或 on-demand
; 对于 2G 内存,推荐 on-demand(按需启动)或者 static 但数值很小
pm = dynamic 

; 最小空闲进程数
pm.start_servers = 2

; 最大空闲进程数
pm.min_spare_servers = 2

; 最大空闲进程数
pm.max_spare_servers = 5

; 【最关键】最大子进程数
; 计算公式参考:总内存 / (单个 PHP 进程平均内存 * 1.2)
; 假设你的 PHP 脚本平均每个进程占 30MB-50MB 内存
; 2048MB - 512MB(留给系统和 MySQL) = 1536MB 可用
; 1536 / 40 ≈ 38 个进程。为了保险,设 20-30 个。
pm.max_children = 25

; 单次请求后重启子进程(防止内存泄漏累积)
pm.max_requests = 500

如何估算单个 PHP 进程内存?
你可以用 top 命令查看 php-fpm 进程的 RSS 列平均值。如果不确定,先按 30-40MB 估算。如果你的代码引入了大量第三方库(如 Laravel, WordPress 插件多),单个进程可能高达 100MB+,那 max_children 就要降到 10 左右。

额外建议:

  • 启用 OPcache:确保 php.ini 中 opcache.enable=1。
    opcache.memory_consumption=128
    opcache.max_accelerated_files=10000
    opcache.revalidate_freq=60

    这能极大降低 CPU 和内存开销,避免重复编译 PHP 代码。

3. Nginx 优化(利用内存做缓冲)

Nginx 本身很省内存,但可以通过调整缓冲区来减少对后端 PHP 和上游资源的压力。

http {
    # 客户端请求头缓冲区
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;

    # 输出缓冲区
    output_buffers 1 32k;
    postpone_output 1460;

    # 发送文件模式
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    # 保持连接超时
    keepalive_timeout 65;

    # 针对静态资源开启 gzip
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_comp_level 2;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
}

重点:

  • 开启 Gzip:大幅减少传输数据量,虽然增加一点点 CPU,但对带宽敏感的小服务器非常有效。
  • Proxy Cache:如果流量稍大,可以考虑配置 Nginx 的 proxy_cache,将动态生成的 HTML 或 API 响应缓存到磁盘或内存中,减轻 PHP 和 MySQL 的压力。

4. Linux 系统级优化

A. 交换空间 (Swap) —— 救命稻草,但不是主力

2G 内存必须开 Swap,但不能太大,也不能太激进。

# 创建一个 2G 的 swap 文件(与内存 1:1)
dd if=/dev/zero of=/swapfile bs=1M count=2048
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

调整 Swappiness:

# 默认是 60,表示倾向于使用 swap。对于 SSD,可以设为 10,尽量先用物理内存。
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf

B. 内核参数微调

编辑 /etc/sysctl.conf,添加或修改:

# 允许重用 TIME_WAIT sockets
net.ipv4.tcp_tw_reuse = 1
# 缩短 TIME_WAIT 时间
net.ipv4.tcp_fin_timeout = 30
# 本地端口范围扩大
net.ipv4.ip_local_port_range = 1024 65535
# 防火墙连接跟踪表大小(如果并发高,需增大)
net.nf_conntrack_max = 65535

执行 sysctl -p 生效。

5. 应用层建议

  1. 禁用不必要的服务:systemctl disable firewalld iptables(如果用云厂商安全组)、disable postfix 等不用的服务,释放内存。
  2. 使用 CDN:这是最便宜的优化。把图片、JS、CSS 全部推到 CDN(阿里云 OSS/CDN,腾讯云 COS/CDN)。2G 服务器的带宽通常只有 3Mbps-5Mbps,静态资源一旦走 CDN,服务器负载下降 80% 以上。
  3. Redis 缓存:如果业务逻辑复杂,务必上 Redis。2G 内存分 256MB 给 Redis 绰绰有余。将热点数据放入 Redis,能显著减少 MySQL 查询次数。
  4. 选择轻量级框架:如果还在用大型框架(如 Spring Boot, .NET Core),请慎重。LNMP 最佳搭档是 PHP 轻量框架(ThinkPHP, Laravel 精简版)或原生 PHP。Java/.NET 应用在 2G 内存下几乎无法流畅运行。

总结检查清单

组件 关键动作 目标
MySQL innodb_buffer_pool_size=768M, max_connections=50 防止 OOM,提高查询速度
PHP-FPM pm.max_children=25, on_demand 或 dynamic 控制并发进程,避免内存爆炸
OPcache 启用并配置合理内存 减少 PHP 解析开销
Nginx 开启 Gzip, 调整 Buffer 减少带宽占用,提升响应
System 开启 2G Swap, swappiness=10 提供内存溢出保护
架构 静态资源上 CDN, 引入 Redis 减轻服务器计算和存储压力

最后提醒:
2G 内存适合个人博客、小型企业官网、内部管理系统。如果遇到突发流量(如秒杀、热点事件),这种配置一定会扛不住。这时候,横向扩展(加多台服务器)比纵向升级(加内存)在成本上更合理,或者直接使用云厂商的弹性伸缩服务。

未经允许不得转载:CLOUD云枢 » 搭建LNMP时,2G内存的服务器需要优化哪些配置?