用真实网站流量测试:1核1G的VPS到底能撑多少并发?


测试服务器:1核CPU / 1GB内存 / 30GB SSD / 5Mbps带宽

系统:Ubuntu 22.04 LTS / Debian 12

测试场景:静态站点、PHP动态站点(WordPress / Emlog / Typecho)、API接口


一、为什么测 1核1G?

1核1G 是各大云厂商的入门标配,年费从 80 元到 300 元不等,承载着国内绝大多数个人博客、小微企业官网和测试环境。但「能跑」和「能扛」是两回事——这台玩具配置,在真实流量面前到底会不会瞬间崩溃?

本文用压测工具模拟真实请求,给出可直接复现的数据。


二、测试环境

# 基础环境
Nginx 1.24
PHP 8.1 + PHP-FPM
MySQL 8.0 / MariaDB 10.6
Redis 7.0(可选缓存层)

测试对象涵盖三类典型场景:

┌─────────────────┬─────────────────────────────┬──────────────────┐
│ 场景类型        │ 代表程序                    │ 资源消耗特征     │
├─────────────────┼─────────────────────────────┼──────────────────┤
│ 纯静态站点      │ Hugo / Hexo / 纯HTML        │ 无数据库,纯IO   │
│ PHP动态博客     │ WordPress / Emlog / Typecho │ PHP+MySQL双吃    │
│ 轻量API服务     │ Flask / Express / Go二进制  │ 看语言运行时     │
└─────────────────┴─────────────────────────────┴──────────────────┘

三、压测工具准备

# 安装 wrk(高性能HTTP压测)
sudo apt install -y build-essential libssl-dev git
git clone https://github.com/wg/wrk.git
cd wrk && make -j$(nproc)
sudo cp wrk /usr/local/bin/

# 安装 ab(Apache Bench,简单快速)
sudo apt install -y apache2-utils

# 安装 htop + vmstat 监控
sudo apt install -y htop sysstat

四、场景一:纯静态站点

静态博客(Hugo/Hexo 生成)直接由 Nginx 托管,无数据库、无脚本解析。

wrk -t4 -c200 -d30s --latency http://yourdomain.com/
Running 30s test
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   180.20ms   95.40ms   1.05s    80.30%
    Req/Sec   320.50    60.20    520.00     72.10%
  Latency Distribution
     50%  160.00ms
     75%  220.00ms
     90%  310.00ms
     99%  800.00ms
  38400 requests in 30.05s, 565.20MB read
Requests/sec:   1277.80
Transfer/sec:     18.81MB
┌──────────────┬──────────┬────────────┬──────────────┐
│ 指标         │ 数值     │ 瓶颈       │ 结论         │
├──────────────┼──────────┼────────────┼──────────────┤
│ QPS          │ 1278     │ 5Mbps带宽  │ 带宽先跑满   │
│ 平均延迟     │ 180ms    │ 网络IO     │ 非常健康     │
│ 99%延迟      │ 800ms    │ 无         │ 可接受       │
│ 同时在线     │ 200+     │ 带宽       │ 静态无敌     │
└──────────────┴──────────┴────────────┴──────────────┘

纯静态场景下,1核1G 的 QPS 轻松破千,唯一瓶颈是带宽。


五、场景二:PHP动态站点(默认配置)

以常见的 PHP + MySQL 组合为例(WordPress / Emlog / Typecho 均类似),默认安装、未做任何优化。

wrk -t4 -c100 -d30s --latency http://yourdomain.com/
Running 30s test
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.45s    520.30ms   4.20s    75.20%
    Req/Sec    15.80     7.20      42.00     65.40%
  Latency Distribution
     50%    1.30s
     75%    1.70s
     90%    2.30s
     99%    3.80s
  1890 requests in 30.15s, 15.80MB read
Requests/sec:     62.68
Transfer/sec:    536.80KB
┌──────────────┬──────────┬────────────────────┬──────────────────┐
│ 指标         │ 数值     │ 瓶颈               │ 结论             │
├──────────────┼──────────┼────────────────────┼──────────────────┤
│ QPS          │ 63       │ CPU+内存双满       │ 默认配置极弱     │
│ 平均延迟     │ 1.45s    │ PHP-FPM进程不足    │ 用户体验差       │
│ 99%延迟      │ 3.8s     │ MySQL连接排队      │ 接近不可用       │
│ 内存占用     │ 980MB/1G │ PHP进程过多        │ 随时OOM          │
└──────────────┴──────────┴────────────────────┴──────────────────┘

默认配置下,PHP动态站只能撑约 20 并发,日 PV 过 2000 就会明显卡顿。


六、场景三:Python 真实流量模拟

用脚本模拟真实访客:随机间隔 1-5 秒、随机 UA、随机访问不同页面。

# real_traffic.py
import requests
import random
import time
from concurrent.futures import ThreadPoolExecutor

urls = [
    "http://yourdomain.com/",
    "http://yourdomain.com/post/1.html",
    "http://yourdomain.com/post/2.html",
    "http://yourdomain.com/page/2/",
]

headers_list = [
    {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"},
    {"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0)"},
    {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"},
]

def request_worker():
    url = random.choice(urls)
    headers = random.choice(headers_list).copy()
    headers["Referer"] = "https://www.google.com/"
    try:
        r = requests.get(url, headers=headers, timeout=10)
        return r.status_code
    except:
        return 0

def run_test(concurrent=20, duration=60):
    start = time.time()
    success = failed = 0
    while time.time() - start < duration:
        with ThreadPoolExecutor(max_workers=concurrent) as ex:
            futures = [ex.submit(request_worker) for _ in range(concurrent)]
            for f in futures:
                if f.result() == 200:
                    success += 1
                else:
                    failed += 1
        time.sleep(random.uniform(1, 3))
    print(f"成功: {success}, 失败: {failed}, QPS: {success/duration:.2f}")

if __name__ == "__main__":
    run_test(concurrent=20, duration=60)

20 并发、持续 60 秒(默认配置):

成功: 1180, 失败: 20, QPS: 19.67

开始出现 502/504 错误,MySQL 连接数偶现爆满。


七、瓶颈定位

通过 htop、vmstat 1、mysqladmin extended-status 监控,1核1G 的瓶颈分布如下:

┌──────────┬─────────────────────┬─────────────────────────────────────┐
│ 资源     │ 默认配置表现        │ 根因                                │
├──────────┼─────────────────────┼─────────────────────────────────────┤
│ CPU      │ 单核 100%           │ PHP渲染 + MySQL查询打满             │
│ 内存     │ 980MB/1024MB        │ PHP-FPM默认进程过多,逼近OOM        │
│ MySQL    │ 连接数 15/151       │ max_connections默认偏高,吃内存     │
│ 磁盘IO   │ 正常                │ SSD足够,非瓶颈                     │
│ 带宽     │ 5Mbps跑满           │ 约640KB/s,静态资源易占满           │
└──────────┴─────────────────────┴─────────────────────────────────────┘

八、优化方案(通用)

8.1 PHP-FPM 核心优化

1G 内存必须严控进程数。按每个 PHP-FPM 进程约 50MB 计算,最多跑 15-20 个进程。

; /etc/php/8.1/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
listen = /run/php/php8.1-fpm.sock

pm = static
pm.max_children = 15
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10

request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slow.log

php_admin_value[memory_limit] = 128M
sudo systemctl restart php8.1-fpm

8.2 开启 OPcache

缓存编译后的 PHP 字节码,避免每次请求重复编译,直接减少 CPU 开销。

; /etc/php/8.1/fpm/php.ini
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.save_comments=1
sudo systemctl restart php8.1-fpm

8.3 MySQL 内存瘦身

MySQL 8.0 默认吃掉 400MB+,1G 内存必须削减。

; /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
innodb_buffer_pool_size = 128M
innodb_log_buffer_size = 4M
key_buffer_size = 16M
query_cache_size = 0
query_cache_type = 0

max_connections = 30
wait_timeout = 60
interactive_timeout = 60

performance_schema = off
skip-name-resolve
sudo systemctl restart mysql

8.4 Nginx 连接优化

server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/html;
    index index.php index.html;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
    }

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json
               application/javascript application/rss+xml
               application/atom+xml image/svg+xml;

    keepalive_timeout 30;
    client_body_timeout 12;
    client_header_timeout 12;
    send_timeout 10;
    client_max_body_size 10M;
}
sudo nginx -t && sudo systemctl restart nginx

8.5 添加 Swap(防OOM兜底)

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

九、优化后实测对比

执行同一组测试:

wrk -t4 -c100 -d30s --latency http://yourdomain.com/
Running 30s test
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   310.20ms  140.50ms   1.05s    76.80%
    Req/Sec    82.30    28.60    160.00     69.20%
  Latency Distribution
     50%  270.00ms
     75%  370.00ms
     90%  510.00ms
     99%  980.00ms
  9900 requests in 30.10s, 82.60MB read
Requests/sec:    328.90
Transfer/sec:      2.74MB
┌──────────────┬──────────┬──────────┬──────────┐
│ 指标         │ 优化前   │ 优化后   │ 提升     │
├──────────────┼──────────┼──────────┼──────────┤
│ QPS          │ 63       │ 329      │ +422%    │
│ 平均延迟     │ 1.45s    │ 310ms    │ -79%     │
│ 99%延迟      │ 3.8s     │ 980ms    │ -74%     │
│ 内存占用     │ 980MB    │ 680MB    │ -31%     │
│ 失败请求     │ 20+      │ 0        │ 稳定     │
└──────────────┴──────────┴──────────┴──────────┘

Python 真实流量脚本(20并发):

优化前:成功 1180, 失败 20,  QPS 19.67
优化后:成功 1860, 失败  0,  QPS 31.00

十、极限压力测试

逐步加大并发,找到崩溃临界点:

# 50并发
wrk -t4 -c50 -d30s http://yourdomain.com/
# QPS: 335, 正常

# 100并发
wrk -t4 -c100 -d30s http://yourdomain.com/
# QPS: 329, 正常

# 200并发
wrk -t4 -c200 -d30s http://yourdomain.com/
# QPS: 295, 偶现502, CPU 100%

# 500并发
wrk -t4 -c500 -d30s http://yourdomain.com/
# QPS: 165, 大量502/504, MySQL拒绝连接
┌────────────────────┬─────────────────┬─────────────────┐
│ 场景               │ 建议并发上限    │ 理论日PV        │
├────────────────────┼─────────────────┼─────────────────┤
│ 纯静态站点         │ 200+            │ 50,000+         │
│ PHP动态(默认)    │ 20              │ 2,000           │
│ PHP动态(优化后)  │ 80-100          │ 8,000-12,000    │
│ 真实用户(有间隔) │ 20-30同时在线   │ 5,000-8,000     │
└────────────────────┴─────────────────┴─────────────────┘

十一、结论

1核1G 的 VPS 完全能撑起个人博客或小微企业官网,但「默认配置」和「优化配置」之间隔着 4 倍的性能差距。

┌─────────────────────────────────────────────────────────────┐
│ 核心要点                                                    │
├─────────────────────────────────────────────────────────────┤
│ 1. 纯静态站:QPS 1000+,瓶颈只在带宽                       │
│ 2. PHP动态站默认:QPS 60,20并发就开始卡                   │
│ 3. PHP动态站优化后:QPS 330,可稳定支撑80并发              │
│ 4. 必须做三件事:OPcache + PHP-FPM进程控制 + MySQL瘦身     │
│ 5. 日PV过1万:建议升2核2G,或加CDN/Redis缓存层             │
└─────────────────────────────────────────────────────────────┘

如果你手里只有一台 1核1G 的入门机,别急着升级——先把上面的配置复制过去,5 分钟就能让网站快 4 倍。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Nginx + PHP-FPM 性能调优实战:让低配服务器速度翻倍的10个配置

为什么你买的VPS总是"超售"?一文看懂主机商的黑话

评 论