在轻量服务器(如腾讯云轻量应用服务器、阿里云共享型实例,通常为 1核2GB 或 2核4GB)上同时运行 MySQL、Redis 和 Java 应用(JAR),关键在于资源合理分配、服务轻量化配置与启动管理优化。以下是经过生产验证的实用方案(以 Ubuntu 22.04 / Debian 12 为例,兼顾 CentOS Stream 9):
✅ 一、前提检查(务必执行)
# 查看资源(重点关注内存和磁盘)
free -h # 确保可用内存 ≥ 1.5GB(MySQL+Redis+JVM至少需 1.2GB)
df -h # 确保剩余磁盘 ≥ 2GB(日志+数据)
ulimit -n # 建议 ≥ 65535(避免连接数瓶颈)
⚠️ 若
free -h显示可用内存 < 1.2GB,必须启用 swap(轻量服务器默认无 swap):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
✅ 二、安装策略:优先使用包管理器(安全 & 轻量)
| 组件 | 推荐方式 | 理由 |
|---|---|---|
| MySQL | apt install mysql-server(Ubuntu/Debian)dnf install mysql-server(CentOS) |
官方维护、自动依赖、内存占用更低(比 Docker 少 100MB+) |
| Redis | apt install redis-server |
启动即用,配置简单,默认仅监听本地 |
| Java | apt install openjdk-17-jre-headless |
headless 版本无 GUI,节省 ~50MB 内存 |
❌ 避免 Docker(在 2GB 内存下,Docker daemon + 3个容器极易 OOM)
✅ 三、关键配置优化(逐项调整,否则必崩!)
🔧 1. MySQL(/etc/mysql/mysql.conf.d/mysqld.cnf)
[mysqld]
# 内存限制(关键!)
innodb_buffer_pool_size = 256M # 占总内存 ≤ 25%
key_buffer_size = 16M
max_connections = 50 # 默认151 → 严重超配!
table_open_cache = 64
sort_buffer_size = 256K
read_buffer_size = 256K
# 禁用不用功能
skip_log_bin
skip_innodb_doublewrite
innodb_flush_log_at_trx_commit = 2 # 平衡性能与安全性(非X_X场景可接受)
✅ 重启:sudo systemctl restart mysql
🔧 2. Redis(/etc/redis/redis.conf)
# 内存限制(强制!)
maxmemory 256mb
maxmemory-policy allkeys-lru # 内存满时自动淘汰
# 仅本地访问(更安全且省资源)
bind 127.0.0.1 ::1
protected-mode yes
# 禁用持久化(开发/轻量场景可选)
save "" # 关闭 RDB
appendonly no # 关闭 AOF(若需持久化,设 appendonly yes + appendfsync everysec)
✅ 重启:sudo systemctl restart redis-server
🔧 3. Java 应用(启动脚本 start.sh)
#!/bin/bash
# 启动参数严格限制 JVM 内存!
java -Xms256m -Xmx512m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-Dspring.profiles.active=prod
-jar /opt/myapp/app.jar
--server.port=8080 > /var/log/myapp.log 2>&1 &
echo $! > /var/run/myapp.pid
✅ 关键点:
-Xms256m -Xmx512m:堆内存上限 512MB(占总内存 ≤ 25%)- 避免
-Xmx1g(极易触发 OOM Killer 杀死进程)- 日志重定向到文件,防止 stdout 涨满磁盘
✅ 四、启动顺序与服务管理(防冲突)
# 1. 先启动数据库(依赖基础服务)
sudo systemctl start mysql redis-server
# 2. 启动 Java 应用(确保 DB 已就绪)
sudo /opt/myapp/start.sh
# 3. 设置开机自启(推荐用 systemd 管理 Java 应用)
sudo tee /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My Java Application
After=network.target mysql.service redis-server.service
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh
Restart=on-failure
RestartSec=10
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
✅ 五、监控与故障预防(运维必备)
| 工具 | 命令 | 说明 |
|---|---|---|
| 实时内存 | htop 或 free -h |
观察 available 列,持续 < 300MB 需扩容或调优 |
| Java 进程 | jstat -gc $(cat /var/run/myapp.pid) 1s |
监控 GC 频率(每秒 GC > 1次 → 堆太小) |
| MySQL 连接 | mysql -e "SHOW STATUS LIKE 'Threads_connected';" |
超过 max_connections 会拒绝新连接 |
| Redis 内存 | redis-cli info memory | grep used_memory_human |
确保 < maxmemory |
🚨 快速诊断 OOM:
dmesg -T | grep -i "killed process"→ 若看到java或mysqld被杀,立即调小内存参数!
✅ 六、进阶建议(按需启用)
- Nginx 反向X_X(暴露 Java 应用):
location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } - Logrotate 日志轮转(防磁盘打满):
/etc/logrotate.d/myapp添加:/var/log/myapp.log { daily missingok rotate 30 compress delaycompress notifempty } - 备份脚本(MySQL + Redis):
# MySQL 备份(每天凌晨2点) 0 2 * * * mysqldump -u root --all-databases | gzip > /backup/mysql_$(date +%F).sql.gz # Redis 备份(RDB 文件已存在 /var/lib/redis/dump.rdb)
❌ 常见踩坑总结
| 现象 | 原因 | 解决 |
|---|---|---|
Java 应用启动失败报 OutOfMemoryError |
JVM -Xmx 设太高(如1G) |
改为 -Xmx512m,并确认系统可用内存 |
MySQL 启动失败(Can't start server) |
innodb_buffer_pool_size 超过物理内存 |
改为 256M,检查 free -h |
Redis 写入报 OOM command not allowed |
maxmemory 未设置或太小 |
在 redis.conf 中明确设 maxmemory 256mb |
| 服务开机不自启 | systemctl enable 未执行或 WantedBy= 错误 |
检查 systemctl list-unit-files | grep myapp |
💡 终极提示:
轻量服务器 ≠ 功能齐全服务器。若业务增长(如并发 > 100 或数据量 > 1GB),请立即迁移至 2核4GB 以上配置,或拆分部署(如 Redis 上云托管)。在资源边界运行,配置比版本更重要。
需要我为你生成:
- ✅ 完整的
myapp.servicesystemd 文件模板 - ✅ 自动化安装脚本(一键部署 MySQL+Redis+Java)
- ✅ Spring Boot 应用的
application-prod.yml示例(适配轻量环境)
欢迎随时提出 👇
云服务器