努力
加油

在2G内存的服务器上推荐如何配置LNMP以节省资源?

2G 内存跑 LNMP(Linux + Nginx + MySQL/MariaDB + PHP)在现在的标准下确实属于“极限操作”。如果是生产环境,我首先建议是加内存或者上容器化集群分摊负载;但如果受限于预算或测试需求,必须在这台机器上跑起来,那就得把每一兆内存都抠出来用。

核心思路就三个:Nginx 抗并发、PHP 精简扩展、MySQL 极致压缩。

下面是一套经过实战验证的、偏向保守但稳定的配置方案:

1. Linux 系统层优化

别装桌面环境,直接用最小化安装的 CentOS Stream 8/9 或 Ubuntu Server LTS。

Swap(交换分区)是救命稻草
2G 物理内存一旦爆满,进程直接 OOM Kill。必须开启 Swap,但不要太大,防止磁盘 IO 拖垮性能。

  • 建议大小:2G – 4G。
  • 调整 swappiness:让内核更倾向于使用物理内存,只有在实在不够时才用 Swap。
    # 查看当前值
    cat /proc/sys/vm/swappiness
    # 临时修改为 10
    sysctl vm.swappiness=10
    # 永久修改,编辑 /etc/sysctl.conf,添加 vm.swappiness=10

关闭不必要的服务

systemctl disable firewalld iptables # 如果用云厂商安全组,本地防火墙可关
systemctl disable auditd
systemctl stop postfix

2. Nginx 配置:轻量且高效

Nginx 本身很省内存,主要控制 Worker 进程数和连接数。

  • Worker 进程数:设为 CPU 核心数即可,2G 内存的服务器通常是 2 核或 4 核。
  • Keepalive 超时时间:适当缩短,减少空闲连接占用。
  • Buffer 设置:调小 client_body_buffer_size 和 proxy_buffer_size,默认可能偏大。
worker_processes auto; # 自动匹配 CPU 核心数
events {
    worker_connections 1024; # 2G 内存别开太高,512-1024 足够
    use epoll;
}
http {
    keepalive_timeout 65;

    # 关键:减小缓冲区,节省内存
    client_body_buffer_size 1k;
    client_header_buffer_size 1k;
    large_client_header_buffers 2 1k;

    proxy_buffer_size 1k;
    proxy_buffers 4 4k;

    # 开启 gzip 压缩,节省带宽并减轻后端压力
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 5;
    types_hash_max_size 2048;
}

3. PHP-FPM 配置:重中之重

PHP 是最吃内存的组件。2G 内存下,绝对不能让 PHP 产生大量子进程。

版本选择:强烈建议使用 PHP 7.4 或 PHP 8.0/8.1(配合 OPcache)。PHP 8 虽然启动稍慢,但内存管理有优化,且 JIT 对计算密集型任务友好。对于 Web 应用,PHP 7.4 的稳定性与资源占用平衡较好。

FPM Pool 配置 (www.conf)

采用 ondemand 模式,平时不占内存,来了请求再 fork。

[www]
user = www-data
group = www-data
listen = /run/php/php-fpm.sock

; 关键:动态模式
pm = ondemand
pm.max_children = 5       ; 最大同时处理 5 个请求,够了
pm.start_servers = 2      ; 启动 2 个预派生进程
pm.min_spare_servers = 1  ; 最少保留 1 个
pm.max_spare_servers = 3  ; 最多保留 3 个
pm.process_idle_timeout = 10s ; 空闲 10 秒后回收,快速释放内存

; 关键:限制每个子进程内存
php_admin_value[memory_limit] = 64M ; 单个 PHP 脚本最大内存 64MB

OPcache 配置 (php.ini)

开启 OPcache 能极大降低 CPU 和内存开销,因为不需要每次解析 PHP 源码。

opcache.enable=1
opcache.memory_consumption=64 ; 分配 64MB 给 OPcache,足够中小型项目
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60    ; 60 秒检查一次文件更新,开发环境可设 0,生产务必大于 0
opcache.validate_timestamps=1

4. MySQL/MariaDB 配置:极度克制

这是最容易 OOM 的地方。MySQL 默认配置会预留大量 Buffer Pool。

强烈建议:如果数据量不大(< 1GB),考虑用 SQLite 替代 MySQL,或者用 MariaDB 代替 MySQL(MariaDB 在某些场景下内存略低)。如果必须用 MySQL,请按以下参数调整 /etc/my.cnf 或 /etc/mysql/my.cnf:

[mysqld]
# 基础设置
innodb_buffer_pool_size = 128M ; 关键!不要超过总内存的 50%,128M-256M 足够
innodb_log_file_size = 32M
innodb_flush_method = O_DIRECT
query_cache_type = 0           ; MySQL 5.7+ 已废弃,MariaDB 10.1+ 也建议关闭,避免锁竞争和内存碎片
query_cache_size = 0

# 连接数限制
max_connections = 50           ; 2G 内存开 100 个连接必死,50 足够
thread_stack = 192K            ; 减小线程栈大小

# 其他优化
table_open_cache = 200         ; 减少文件描述符打开数量
sort_buffer_size = 256K        ; 排序缓冲
read_buffer_size = 256K        ; 读缓冲
join_buffer_size = 256K        ; 连接缓冲

# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

注意:innodb_buffer_pool_size 是内存大户。如果数据库表很小,甚至可以降到 64M。

5. 额外建议:架构层面的“省钱”技巧

  1. 静态资源分离:图片、CSS、JS 全部上传到 OSS/COS/S3,并在 Nginx 配置中直接返回 CDN 地址或XX到对象存储,不要让 PHP 去读取这些文件,也不要用 Nginx 做静态文件的缓存盘。
  2. 使用 Redis 做简单缓存:如果只有 2G 内存,Redis 也可以装,但配置要小。
    maxmemory 64mb
    maxmemory-policy allkeys-lru

    用它来缓存数据库查询结果,减少 MySQL 压力。

  3. 监控告警:安装 htop 和 nmon,或者简单的 shell 脚本监控内存使用。当内存使用率持续超过 85% 时,手动重启 php-fpm 或清理缓存。
  4. 应用代码优化:
    • 避免在循环中查库。
    • 使用 Composer 自动加载,而不是手写 include。
    • 如果可能,将非实时任务(如发邮件、生成报表)通过消息队列异步处理,或者干脆做成定时任务 cron job,避免阻塞 PHP-FPM 进程。

总结 checklist

组件 关键动作
OS 最小化安装,开启 2G Swap,swappiness=10
Nginx worker_connections 1024,减小 buffer,开启 gzip
PHP FPM 用 ondemand 模式,max_children=5,memory_limit=64M,开启 OPcache
MySQL innodb_buffer_pool_size=128M,max_connections=50,关闭 query_cache
整体 静态资源上 OSS,代码层面优化 SQL

这套配置能在 2G 内存服务器上稳定运行一个日均 PV 几千到一两万的 WordPress 或小型 CMS 网站。如果流量更大,唯一的出路就是升级硬件或拆分服务。