服务器配置

export maxParameterCount="1000"

export acceptCount="1000"

export maxSpareThreads="750"

export maxThreads="1000"

export minSpareThreads="50"

export URIEncoding="UTF-8"

export JAVA_OPTS=" -Xms5120m -Xmx5120m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -XX:MaxDirectMemorySize=2048m -XX:+HeapDumpOnOutOfMemoryError -Xloggc: -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=50 -XX:ErrorFile=/export/Logs/hs_err_pid%p.log /export/Logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintReferenceGC -XX:+PrintTenuringDistribution -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M -Djava.library.path=/usr/local/lib -server -XX:HeapDumpPath=/export/Logs -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no -Dnetworkaddress.cache.ttl=300 -Dsun.net.inetaddr.ttl=300 -DswimLaneEnable=true "

除了之前的 Tomcat + JVM 基础配置,生产环境还需要补充 "容易被忽略但至关重要" 的配置,主要包括 JVM 安全/诊断增强Tomcat 安全/性能加固操作系统内核优化日志规范启动脚本健壮性 五个维度。以下是具体的补充配置和代码:


一、JVM 层面:补充安全、诊断与兜底配置

在现有 JAVA_OPTS 基础上,添加以下参数:

1. 安全加固(禁用不安全协议/功能)

bash 复制代码
# 禁用 TLS 1.0/1.1 等不安全协议,强制使用 TLS 1.2+
-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3
-Dhttps.protocols=TLSv1.2,TLSv1.3

# 禁用 JNDI 远程类加载(防止 Log4j2 等类似漏洞)
-Dcom.sun.jndi.rmi.object.trustURLCodebase=false
-Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false

# 禁用 JVM 的 Attach 机制(防止未授权的进程注入,可选,需配合监控方案)
# -XX:+DisableAttachMechanism

2. OOM 兜底:自动重启应用(可选,需谨慎)

如果应用 OOM 后无法自动恢复,可以添加以下参数让 JVM 在 OOM 时自动执行重启脚本:

bash 复制代码
# OOM 时执行自定义重启脚本(需提前写好 restart.sh)
-XX:OnOutOfMemoryError="/opt/scripts/restart.sh %p"

⚠️ 注意:restart.sh 需要包含"停止旧进程、等待端口释放、启动新应用"的逻辑,且要避免无限循环重启。

3. JMX 监控配置(配合 Prometheus/Grafana)

如果需要用 JConsole 或 Prometheus 监控 JVM 内部指标,添加以下参数:

bash 复制代码
# 开启 JMX 远程监控(端口 9999,无认证,生产环境建议加认证和 SSL)
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=你的服务器IP

二、Tomcat 层面:补充安全、性能与日志配置

1. 安全加固:关闭默认管理页面与危险方法

修改 Tomcat 的 conf/server.xml禁用或注释掉以下内容:

xml 复制代码
<!-- 1. 禁用默认的 Manager 管理页面(防止未授权访问) -->
<!-- <Valve className="org.apache.catalina.valves.AccessLogValve" ... /> -->

<!-- 2. 禁用危险的 HTTP 方法(只保留 GET/POST) -->
<Connector port="8080" protocol="HTTP/1.1"
           ...
           allowTrace="false"
           allowedMethods="GET,POST,PUT,DELETE" />

<!-- 3. 隐藏 Tomcat 版本号(防止被针对性攻击) -->
<Host name="localhost"  appBase="webapps"
      unpackWARs="true" autoDeploy="true">
    <Valve className="org.apache.catalina.valves.ErrorReportValve"
           showReport="false" showServerInfo="false" />
</Host>

2. 性能优化:开启 Gzip 压缩与限制请求大小

conf/server.xml<Connector> 标签中添加:

xml 复制代码
<Connector port="8080" protocol="HTTP/1.1"
           ...
           <!-- 开启 Gzip 压缩,压缩文本/JS/CSS,减少传输带宽 -->
           compression="on"
           compressionMinSize="2048"
           compressableMimeType="text/html,text/xml,text/plain,text/css,application/javascript,application/json"
           
           <!-- 限制请求体大小(防止大文件上传攻击,这里设为 10MB,根据业务调整) -->
           maxPostSize="10485760"
           
           <!-- 限制请求头大小(防止 HTTP 头注入攻击) -->
           maxHttpHeaderSize="8192" />

3. 补充 Access Log(访问日志)配置

conf/server.xml<Host> 标签内添加 Access Log(用于分析用户请求、排查攻击):

xml 复制代码
<Valve className="org.apache.catalina.valves.AccessLogValve"
       directory="/export/Logs/tomcat_access"  <!-- 日志保存路径 -->
       prefix="access_log"
       suffix=".log"
       pattern="%h %l %u %t &quot;%r&quot; %s %b %D &quot;%{Referer}i&quot; &quot;%{User-Agent}i&quot;"
       rotatable="true"
       renameOnRotate="true"
       maxDays="30" />  <!-- 保留 30 天日志 -->
  • %h:客户端 IP;%s:HTTP 状态码;%b:响应大小;%D:请求处理时间(毫秒)。

三、操作系统层面:内核参数优化(高并发场景必须)

这是最容易被忽略但对高并发影响最大 的配置!需要修改 Linux 的 /etc/sysctl.conf 文件(修改后执行 sysctl -p 生效):

1. 文件描述符限制(允许更多并发连接)

bash 复制代码
# 1. 先修改 /etc/security/limits.conf(永久生效)
* soft nofile 655350
* hard nofile 655350
* soft nproc 655350
* hard nproc 655350

# 2. 再修改 /etc/sysctl.conf
fs.file-max = 655350  # 系统级最大文件描述符数

2. TCP 网络参数优化(应对高并发连接)

bash 复制代码
# /etc/sysctl.conf 中添加:
net.ipv4.tcp_tw_reuse = 1          # 允许 TIME_WAIT 状态的 socket 重新用于新连接
net.ipv4.tcp_tw_recycle = 0         # 关闭快速回收(NAT 环境下会有问题,建议设为 0)
net.ipv4.tcp_fin_timeout = 30       # TIME_WAIT 状态的超时时间(默认 60s,缩短到 30s)
net.ipv4.tcp_max_tw_buckets = 20000 # 系统允许的最大 TIME_WAIT socket 数
net.ipv4.tcp_max_syn_backlog = 8192 # SYN 队列长度(应对突发连接)
net.core.somaxconn = 8192            # 监听端口的最大等待连接数(配合 Tomcat 的 acceptCount)
net.core.netdev_max_backlog = 8192   # 网络设备接收队列的最大长度

四、日志层面:补充应用日志规范

除了 GC 日志和 Tomcat Access Log,应用日志(比如 Logback/Log4j2)也需要补充规范配置:

1. Logback 配置示例(logback-spring.xml

xml 复制代码
<configuration>
    <!-- 1. 控制台输出(开发环境用,生产环境可关闭) -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 2. 应用日志文件(按天滚动,保留 30 天) -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/export/Logs/app/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/export/Logs/app/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <totalSizeCap>10GB</totalSizeCap> <!-- 总日志大小不超过 10GB -->
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 3. 错误日志单独输出(方便排查) -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/export/Logs/app/error.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/export/Logs/app/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 4. 日志脱敏(防止敏感信息泄露,比如手机号、身份证号) -->
    <conversionRule conversionWord="msg" converterClass="com.example.SensitiveDataMaskingConverter" />

    <!-- 生产环境日志级别:INFO(避免 DEBUG 日志过多占用磁盘) -->
    <root level="INFO">
        <appender-ref ref="FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
</configuration>

五、启动脚本:补充健壮性检查

最后,给你的应用启动脚本(start.sh)补充以下检查逻辑,避免启动失败或异常:

bash 复制代码
#!/bin/bash
APP_NAME="your-app.jar"
APP_PATH="/opt/app"
LOG_PATH="/export/Logs"
PID_FILE="$APP_PATH/app.pid"

# 1. 前置检查:创建必要目录
mkdir -p $LOG_PATH $APP_PATH

# 2. 前置检查:检查 JDK 版本(要求 JDK 8+)
JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{print $1$2}')
if [ "$JAVA_VERSION" -lt "18" ]; then
    echo "错误:JDK 版本过低,需要 JDK 8+,当前版本:$(java -version 2>&1)"
    exit 1
fi

# 3. 前置检查:检查端口是否被占用(假设应用端口是 8080)
if netstat -tuln | grep -q ":8080 "; then
    echo "错误:端口 8080 已被占用,请先停止旧进程"
    exit 1
fi

# 4. 停止旧进程(如果存在)
if [ -f $PID_FILE ]; then
    PID=$(cat $PID_FILE)
    if kill -0 $PID 2>/dev/null; then
        echo "正在停止旧进程(PID: $PID)..."
        kill $PID
        sleep 10
        if kill -0 $PID 2>/dev/null; then
            echo "强制杀死旧进程..."
            kill -9 $PID
        fi
    fi
    rm -f $PID_FILE
fi

# 5. 启动应用(使用修正后的 JVM 参数)
echo "正在启动应用..."
nohup java -jar $APP_PATH/$APP_NAME \
  -Xms5120m -Xmx5120m \
  -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m \
  -XX:MaxDirectMemorySize=2048m \
  -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$LOG_PATH \
  -XX:ErrorFile=$LOG_PATH/hs_err_pid%p.log \
  -Xloggc:$LOG_PATH/gc.log \
  -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelRefProcEnabled \
  -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintReferenceGC -XX:+PrintTenuringDistribution \
  -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M \
  -Djava.awt.headless=true \
  -Dsun.net.client.defaultConnectTimeout=20000 -Dsun.net.client.defaultReadTimeout=20000 \
  -Dnetworkaddress.cache.ttl=300 \
  > $LOG_PATH/app.out 2>&1 &

# 6. 保存 PID 并检查启动是否成功
echo $! > $PID_FILE
sleep 15
if curl -s http://localhost:8080/actuator/health >/dev/null; then
    echo "应用启动成功!PID: $(cat $PID_FILE)"
else
    echo "应用启动失败,请查看日志:$LOG_PATH/app.out"
    exit 1
fi

总结

补充以上配置后,你的生产环境会更安全、稳健、易排查问题。核心补充点是:

  1. JVM:安全加固、OOM 兜底、JMX 监控;
  2. Tomcat:关闭管理页面、开启压缩、配置 Access Log;
  3. 操作系统:文件描述符和 TCP 参数优化(高并发必须);
  4. 日志:规范滚动、脱敏、错误日志单独输出;
  5. 启动脚本:前置检查、健康检查、自动停止旧进程。

如果你需要 某个配置的更详细说明(比如日志脱敏的具体实现、JMX 加认证的方法),可以告诉我,我帮你进一步补充!

相关推荐
Barkamin2 小时前
堆排序简单实现
java·数据结构·算法·排序算法
小江的记录本2 小时前
【TCP】TCP三次握手与四次挥手(系统性知识体系+对比表格)
java·服务器·网络·网络协议·tcp/ip·http·tcp
小吴编程之路2 小时前
TCP 通信中的四种核心异常情况
服务器·网络·tcp/ip
闻哥2 小时前
MySQL索引核心原理:B+树生成、页分裂与页合并全解析
java·jvm·b树·mysql·adb·面试·springboot
蜡台2 小时前
Android Gradle 项目下载编译失败解决---持续更新
android·java·kotlin·gradle
迈巴赫车主2 小时前
天梯赛 L2-004 这是二叉搜索树吗?java
java·开发语言·数据结构·算法·天梯赛
moonlight03042 小时前
对象组成、分配、强弱引用
jvm
一叶飘零_sweeeet3 小时前
从 GC 频繁到毫秒级停顿:JVM 内存调优分代配比、晋升机制与架构策略全拆解
jvm
JMchen1233 小时前
跨技术栈:在Flutter/Compose中应用自定义View思想
java·经验分享·flutter·canvas·dart·自定义view