在 2 核 2G 的 Linux 服务器上同时运行 Tomcat 和轻量数据库(如 H2、SQLite、HSQLDB,或 MySQL/PostgreSQL 等),资源非常紧张。优化核心思路是:限制 JVM 内存、降低数据库开销、减少非必要服务、启用缓存与压缩。以下是具体优化方案:
一、JVM 参数优化(Tomcat)
避免 OOM 和频繁 GC,关键在控制堆大小和禁用不必要的功能:
# catalina.sh 中设置 CATALINA_OPTS
export CATALINA_OPTS="-Xms512m -Xmx768m -XX:MaxMetaspaceSize=128m
-XX:+UseG1GC -XX:G1HeapRegionSize=4m
-XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/tomcat/heap.hprof"
说明:
-Xmx768m:预留约 300MB 给数据库 + OS,避免系统 swap。- 使用 G1GC(Java 8+ 默认较优),避免 CMS 的老年代碎片问题。
- 禁用
-XX:+PrintGCDetails等日志输出,减少 I/O。 - 若应用为纯静态或小流量,可进一步压到
-Xmx512m。
✅ 验证:用
jstat -gcutil <pid>观察 GC 频率和暂停时间。
二、数据库选型与配置(以 MySQL 为例;H2/SQLite 更轻但需权衡)
方案 A:轻量嵌入式 DB(推荐用于极低负载)
-
H2(内存模式 or 文件模式):
-- 启动参数示例(spring.datasource.url) jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL # 或文件模式(持久化) jdbc:h2:/data/myapp;AUTO_SERVER=TRUE优势:零进程开销,无网络通信,适合单实例部署。
-
SQLite:
通过 JDBC 直接嵌入,无需独立服务进程,极致轻量。
方案 B:微型 MySQL / MariaDB(需调参)
编辑 /etc/mysql/conf.d/perf.cnf(或 my.cnf):
[mysqld]
max_connections = 20
innodb_buffer_pool_size = 128M # ≤ 总内存的 1/4
innodb_log_file_size = 32M
query_cache_type = 0 # 禁用查询缓存(高并发下反效果)
table_open_cache = 400
thread_stack = 192K
skip-name-resolve # 禁止 DNS 反向解析(提速连接)
log-error = /var/log/mysql/error.log
slow_query_log = 1
long_query_time = 2
⚠️ 注意:若使用 InnoDB,务必限制
innodb_buffer_pool_size,否则易触发 OOM Killer。
三、系统级优化
1. 交换空间(Swap)谨慎使用
- 创建小 swap(如 512MB)作为缓冲,但避免依赖它:
sudo fallocate -l 512M /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab - 调整 swappiness(降低主动换出倾向):
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf sudo sysctl -p
2. 关闭非必要服务
systemctl disable bluetooth cups avahi-daemon sshd-permit-root-login # 按需裁剪
3. 文件系统优化
- 挂载时加
noatime,nodiratime(减少元数据写入):/dev/sda1 /opt ext4 noatime,nodiratime,defaults 0 0 - 将临时目录指向 tmpfs(提升 IO):
mount -t tmpfs -o size=256M tmpfs /tmp
4. 内核参数调优
# /etc/sysctl.d/99-tomcat-db.conf
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
fs.file-max = 65535
四、应用层优化
- 启用 Gzip 压缩(Tomcat
server.xml中<Connector compression="on" />)。 - 使用 Nginx 做反向X_X + 静态资源缓存(减轻 Tomcat 压力)。
- 数据库连接池调优(如 HikariCP):
spring: datasource: hikari: maximum-pool-size: 8 # 2 核建议 ≤ 8 minimum-idle: 2 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000
五、监控与告警
- 安装轻量监控:
htop,iotop,nmon,或 Prometheus + Node Exporter(资源占用低)。 - 重点监控:
free -h查看内存/swap 使用vmstat 1观察si/so(swap in/out)是否频繁top -o %MEM定位内存大户进程
六、替代方案建议(如仍吃力)
| 场景 | 推荐方案 |
|---|---|
| 纯 API + 少量数据 | Spring Boot + H2(内存模式)+ 本地缓存(Caffeine) |
| 需持久化 + 多用户 | SQLite + Flyway 管理 schema |
| 必须关系型 DB | 考虑云厂商免费 tier(如 AWS RDS t2.micro)或容器化隔离 |
✅ 最后检查清单:
- [ ] Tomcat 堆内存 ≤ 768MB
- [ ] 数据库 buffer pool ≤ 128MB
- [ ] Swap 存在但 swappiness=10
- [ ] 关闭 DNS 解析、无用服务
- [ ] 应用开启 gzip 和连接池限制
如需针对具体技术栈(如 Spring Boot 版本、数据库类型)进一步细化配置,欢迎提供细节,我可生成定制化脚本或配置文件。
CLOUD技术博