在 1核 1G(1 CPU Core, 1GB RAM)的极限环境下同时运行 Java 后端和 MySQL,属于典型的“资源争抢”场景。如果不做严格限制,极易出现 OOM(内存溢出)、Swap 交换导致系统卡顿甚至死机。
核心原则只有一个:严格控制内存占用,杜绝 Swap,保持 CPU 单线程高效执行。
以下是具体的调优建议,分为 JVM、MySQL、操作系统三个层面:
一、 JVM 调优(最关键部分)
Java 默认堆大小往往过大,且 GC 停顿会影响响应速度。你需要手动指定堆大小,并选择适合小内存的垃圾回收器。
1. 明确堆内存上限
- 总可用内存:假设系统预留 200MB-300MB 给 OS 和 MySQL,留给 JVM 的内存建议在 300MB – 500MB 之间。
- 参数设置:
-Xms256m -Xmx512m-Xms和-Xmx必须设置为相同值,避免运行时动态调整堆大小带来的性能损耗。- 如果应用非常轻量(如 Spring Boot 最小化启动),可以尝试
-Xms128m -Xmx256m。
2. 选择合适的 GC 收集器
- 推荐:Parallel GC (并行垃圾回收)
- 对于单核机器,Parallel GC 吞吐量高,且实现简单,开销低。
- 参数:
-XX:+UseParallelGC(JDK 8+) 或-XX:+UseParallelOldGC。
- 备选:ZGC/G1
- ZGC 虽然暂停时间短,但本身有内存开销,且在极小堆下优势不明显,反而可能增加负担。
- G1 在小堆下效果不如 Parallel,且需要更多元空间。
- 结论:优先使用 Parallel GC。
3. 元空间与代码缓存
- Metaspace:不要设太大,默认即可,或设为
128m。-XX:MaxMetaspaceSize=128m - Code Cache:JIT 编译的代码缓存,设小一点防止膨胀。
-XX:ReservedCodeCacheSize=64m
4. 关闭不必要的调试功能
-Xloggc:/path/to/gc.log # 生产环境谨慎开启,IO 会消耗资源
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
- 注意:日志文件不要放在系统盘,或者定期清理,避免 IO 瓶颈。
二、 MySQL 调优(重点控制 InnoDB Buffer Pool)
MySQL 是内存大户,默认配置在 1G 服务器上必崩。
1. 关键参数修改 (my.cnf)
[mysqld]
# 基础设置
max_connections = 50 # 极大降低连接数,防止连接池耗尽
thread_cache_size = 10 # 减少线程创建开销
# 内存核心控制
innodb_buffer_pool_size = 128M # 【最重要】InnoDB 缓冲池,设为总内存的 15%-20%
innodb_log_file_size = 32M # 日志文件大小,不宜过大
innodb_flush_method = O_DIRECT # 绕过操作系统缓存,减少双重拷贝
# 其他优化
query_cache_type = OFF # MySQL 5.7+ 已废弃,8.0 完全移除,务必关闭
table_open_cache = 200 # 根据实际表数量调整,不宜过大
tmp_table_size = 16M # 临时表最大内存
max_heap_table_size = 16M # 同上
# 安全阈值
wait_timeout = 10 # 空闲连接超时时间缩短,快速释放资源
interactive_timeout = 10
2. 数据库设计建议
- 避免大字段:尽量不使用 TEXT/BLOB 类型,除非必要。
- 索引优化:确保查询都有索引,避免全表扫描消耗 CPU。
- 字符集:使用
utf8mb4,但注意其存储开销略大于utf8。
三、操作系统层面调优
1. 禁用 Swap(交换分区)
- 原因:1G 内存一旦触发 Swap,磁盘 IO 将成为瓶颈,系统响应时间从毫秒级变成秒级甚至分钟级,用户体验极差。
- 操作:
swapoff -a # 永久禁用:注释 /etc/fstab 中的 swap 行 - 替代方案:如果担心 OOM,宁可让进程被 Kill,也不要让系统进入 Swap 状态。
2. 内核参数优化 (/etc/sysctl.conf)
# 减少 TCP 端口复用等待时间
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# 提高文件描述符限制
fs.file-max = 65535
# 网络缓冲区优化
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
3. 使用轻量级 Web 服务器
- Nginx:作为反向X_X,静态资源由 Nginx 直接处理,不经过 Java 应用。
- 压缩:启用 gzip,减少网络传输量,间接降低带宽压力。
四、架构与应用层建议
1. 应用瘦身
- Spring Boot 优化:
- 排除自动配置中不需要的模块(如
spring-boot-starter-data-jpa若用 MyBatis 则排除)。 - 使用
spring-boot-maven-plugin的repackage打包,减小 jar 包体积。 - 考虑使用 Spring Native 或 GraalVM 将应用编译为原生镜像,大幅降低内存占用和启动时间(适合极简场景)。
- 排除自动配置中不需要的模块(如
- 依赖精简:移除无用依赖,特别是大型工具库。
2. 缓存策略
- 本地缓存:使用 Caffeine 等轻量级本地缓存,减少对 MySQL 的查询次数。
- Redis 隔离:如果可能,将 Redis 部署在其他机器上,或共享一个更大的实例,避免在本机占用宝贵内存。
3. 监控与告警
- 安装轻量级监控 agent(如 Node Exporter + Prometheus),重点关注:
- Memory Usage
- CPU Load Average
- Disk I/O Wait
- 设置 OOM Killer 日志监控,及时发现异常。
五、总结 checklist
| 项目 | 推荐配置/动作 |
|---|---|
| JVM Heap | -Xms256m -Xmx512m |
| JVM GC | -XX:+UseParallelGC |
| MySQL Buffer Pool | 128M |
| MySQL Connections | max_connections=50 |
| Swap | 彻底禁用 |
| Web Server | Nginx 反代 + 静态资源分离 |
| 应用框架 | Spring Boot 精简启动 |
最后提醒
1核1G 服务器仅适合个人博客、小型内部工具、测试环境。如果是面向公网的生产环境,即使做了上述调优,也极易在高并发下崩溃。
长期建议:
- 升级到 2核2G 或以上配置,成本增加有限,但稳定性和性能提升巨大。
- 或将 MySQL 迁移至云数据库 RDS(按量付费或低配版),将本地图书计算资源全部留给 Java 应用。
CLOUD云枢