在 2核2G(2 vCPU, 2GB RAM)这种资源相对受限的云服务器上部署 Java Web 应用,核心目标是:防止 OOM(内存溢出)、减少 GC 停顿时间、降低 CPU 上下文切换开销。
以下是针对 Tomcat 的关键优化建议,按优先级排序:
一、JVM 参数优化(最关键)
2GB 内存中,Tomcat 进程本身需要占用大量内存。默认 JVM 配置往往不适合小内存环境。
1. 设置合理的堆内存大小
- 原则:不要给太多堆内存,留出空间给 Metaspace、线程栈、Direct Buffer 等。
- 推荐值:
-Xms512m -Xmx512m # 初始堆和最大堆设为 512MB~768MB -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m⚠️ 注意:如果应用类很多(如 Spring Boot + 多个模块),可适当调大 Metaspace,但总内存不要超过 1.5GB。
2. 选择合适的垃圾回收器
- 推荐:
G1 GC(Java 8u191+ 或 Java 11+)或Parallel GC(Java 8)。 - G1 GC 优点:可预测停顿时间,适合中等堆大小。
- 示例(Java 8+):
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 # 最大 GC 停顿目标 200ms -XX:InitiatingHeapOccupancyPercent=45 # 触发并发标记的堆占用阈值
3. 禁用不必要的功能
-XX:-UseBiasedLocking # 关闭偏向锁(高并发下可能引起 STW)
-XX:+AlwaysPreTouch # 启动时预分配内存,避免运行时首次分配导致卡顿
-XX:+ExitOnOutOfMemoryError # OOM 时直接退出容器,便于重启监控
4. 线程栈大小优化
默认线程栈是 1MB,2GB 内存下最多只能创建约 2000 个线程。
-Xss256k # 将线程栈从 1MB 降至 256KB,允许更多线程存在
二、Tomcat 连接器(Connector)优化
1. 使用 NIO 协议(非阻塞 I/O)
确保 server.xml 中使用 protocol="org.apache.coyote.http11.Http11NioProtocol"
2. 调整连接数与线程池
- maxThreads:不要设太大,否则上下文切换成本高。
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="200" minSpareThreads="20"/> - acceptCount:等待队列长度,建议设为 100~200。
- connectionTimeout:设置为 20000ms(20秒),避免慢连接占满线程。
✅ 推荐配置:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxThreads="200" minSpareThreads="20" acceptCount="100" enableLookups="false" />
三、系统级优化
1. 增加 Swap 分区(防 OOM 最后一道防线)
虽然 Swap 性能差,但在 2G 内存下,强烈建议添加 1~2GB Swap,避免进程被直接杀死。
# 创建 2GB swap 文件
dd if=/dev/zero of=/swapfile bs=1M count=2048
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
💡 同时调整内核参数降低 swap 使用倾向:
vm.swappiness=10 # 默认通常是 60,改为 10 表示尽量不用 swap
2. 文件描述符限制
Tomcat 在高并发下会打开大量文件/socket,需提高限制。
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
3. 关闭 DNS 反向查找
在 server.xml 的 Connector 中设置:
enableLookups="false"
否则每次请求都会进行 DNS 反向解析,严重拖慢性能。
四、应用层面优化建议
-
静态资源分离:
- 将 JS/CSS/图片等静态资源放到 Nginx 或 CDN,Tomcat 只处理动态请求。
- Nginx 配置
expires缓存策略,减少重复请求。
-
压缩响应:
- 启用 GZIP 压缩,减少网络传输量。
<!-- server.xml --> <Valve className="org.apache.catalina.valves.GzipOutputFilterValve" compressedMimeTypes="text/html,text/xml,application/json,application/javascript,text/css,image/png" compressionMinSize="1024"/>
- 启用 GZIP 压缩,减少网络传输量。
-
避免大对象序列化:
- Session 尽量轻量,或使用 Redis 集中管理 Session,避免 Tomcat 内存压力。
-
日志优化:
- 使用异步日志(如 Logback AsyncAppender),避免 IO 阻塞业务线程。
- 日志级别在生产环境设为
INFO或WARN,避免 DEBUG 频繁写盘。
五、监控与告警
务必部署轻量级监控工具:
- Prometheus + Grafana:监控 JVM 内存、GC 次数、CPU、线程数。
- Arthas:在线诊断工具,用于排查 CPU 飙高、死锁等问题。
- 简单脚本:监控进程是否存活,失败自动重启(systemd 或 supervisor)。
✅ 总结:最小化优化清单
| 类别 | 关键动作 |
|---|---|
| JVM | -Xms512m -Xmx512m, -XX:+UseG1GC, -Xss256k |
| Tomcat | 使用 NIO,maxThreads=200, enableLookups=false |
| 系统 | 添加 1~2GB Swap,vm.swappiness=10,nofile=65535 |
| 架构 | Nginx 反代 + 静态资源分离 + GZIP 压缩 |
| 运维 | 配置 OOM 自动重启,接入基础监控 |
通过以上优化,2核2G 服务器可以稳定支撑日均几万 PV 的小型 Web 应用。如果流量更大,建议升级配置或引入负载均衡集群。
轻量云Cloud