Tomcat 连接器配置

Connector Configuration

概述

Tomcat连接器是处理客户端请求的核心组件,负责接收、解析和响应HTTP/HTTPS/AJP请求。本文将详细介绍各种连接器类型的配置方法、性能优化技巧和最佳实践。

1. 连接器类型概览

1.1 连接器协议类型

Tomcat连接器类型
├── HTTP连接器
│   ├── HTTP/1.1 (默认)
│   ├── HTTP/2
│   └── WebSocket
├── 实现类型
│   ├── NIO (默认)
│   ├── NIO2
│   ├── APR/Native
│   └── BIO (已废弃)
└── 特殊协议
    ├── AJP/1.3
    └── gRPC (扩展)

1.2 连接器选择指南

性能对比表
┌─────────────┬─────────┬─────────┬─────────┬─────────┐
│ 连接器类型   │ 并发性能  │ 内存使用  │ CPU使用  │ 适用场景 │
├─────────────┼─────────┼─────────┼─────────┼─────────┤
│ NIO         │ 高      │ 中      │ 中      │ 通用     │
│ NIO2        │ 很高    │ 中      │ 低      │ 高并发   │
│ APR/Native  │ 最高    │ 低      │ 最低    │ 生产环境 │
│ AJP         │ 高      │ 低      │ 低      │ 代理集成 │
└─────────────┴─────────┴─────────┴─────────┴─────────┘

2. HTTP连接器配置

2.1 基础HTTP连接器

<!-- server.xml - 基础HTTP连接器 -->
<Connector port="8080" 
           protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true" />

2.2 NIO连接器详细配置

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"

           <!-- 基本参数 -->
           maxThreads="200"
           minSpareThreads="10"
           maxSpareThreads="75"
           acceptCount="100"

           <!-- 连接参数 -->
           connectionTimeout="20000"
           keepAliveTimeout="60000"
           maxKeepAliveRequests="100"

           <!-- 缓冲区设置 -->
           socketBuffer="9000"
           bufferSize="16384"

           <!-- 压缩设置 -->
           compression="on"
           compressionMinSize="2048"
           compressibleMimeType="text/html,text/xml,text/css,text/javascript,application/javascript,application/json,application/xml"

           <!-- 其他设置 -->
           enableLookups="false"
           disableUploadTimeout="true"
           maxParameterCount="1000"
           maxPostSize="2097152"
           maxSavePostSize="4096"

           <!-- 执行器引用 -->
           executor="tomcatThreadPool" />

2.3 NIO2连接器配置

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11Nio2Protocol"

           <!-- NIO2特有参数 -->
           useSendfile="true"
           sendfileSize="1024"

           <!-- 性能参数 -->
           maxThreads="300"
           minSpareThreads="25"
           acceptCount="200"

           <!-- 异步处理 -->
           asyncTimeout="30000"

           <!-- 连接管理 -->
           connectionTimeout="20000"
           keepAliveTimeout="60000"
           maxKeepAliveRequests="200"

           <!-- SSL配置(如果需要) -->
           SSLEnabled="false" />

2.4 APR/Native连接器配置

<!-- 需要先安装tomcat-native库 -->
<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11AprProtocol"

           <!-- APR特有参数 -->
           pollTime="2000"
           pollerSize="32768"
           useSendfile="true"
           sendfileSize="1024"

           <!-- 高性能设置 -->
           maxThreads="400"
           minSpareThreads="25"
           acceptCount="300"

           <!-- 连接池设置 -->
           acceptorThreadCount="2"
           acceptorThreadPriority="5"

           <!-- 缓冲区优化 -->
           socketBuffer="65536"
           bufferSize="16384"

           <!-- 压缩优化 -->
           compression="on"
           compressionMinSize="1024" />

3. HTTPS连接器配置

3.1 基础HTTPS配置

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" 
           SSLEnabled="true"
           scheme="https" 
           secure="true"
           clientAuth="false" 
           sslProtocol="TLS">

  <SSLHostConfig>
    <Certificate certificateKeystoreFile="conf/keystore.jks"
                 certificateKeystorePassword="changeit"
                 type="RSA" />
  </SSLHostConfig>
</Connector>

3.2 高级HTTPS配置

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="200"
           SSLEnabled="true"
           scheme="https" 
           secure="true">

  <SSLHostConfig protocols="TLSv1.2,TLSv1.3"
                 ciphers="ECDHE-RSA-AES256-GCM-SHA384,ECDHE-RSA-AES128-GCM-SHA256"
                 honorCipherOrder="true"
                 disableCompression="true"
                 disableSessionTickets="false"
                 sessionTimeout="86400">

    <!-- RSA证书 -->
    <Certificate certificateKeystoreFile="conf/rsa-keystore.jks"
                 certificateKeystorePassword="rsapass"
                 certificateKeyAlias="rsa-key"
                 type="RSA" />

    <!-- ECC证书(可选) -->
    <Certificate certificateKeystoreFile="conf/ecc-keystore.jks"
                 certificateKeystorePassword="eccpass"
                 certificateKeyAlias="ecc-key"
                 type="EC" />
  </SSLHostConfig>

  <!-- HSTS设置 -->
  <Valve className="org.apache.catalina.valves.HttpHeaderSecurityFilter"
         hstsEnabled="true"
         hstsMaxAgeSeconds="31536000"
         hstsIncludeSubdomains="true" />
</Connector>

3.3 双向SSL认证配置

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           SSLEnabled="true"
           scheme="https" 
           secure="true">

  <SSLHostConfig certificateVerification="required"
                 truststoreFile="conf/truststore.jks"
                 truststorePassword="trustpass"
                 truststoreType="JKS"
                 caCertificateFile="conf/ca-cert.pem">

    <Certificate certificateKeystoreFile="conf/server-keystore.jks"
                 certificateKeystorePassword="serverpass"
                 type="RSA" />
  </SSLHostConfig>
</Connector>

4. AJP连接器配置

4.1 基础AJP配置

<!-- 用于与Apache httpd集成 -->
<Connector port="8009" 
           protocol="AJP/1.3" 
           redirectPort="8443"
           address="0.0.0.0"
           secretRequired="true"
           secret="ajp_secret_key" />

4.2 高性能AJP配置

<Connector port="8009" 
           protocol="org.apache.coyote.ajp.AjpNioProtocol"

           <!-- 连接参数 -->
           maxThreads="200"
           minSpareThreads="10"
           acceptCount="100"
           connectionTimeout="600000"

           <!-- AJP特定参数 -->
           packetSize="65536"
           processorCache="200"

           <!-- 安全设置 -->
           secretRequired="true"
           secret="complex_ajp_secret_2023"
           allowedRequestAttributesPattern=".*"

           <!-- 地址限制 -->
           address="127.0.0.1"

           <!-- 执行器 -->
           executor="ajpThreadPool" />

5. HTTP/2连接器配置

5.1 HTTP/2基础配置

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           SSLEnabled="true"
           scheme="https" 
           secure="true">

  <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
                  readTimeout="30000"
                  keepAliveTimeout="20000"
                  maxConcurrentStreams="200"
                  maxConcurrentStreamExecution="20"
                  initialWindowSize="65535"
                  allowedTrailerHeaders="x-trace-id" />

  <SSLHostConfig protocols="TLSv1.2,TLSv1.3">
    <Certificate certificateKeystoreFile="conf/keystore.jks"
                 certificateKeystorePassword="changeit"
                 type="RSA" />
  </SSLHostConfig>
</Connector>

5.2 HTTP/2性能优化

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11Nio2Protocol"
           SSLEnabled="true">

  <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
                  <!-- 流控制设置 -->
                  readTimeout="60000"
                  keepAliveTimeout="30000"
                  streamReadTimeout="20000"
                  streamWriteTimeout="20000"

                  <!-- 并发控制 -->
                  maxConcurrentStreams="100"
                  maxConcurrentStreamExecution="200"

                  <!-- 窗口大小 -->
                  initialWindowSize="1048576"

                  <!-- 压缩设置 -->
                  compressionLevel="6"
                  compressibleMimeType="text/html,text/css,application/javascript"

                  <!-- 推送设置 -->
                  allowedTrailerHeaders="x-request-id,x-correlation-id" />
</Connector>

6. 线程池配置

6.1 共享线程池

<!-- server.xml中定义共享线程池 -->
<Service name="Catalina">

  <!-- 通用线程池 -->
  <Executor name="tomcatThreadPool" 
            namePrefix="catalina-exec-" 
            maxThreads="300" 
            minSpareThreads="50"
            maxIdleTime="60000"
            prestartminSpareThreads="true"
            maxQueueSize="100"
            threadPriority="5" />

  <!-- AJP专用线程池 -->
  <Executor name="ajpThreadPool" 
            namePrefix="ajp-exec-" 
            maxThreads="150" 
            minSpareThreads="25"
            maxIdleTime="60000" />

  <!-- HTTP连接器使用共享线程池 -->
  <Connector port="8080" 
             protocol="HTTP/1.1"
             executor="tomcatThreadPool" />

  <!-- AJP连接器使用专用线程池 -->
  <Connector port="8009" 
             protocol="AJP/1.3"
             executor="ajpThreadPool" />
</Service>

6.2 线程池监控配置

// ThreadPoolMonitor.java
package com.example.tomcat.monitor;

import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;

public class ThreadPoolMonitor {

    private MBeanServer mbs;

    public ThreadPoolMonitor() {
        this.mbs = ManagementFactory.getPlatformMBeanServer();
    }

    public void monitorThreadPool() throws Exception {
        // 获取线程池信息
        ObjectName executorName = new ObjectName(
            "Catalina:type=Executor,name=tomcatThreadPool"
        );

        Integer activeCount = (Integer) mbs.getAttribute(executorName, "activeCount");
        Integer poolSize = (Integer) mbs.getAttribute(executorName, "poolSize");
        Integer maxThreads = (Integer) mbs.getAttribute(executorName, "maxThreads");
        Integer queueSize = (Integer) mbs.getAttribute(executorName, "queueSize");

        System.out.println("线程池监控:");
        System.out.println("活跃线程数: " + activeCount);
        System.out.println("池大小: " + poolSize);
        System.out.println("最大线程数: " + maxThreads);
        System.out.println("队列大小: " + queueSize);
        System.out.println("使用率: " + (activeCount * 100.0 / maxThreads) + "%");

        // 检查是否需要调整
        if (activeCount * 100.0 / maxThreads > 80) {
            System.out.println("警告: 线程池使用率过高!");
        }
    }
}

7. 连接器性能调优

7.1 连接超时优化

<Connector port="8080" 
           protocol="HTTP/1.1"

           <!-- 连接超时设置 -->
           connectionTimeout="20000"
           socketTimeout="60000"

           <!-- Keep-Alive优化 -->
           keepAliveTimeout="15000"
           maxKeepAliveRequests="100"

           <!-- 异步超时 -->
           asyncTimeout="30000"

           <!-- 处理器缓存 -->
           processorCache="200"

           <!-- Socket选项 -->
           tcpNoDelay="true"
           soLinger="-1"
           soTimeout="60000" />

7.2 缓冲区优化

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"

           <!-- 缓冲区大小 -->
           socketBuffer="65536"
           bufferSize="16384"

           <!-- 文件上传缓冲 -->
           maxPostSize="20971520"
           maxSavePostSize="8192"

           <!-- 请求参数限制 -->
           maxParameterCount="10000"
           maxHeaderCount="200"
           maxHttpHeaderSize="8192"

           <!-- Sendfile优化 -->
           useSendfile="true"
           sendfileSize="1024" />

7.3 压缩优化配置

<Connector port="8080" 
           protocol="HTTP/1.1"

           <!-- 压缩设置 -->
           compression="on"
           compressionMinSize="1024"
           compressibleMimeType="text/html,text/xml,text/css,text/javascript,text/json,application/javascript,application/json,application/xml,application/rss+xml,application/atom+xml,image/svg+xml"

           <!-- 压缩级别(APR connector支持) -->
           compressionLevel="6"

           <!-- 不压缩的用户代理 -->
           noCompressionUserAgents="gozilla, traviata"

           <!-- 不压缩的文件类型 -->
           restrictedUserAgents=".*MSIE.*" />

8. 连接器监控与诊断

8.1 JMX监控配置

<!-- 启用JMX监控 -->
<Connector port="8080" 
           protocol="HTTP/1.1"

           <!-- JMX相关属性 -->
           processorCache="200"
           socket.txBufSize="25188"
           socket.rxBufSize="25188"
           socket.tcpNoDelay="true"

           <!-- 统计信息收集 -->
           enableLookups="false"
           maxParameterCount="1000" />

8.2 连接器状态监控

// ConnectorMonitor.java
package com.example.tomcat.monitor;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Set;

public class ConnectorMonitor {

    private MBeanServer mbs;

    public ConnectorMonitor() {
        this.mbs = ManagementFactory.getPlatformMBeanServer();
    }

    public void monitorConnectors() throws Exception {
        // 查找所有连接器
        Set<ObjectName> connectors = mbs.queryNames(
            new ObjectName("Catalina:type=Connector,*"), null
        );

        for (ObjectName connector : connectors) {
            String port = connector.getKeyProperty("port");
            String protocol = (String) mbs.getAttribute(connector, "protocol");

            // 获取连接器统计信息
            Integer maxThreads = (Integer) mbs.getAttribute(connector, "maxThreads");
            Integer currentThreadCount = (Integer) mbs.getAttribute(connector, "currentThreadCount");
            Integer currentThreadsBusy = (Integer) mbs.getAttribute(connector, "currentThreadsBusy");
            Long bytesReceived = (Long) mbs.getAttribute(connector, "bytesReceived");
            Long bytesSent = (Long) mbs.getAttribute(connector, "bytesSent");
            Integer requestCount = (Integer) mbs.getAttribute(connector, "requestCount");
            Long processingTime = (Long) mbs.getAttribute(connector, "processingTime");
            Integer errorCount = (Integer) mbs.getAttribute(connector, "errorCount");

            System.out.println("连接器监控 - 端口: " + port + ", 协议: " + protocol);
            System.out.println("  最大线程数: " + maxThreads);
            System.out.println("  当前线程数: " + currentThreadCount);
            System.out.println("  忙碌线程数: " + currentThreadsBusy);
            System.out.println("  线程使用率: " + (currentThreadsBusy * 100.0 / maxThreads) + "%");
            System.out.println("  接收字节数: " + formatBytes(bytesReceived));
            System.out.println("  发送字节数: " + formatBytes(bytesSent));
            System.out.println("  请求数量: " + requestCount);
            System.out.println("  平均处理时间: " + (processingTime / Math.max(requestCount, 1)) + "ms");
            System.out.println("  错误数量: " + errorCount);
            System.out.println("  错误率: " + (errorCount * 100.0 / Math.max(requestCount, 1)) + "%");
            System.out.println();
        }
    }

    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
        if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024));
        return String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024));
    }
}

8.3 连接器健康检查

#!/bin/bash
# connector-health-check.sh

TOMCAT_HOST="localhost"
HTTP_PORT="8080"
HTTPS_PORT="8443"
AJP_PORT="8009"

check_http_connector() {
    echo "检查HTTP连接器 (端口: $HTTP_PORT)"

    response=$(curl -s -o /dev/null -w "%{http_code},%{time_total},%{time_connect}" \
              http://$TOMCAT_HOST:$HTTP_PORT/)

    http_code=$(echo $response | cut -d',' -f1)
    time_total=$(echo $response | cut -d',' -f2)
    time_connect=$(echo $response | cut -d',' -f3)

    if [ "$http_code" = "200" ]; then
        echo "  ✓ HTTP连接器正常 (响应时间: ${time_total}s, 连接时间: ${time_connect}s)"
    else
        echo "  ✗ HTTP连接器异常 (状态码: $http_code)"
    fi
}

check_https_connector() {
    echo "检查HTTPS连接器 (端口: $HTTPS_PORT)"

    if timeout 5 bash -c "</dev/tcp/$TOMCAT_HOST/$HTTPS_PORT"; then
        echo "  ✓ HTTPS端口可访问"

        # 检查SSL证书
        cert_info=$(echo | openssl s_client -connect $TOMCAT_HOST:$HTTPS_PORT 2>/dev/null | \
                   openssl x509 -noout -dates 2>/dev/null)

        if [ $? -eq 0 ]; then
            echo "  ✓ SSL证书有效"
            echo "    $cert_info"
        else
            echo "  ⚠ SSL证书检查失败"
        fi
    else
        echo "  ✗ HTTPS端口不可访问"
    fi
}

check_ajp_connector() {
    echo "检查AJP连接器 (端口: $AJP_PORT)"

    if timeout 5 bash -c "</dev/tcp/$TOMCAT_HOST/$AJP_PORT"; then
        echo "  ✓ AJP端口可访问"
    else
        echo "  ✗ AJP端口不可访问"
    fi
}

check_thread_pools() {
    echo "检查线程池状态"

    # 通过JMX获取线程池信息(需要jmxterm或其他JMX客户端)
    if command -v jmxterm.jar &> /dev/null; then
        echo "get -b Catalina:type=Executor,name=tomcatThreadPool activeCount" | \
        java -jar jmxterm.jar -l service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi -n
    else
        echo "  ⚠ 无法检查线程池(需要JMX客户端)"
    fi
}

main() {
    echo "=== Tomcat连接器健康检查 $(date) ==="
    echo

    check_http_connector
    echo

    check_https_connector
    echo

    check_ajp_connector
    echo

    check_thread_pools
    echo

    echo "=== 检查完成 ==="
}

main

9. 连接器安全配置

9.1 访问控制

<Connector port="8080" 
           protocol="HTTP/1.1">

  <!-- 远程地址过滤 -->
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="192\.168\.1\..*|127\.0\.0\.1"
         deny=".*" />

  <!-- 请求大小限制 -->
  maxPostSize="2097152"
  maxSavePostSize="4096"
  maxParameterCount="1000"
  maxHeaderCount="100"
  maxHttpHeaderSize="8192"

  <!-- 禁用不安全的HTTP方法 -->
  allowTrace="false"
</Connector>

9.2 SSL安全增强

<Connector port="8443" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           SSLEnabled="true">

  <SSLHostConfig protocols="TLSv1.2,TLSv1.3"
                 ciphers="ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305"
                 honorCipherOrder="true"
                 disableCompression="true"
                 disableSessionTickets="false"
                 sessionTimeout="300"
                 caCertificateFile="conf/ca-bundle.crt"
                 certificateVerification="none"
                 revocationEnabled="false">

    <Certificate certificateKeystoreFile="conf/keystore.jks"
                 certificateKeystorePassword="changeit"
                 certificateKeyAlias="tomcat"
                 type="RSA" />
  </SSLHostConfig>

  <!-- 安全头设置 -->
  <Valve className="org.apache.catalina.valves.HttpHeaderSecurityFilter"
         hstsEnabled="true"
         hstsMaxAgeSeconds="31536000"
         hstsIncludeSubdomains="true"
         hstsPreload="true" />
</Connector>

小结

通过本文学习,你应该掌握:

  1. 各种连接器类型的选择和配置方法
  2. HTTP、HTTPS、AJP、HTTP/2连接器的详细配置
  3. 线程池的配置和监控
  4. 连接器性能调优技巧
  5. 连接器监控和诊断方法
  6. 连接器安全配置最佳实践
  7. 缓冲区、压缩、超时等优化参数

下一篇文章将详细介绍Tomcat虚拟主机的配置与管理。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-08-29 15:40:15

results matching ""

    No results matching ""