ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

THS部署实战:从tar包解压到反向代理与负载均衡配置

2026/9/29 20:58:26 拓冰建站 浏览量
THS部署实战:从tar包解压到反向代理与负载均衡配置 简介TongHttpServerTHS是一款面向负载均衡场景的企业级软件发行包适合运维工程师、架构师在构建高可用服务集群时使用解决流量分发、后端节点调度与可靠性保障问题。压缩包共71个文件约39.44MB内含pem/crt/key等证书文件、so动态库模块、conf配置、sh启停脚本及pfx证书包等覆盖HTTPS加密、负载策略、进程守护与Web管理界面等功能。资源提供双机热备组件、反向代理插件、Web管理面板及多种负载均衡算法模块如按主机、IP哈希、最小连接数便于用户按需选用。已有4389人学习下载适合需要快速部署THS或了解其目录结构、模块用途的中高级运维人员可直接用于内网测试或生产环境参考。1. 拿到 THS_x86.tar.gz 之前先弄清楚它到底是个什么东西有人把 TongHttpServerTHS THS_x86.tar.gz 当成一个普通压缩包解压完跑起来就以为部署完成。实际上这个包是一个可移植的 HTTP 服务器/反向代理的编译产物x86 表示它面向 x86_64 指令集tar.gz 是典型的分发方式。THS 兼容 Apache 的配置习惯能直接处理静态资源、转发动态请求还可在后端多实例之间做负载均衡。适合谁给内网应用做统一入口的运维、在国产化环境下替换商业负载均衡的实施工程师以及被架构要求“别再用 Nginx 单打独斗”的后端开发。这章先不聊安装先让你明白为什么值得用 THS而不是继续用裸 Apache 或 Nginx 直接改配置。如果你第一次接触 THS建议先花十分钟把包的目录和模块清单读懂再谈启动。2. 把 THS_x86.tar.gz 解压到指定目录并启动从 tar 解压到 curl 验证2.1 解压前的准备校验、预览目录、确认安装位置拿到 THS_x86.tar.gz 后我一般不会直接tar -xzf。如果这个包是从同事 U 盘或内网传输过来的先做一次完整性校验避免解压到一半报错或者某个 .so 库文件被截断。常见做法是比对 sha256 或 md5包旁边通常会有一个对应校验文件如果没有就在传输工具里单独确认一下大小。命令如下sha256sum THS_x86.tar.gz tar -tzvf THS_x86.tar.gz | head -30 tar -xzvf THS_x86.tar.gz -C /opt第一行是对整个包算摘要第二行不解压直接打印压缩包内的文件清单重点看两个信息顶层目录名是 THS 还是 THS_x86以及有没有 bin/、conf/、modules/、logs/ 这些标准结构。第三行才真正解压到 /opt 下。如果你希望放到别的路径比如 /usr/local/THS那就把 -C 改成 /usr/local。注意不要解压到当前目录后就随手把 tar.gz 和解压目录混在一起后续做 systemd 时路径一乱启动脚本很容易找不到 ServerRoot。解压完成后先别急着进 bin 目录去读一下 release 或 readme 文件。THS 的包通常会带一个文本说明记录编译时用的 Apache 版本、OpenSSL 版本以及启用的模块列表。这一步能帮你确认一个关键信息你手里这个 THS_x86.tar.gz 内部是 Apache 2.4 还是 2.2 的基建。两者的配置指令差异很大比如 2.4 默认用Require all granted而 2.2 用Order allow,deny。如果直接套用网上拷贝的配置段很可能启动报错。我见过太多人把 Nginx 的 location 语法改巴改巴塞进 httpd.conf然后问为什么httpd -t一片红。2.2 启动 THS 的两种姿势前台调试和后台守护THS 的 bin 目录下通常会有 ths 和 apachectl 两个可执行文件。ths 本身是主程序前台运行会占据终端适合第一次验证配置时使用apachectl 是管理脚本内部封装了启动、停止、优雅重启等操作。第一次启动我建议用前台模式因为任何配置错误都会直接打印在终端上比翻 error_log 快得多。命令如下/opt/THS/bin/ths -X-X 表示以前台模式运行忽略系统守护逻辑。如果终端输出类似AH00548: NameVirtualHost has no effect这种信息不用慌前几行是提示只有包含Syntax error或者Cannot load module的才说明配置有问题。看到Server configured -- listening on port 80就说明这个进程已经就绪此时不要按 CtrlC再开一个会话去执行验证命令。验证通过后退掉前台进程用 apachectl 正式拉起/opt/THS/bin/apachectl start这个脚本做的事情比ths -X多它会检查 httpd.conf 语法、生成 pid 文件、并把进程转成 daemon 模式。执行完以后可以配合 ps 和 netstat 确认ps -ef | grep ths netstat -pntl | grep -E 80|443ps 输出里你会看到第一个父进程root 启动和几个工作子进程子进程数量由 httpd.conf 里的 StartServers 决定。netstat 能看到 80 或指定端口正在监听。如果进程在但端口没有监听多半是服务启动后又因为端口被占用或者权限不足自己退出了直接去看 logs/error_log。2.3 验证安装curl 探活和版本信息启动成功不意味着可以交付。我习惯先在本机用 curl 探活避免防火墙或网络策略挡住真实客户端。THS 默认会有一个欢迎页或静态页面如果没有改过 DocumentRoot用下面命令应该能拿到 200curl -I http://127.0.0.1 curl -v http://127.0.0.1/ 21 | tail -20第一条会返回 HTTP 状态头第二条能看到具体响应体。如果返回 403一般是因为 DocumentRoot 下没有 index 文件或者目录权限配置不允许 Indexes如果返回 404检查 httpd.conf 里的 DocumentRoot 路径是否和实际解压位置对得上。接下来记录版本信息方便后面排障时判断语法兼容/opt/THS/bin/ths -V /opt/THS/bin/ths -M-V 输出编译参数和版本-M 输出已加载模块列表。这两条命令的输出要保存下来等做 systemd 或者调优时可以快速确认有没有 mod_proxy、mod_ssl、mod_headers 这些关键模块。-M 输出的模块可能是静态编译进去的也可能通过 LoadModule 加载的在输出里会用不同形式表示。THS 常见做法是大部分模块以 .so 形式放在 modules/ 目录下所以如果发现mod_proxy.so文件存在但 -M 里没有多半是 httpd.conf 里对应的 LoadModule 行被注释了。2.4 启动失败的兜底检查缺库和权限问题如果 apachectl start 后没有任何输出但 error_log 里出现error while loading shared libraries: libapr-1.so.0: cannot open shared object file说明系统里缺少 THS 依赖的 APR 运行库。此时不要立刻重装 THS先确认依赖库是否真的不在。用 ldd 检查主程序ldd /opt/THS/bin/ths输出里标记not found的项就是缺的库。常见缺libapr-1.so.0、libpcre.so.1、libexpat.so.1。这些在 CentOS/RHEL 上分别对应 apr、pcre、expat 的运行时包在 Debian 系上可能是 libapr1、libpcre3、libexpat1。安装对应包即可例如yum install apr pcre expat或apt install libapr1 libpcre3 libexpat1。如果因为环境限制不能装系统包可以临时把库路径加进 LD_LIBRARY_PATH但这种方法只适合临时验证因为每次启动都要带环境变量脚本化很脆弱。另一个要注意的是解压后的属主。如果 tar 包在 Windows 下被折腾过解压出来的 bin/ths 可能没有执行权限用chmod x /opt/THS/bin/ths解决。提示第一次修改 httpd.conf 前先把原始文件备份成 httpd.conf.bakYYMMDD后面排障能省大量时间。3. 让 THS 真正干活反向代理与负载均衡的配置拆解3.1 httpd.conf 里绕不开的基础指令THS 的配置文件是 conf/httpd.conf和 Apache 一脉相承。第一次修改前先备份一份这是所有配置运维的底线。我一般复制成 httpd.conf.bakYYMMDD然后用httpd -t验证语法。下面这几个指令是反向代理场景的基础先挨个说清楚。ServerRoot /opt/THS Listen 80 ServerName www.example.com:80 DocumentRoot /opt/THS/htdocsServerRoot 必须和解压目录一致如果解压到了 /usr/local/THS 而这里还写 /opt/THS启动时大量相对路径都会失效。Listen 决定对外监听端口注意一个端口只能被一个 Listen 使用如果你同时跑着 Nginx就先把 Nginx 切走再动 THS否则会出现Address already in use。ServerName 设置域名加端口不设的话启动时会警告某些虚拟主机功能也受影响。DocumentRoot 是静态资源根目录可以和反向代理的路径共存只要前面的 ProxyPass 规则匹配得更精确即可。再往下是目录权限段。Apache 2.4 的写法是Require all granted2.2 是Order allow,deny/Allow from all。如果你不确定用ths -V查看编译参数里的 SERVER_VERSION也可以直接看 httpd.conf 里的注释THS 的包一般会保留默认配置片段。以下是我常用的段Directory /opt/THS/htdocs Options FollowSymLinks AllowOverride None Require all granted /DirectoryOptions 里别随意加 Indexes否则访问目录时会列出文件列表内网环境下容易把不该暴露的备份文件泄露出去。AllowOverride None 是关闭目录下的 .htaccess 生效防止应用上传目录里的 .htaccess 覆盖全局配置。3.2 用 mod_proxy 做一条最小反向代理THS 之所以能替代部分 Nginx 场景核心在 mod_proxy 系列模块。先确认 -M 输出里有proxy_module、proxy_http_module缺了就去找 modules/ 目录下有没有 mod_proxy.so有就在主配置里加 LoadModule。然后写如下配置ProxyRequests Off ProxyPreserveHost On ProxyPass /api/ http://192.168.1.10:8080/api/ ProxyPassReverse /api/ http://192.168.1.10:8080/api/ProxyRequests Off 是必须的。它关闭正向代理能力否则你的 THS 被内网机器当跳板变成开放代理这是安全事故。ProxyPreserveHost On 会保留原始请求里的 Host 头后端 Java 应用如果根据 Host 生成重定向 URL少了这个配置就可能跳错域。ProxyPass 负责把匹配 /api/ 的请求转发到后端指定地址路径后面的斜杠要一一对应两个 /api/ 都带斜杠转发时会以原 path 直接拼到后端地址后。若后端应用的上下文根不是 /api需要额外写 rewrite 规则但那样调试成本会上升我一般会建议后端正则把应用根设成一样。ProxyPassReverse 是给 THS 修改响应头里的 Location/Content-Location防止后端返回 302 时跳到它自己地址。这段配置放在 httpd.conf 全局或虚拟主机里都可以。如果放在全局它会影响所有 VirtualHost建议在相应的 VirtualHost 里写避免你只有一个 IP 却想给两个域名做不同转发规则时互相打架。改完后用httpd -t验证然后apachectl graceful平滑加载不要 restart避免瞬时断连。3.3 一组后端实例的负载均衡Balancer 与粘滞会话当后端 Java 实例有多个时直接多写几个 ProxyPass 不现实要用 Balancer 集群管理。配置如下Proxy balancer://mycluster BalancerMember http://192.168.1.10:8080 routeapp1 loadfactor1 BalancerMember http://192.168.1.11:8080 routeapp2 loadfactor2 ProxySet lbmethodbyrequests ProxySet stickysessionJSESSIONID /Proxy ProxyPass /app balancer://mycluster/app ProxyPassReverse /app balancer://mycluster/appBalancerMember 每行一个后端route 是节点标识loadfactor 是权重默认都是 1。我常用的分配方式是性能强的机器权重调高。lbmethod 有 byrequests按请求数默认、bytraffic按流量、bybusyness按忙闲程度简单的按请求数分配足够如果后端响应时间差距大可以换 bybusyness。stickysession 是会话粘滞的关键。Java 应用通常用 JSESSIONID 这个 Cookie 标识会话如果会话存在本机内存而不是 Redis就必须做粘滞否则同一个用户的请求在 app1 和 app2 间跳来跳去登录态会反复失效。ProxySet stickysession 告诉 THS 哪个 Cookie 或参数携带会话标识THS 会尽量把同一标识的请求固定到同一个后端。这里有个容易掉坑的地方如果后端是多级网关Cookie 的 Path 不是 /或者浏览器启用了隐私模式Cookie 可能不会随每次请求发给 THS粘滞就失效了。解决办法是让后端统一会话存储比如 Redis或者把 stickysession 换成 URL 里的 jsessionid但 URL 重写方式的改造较繁琐。我建议先把后端会话共享修好再把这里的粘滞关掉负载分配会均匀很多如果非要粘滞优先确保 Cookie 能正常返回。3.4 动静分离与缓存头让 THS 比“傻转发”更有价值纯反向代理只是流量搬运THS 还应该承担静态资源缓存和响应头控制。常见做法是在 httpd.conf 里加一个 Location 或 FileMatch 块对图片、CSS、JS 设置过期时间减少后端压力。配置如下IfModule mod_expires.c ExpiresActive On ExpiresByType image/jpeg access plus 30 days ExpiresByType text/css access plus 7 days /IfModulemod_expires 需要加载如果 -M 里没有确认 modules 下有没有 mod_expires.so。ExpiresByType 后面可以写access plus 30 days或now plus 7 days等格式。这里要注意Expires 头是缓存的“最后期限”但如果后端动态页面也设置了 Cache-Control: no-cache后端响应头优先级更高THS 不会强制覆盖。如果某些静态资源需要带跨域头还得配合 mod_headersLocation /static/ Header set Access-Control-Allow-Origin * /LocationHeader set 会无条件覆盖原有值用 Header append 表示追加。生产环境里我很少直接写 *因为内网用户大概率走统一身份认证跨域场景往往是前后端分离的前端页面要访问 THS 上的静态资源这时用 Vary 或精确域名更稳妥。写到这里动静分离策略已经够用了动态请求走 Balancer静态资源由 THS 直接返回并在响应头里告诉浏览器可以缓存多久。4. THS 从解压到上线的踩坑记录现象、原因、解决4.1 坑一提示找不到 libapr-1.so.0服务起不来现象THS_x86.tar.gz 解压后执行/opt/THS/bin/ths -V或apachectl start输出error while loading shared libraries: libapr-1.so.0: cannot open shared object file进程起不来。原因THS 主程序对 APR、PCRE、OpenSSL 等基础库的依赖不是静态链接在程序里的而是运行时动态加载。tar.gz 包通常只带 THS 自己的库和模块不会干涉系统目录里的依赖库。目标机器上如果原本只装了 Nginx 而没有装 Apache 全家桶这些基础库可能缺失或版本不匹配。解决先跑ldd /opt/THS/bin/ths确认究竟缺哪几项再安装系统包。CentOS/RHEL 系执行yum install apr apr-util pcreDebian/Ubuntu 系执行apt install libapr1 libaprutil1 libpcre3。装完以后再 ldd看到not found全部消失即可。如果因为内网源没有这些包可以把库文件复制到 /opt/THS/lib 下并在启动脚本里对 LD_LIBRARY_PATH 追加该路径但这是下策后续每次升级都要维护环境变量不建议作为正式方案。4.2 坑二端口被占用或者被防火墙策略拦截现象apachectl start 显示启动成功但 curl 一直连接不上。ps -ef 里有 ths 进程netstat 却看不到 80 端口监听。或者只有本机能访问外部机器访问超时。原因端口被占用的场景比较直接——别的 Web 服务先绑定了 80外部访问超时的场景则涉及防火墙或 SELinux。THS 默认监听 80若系统里 Nginx、Tomcat 或者其他 HTTP Server 抢占了 80THS 的 listen 套接字创建失败但主进程可能不会立即退出错误只留在 error_log 里。解决先看 error_log 有没有Address already in use再用netstat -pntl或ss -lntp找出占用者。如果只是端口冲突修改 httpd.conf 里的 Listen 为 8080 或其他可用端口即可。如果外部访问不了检查防火墙放行端口firewall-cmd --zonepublic --add-port8080/tcp --permanent firewall-cmd --reloadCentOS/RHEL 7Ubuntu 则用ufw allow 8080/tcp。还要执行getenforce确认 SELinux 状态如果是 Enforcing大概率是下面的坑三。4.3 坑三SELinux 把 THS 的陌生端口给挡了现象监听端口从默认的 80 改成了 8080进程也起来了同一台机器上 curl 通但从别的机器访问还是连不上。关闭防火墙后问题依旧。原因SELinux 的 httpd_t 域允许的端口列表是预设好的THS 虽然不叫 httpd但通常也被放进 httpd_t 域或类似类型。SELinux 策略允许绑定 80、443 这类标准端口却不放行 8080 这类非标准端口即使防火墙已经放行内核仍然会拒绝 bind()。解决使用 semanage 把端口加入 http_port_t。命令如下semanage port -a -t http_port_t -p tcp 8080如果提示Port 8080 already defined改用 -m 修改semanage port -m -t http_port_t -p tcp 8080执行完再getenforce确认是 Enforcing然后重启 THS。这里我不建议直接setenforce 0因为那是关闭整个 SELinux相当于把安全机制废掉测试可以生产别这么干。如果你不想维护 SELinux 规则可以把 THS 的标准端口就留在 80/443或者统一规划内网端口一次 semanage 加全。4.4 坑四后端响应稍慢就报 502日志里全是 timeout现象压测时只要后端接口处理时间超过十几秒THS 立刻返回 502 Bad Gateway而后端应用其实还在正常处理最终也能返回数据但经过 THS 就变成错误。原因mod_proxy 的 ProxyTimeout 默认值很短取决于编译参数另外后端响应时间如果接近 Timeout 就会误判超时。另外如果后端在响应前有长轮询或慢查询THS 的 worker 线程被一直占着也会快速耗尽连接池导致后续请求失败。解决在 httpd.conf 的 proxy 配置段调整超时参数ProxyTimeout 300 SetEnv proxy-sendchunked 1ProxyTimeout 是按秒算的300 表示允许后端最长 5 分钟才给出响应。这里要结合实际接口最慢耗时来设置不要盲目调到很大否则恶意请求能把 worker 全部吊死。同时检查 MaxRequestWorkers 是否太小如果日志里出现server reached MaxRequestWorkers setting就需要把 worker 数调大或者限流。这个问题在 Nginx 里叫做 proxy_read_timeout迁移过来的运维经常忽略两者对应关系。4.5 坑五解压到一半报 Cannot exec 或启动脚本权限错乱现象tar -xzvf可以解压但解压完跑 bin/ths 报 Permission deniedls -l看权限主程序竟然没有 x 位。或者在 Windows 上解压后传到 Linux整个目录的属主和权限都不对。原因tar.gz 包在制作时会保留文件权限位但如果你用 Windows 下的 WinRAR/7-Zip 解压它默认不还原 owner/group 和 execute 位然后你又用 tar 重新打包传到服务器权限信息就丢了还有一种可能是包本身是源码包需要先编译但 THS_x86.tar.gz 这个名字暗示是二进制包所以更多是前一种。解决在 Linux 上直接解压 tar.gz不要中间经过 Windows。如果已经坏了用以下命令批量修复可执行文件权限chmod x /opt/THS/bin/ths /opt/THS/bin/apachectl find /opt/THS -type d -exec chmod 755 {} \;不要无脑chmod -R 777会把安全边界暴露。正确做法是只给 bin 目录下确实需要执行的程序加 x目录保持 755普通文件 644。同时用chown -R root:root /opt/THS重置属主如果 THS 需要以非 root 运行后续再单独改 logs/ 目录属主即可。5. 把 THS 纳入 systemd 管理开机自启、进程守护和日志切割5.1 写一个可用的 ths.service 单元文件THS_x86.tar.gz 解压后自带 apachectl 脚本但裸跑 apachectl 不会在服务器重启后自动拉起进程崩溃了也不会自动重启。生产环境必须用守护进程来管。CentOS 7、Ubuntu 16.04 都用 systemd所以下面的方法对所有现代 Linux 都通用。先创建服务文件 /etc/systemd/system/ths.service内容如下[Unit] DescriptionTongHttpServer THS Afternetwork.target [Service] Typeforking PIDFile/opt/THS/logs/ths.pid ExecStart/opt/THS/bin/apachectl start ExecReload/opt/THS/bin/apachectl graceful ExecStop/opt/THS/bin/apachectl stop PrivateTmptrue LimitNOFILE65535 Restarton-failure RestartSec3 [Install] WantedBymulti-user.targetTypeforking 很关键因为 apachectl start 会启动一个父进程然后立即返回真正的服务进程变成后台子进程systemd 需要从 PIDFile 找到主进程的 PID 来跟踪。所以确认 THS 的 apachectl 脚本里 PIDFile 路径和这里的配置一致。如果脚本没有生成 pid 文件就改成 Typesimple 并用 ExecStart 直接执行 /opt/THS/bin/ths但那样日志输出会绑在标准输出上需要额外配置。ExecReload 用 graceful它会平滑重载配置不中断现有连接上线时非常有价值。Restarton-failure 可以让 systemd 在进程异常退出时自动拉起RestartSec3 防止频繁重启把日志刷爆。LimitNOFILE 设为 65535 是因为高并发下 THS 需要打开大量文件描述符默认 1024 肯定不够。写完后执行systemctl daemon-reload systemctl enable ths systemctl start ths systemctl status thsenable 会创建开机自启的软链status 可以看到进程状态、内存占用和最近日志。如果出现启动失败systemctl status 的输出会包含失败原因例如ExecStart timeout或PID file not readable比翻 error_log 直观多了。5.2 让日志按时切割别让 access.log 无限膨胀THS 默认把所有访问日志写进 logs/access_log无切割的情况下压测一晚上就能产出几个 GB。日志太大会导致磁盘告警、排查困难、甚至磁盘满后 THS 无响应。常见做法是让 THS 直接把日志管道给 rotatelogs 工具按天切割。配置如下CustomLog |/opt/THS/bin/rotatelogs -l /opt/THS/logs/access.%Y%m%d.log 86400 combinedrotatelogs 是 Apache/THS 自带的日志轮转工具-l 表示用本地时间而不是 UTC86400 是秒数表示每天切换一个新文件。写入时必须加引号管道符号后面的路径要绝对路径否则 apachectl 在后台模式下找不到命令。改完配置后记得 graceful否则 CustomLog 不会重新读取。如果你想保留 30 天可以用 logrotate 方式在 /etc/logrotate.d/ths 里写配置按天压缩。但 logrotate 需要 crond 触发而 rotatelogs 是 THS 自身切日志无外部依赖我通常优先用 rotatelogs。日志格式也可以调整。默认 combined 包含客户端 IP、时间、请求行、状态码、Referer、User-Agent。如果不想记录 User-Agent 或需要加响应时间可以自定义 LogFormatLogFormat %h %l %u %t \%r\ %s %b %D custom_perf CustomLog |/opt/THS/bin/rotatelogs -l /opt/THS/logs/access.%Y%m%d.log 86400 custom_perf%D是处理耗时微秒压测时能从访问日志里筛出慢请求比逐个抓包更省事。5.3 用 systemd 做启停和排障的日常操作事情不能只停在配置文件里。日常启停我基本不碰 apachectl 了全部用 systemctl。下面几条命令要熟练systemctl reload ths # 平滑重载相当于 apachectl graceful systemctl stop ths # 停止 systemctl restart ths # 重启会断开连接谨慎 journalctl -u ths -f # 实时看 systemd 记录的日志其中 systemctl reload 不等于 restart它在 THS 主进程不退出、连接不断开的情况下重新读取 httpd.conf发布新后端节点时非常合适。journalctl 默认记录 THS 进程的 stderr/stdout 输出但如果 THS 已经通过 apachectl 把日志写入文件journalctl 里可能只有框架事件。如果 systemd 日志里出现Failed to read PID from file /opt/THS/logs/ths.pid: Invalid argument说明 pid 文件路径没有生成或权限不对回到 5.1 的 PIDFile 设置。另一个我踩过的坑是 systemd 在 stop 时并不会等慢连接全部结束它等的是 PIDFile 里的主进程退出如果子进程挂起导致 stop 卡住要结合 TimeoutStopSec 调整TimeoutStopSec15超过 15 秒停不掉systemd 会强杀。正常情况下 apachectl stop 几秒就完成如果经常打到这个超时基本说明有慢请求或 worker 卡死要去看 error_log。6. 上量之前先做一轮压测ab 命令、Worker 参数和 TCP 细节6.1 先压静态资源用 ab 拿到基线数据配置完成后别直接接生产流量。我习惯先用压测工具给 THS 一个预期承载数字。最简单的是 ab随 httpd-tools 安装。命令如下ab -n 10000 -c 100 -k http://127.0.0.1/static/index.html-n 是总请求数-c 是并发数-k 开启 KeepAlive。压测结果里重点看 Requests per second 和 Time per request。如果 RPS 不到一千先别怀疑机器性能大概率是 KeepAlive 没开或者 worker 数太小。此时可以顺手抓一下 THS 的访问日志确认记录到的时长分布。6.2 调整 Worker 和连接参数THS 的并发能力由 prefork/worker 事件模型和 MaxRequestWorkers 决定。常见的生产配置如下StartServers 8 MinSpareServers 5 MaxSpareServers 20 MaxRequestWorkers 512 MaxConnectionsPerChild 10000 KeepAlive On KeepAliveTimeout 5 Timeout 60MaxRequestWorkers 是同时能处理的请求数上限超出后请求排队。这个值不是越大越好每个 worker 都会吃内存512 在 4C8G 的 x86 机器上通常够用配置后观察 load average 和内存逐步上调。MaxConnectionsPerChild 设置为 10000 表示每个 worker 处理满 1 万请求后退出重建用来化解偶尔的内存泄漏如果不设置进程会一直跑老。KeepAliveTimeout 5 表示单个 TCP 连接上空闲 5 秒就断开太短会频繁握手太长会占住 worker 不放压测时要开着 KeepAlive 的 k 选项否则结果失真。如果后端是 Tomcat压测动态接口时不要用 ab -k因为 Tomcat 自身线程数也会成为瓶颈。可以先用 wrk 测一次纯 THS 转发再直接压后端 Tomcat对比差值就能看出谁的吞吐更低。wrk 的线程模型比 ab 轻很多适合长连接场景但多数系统自带 wrk 少ab 胜在随 git 工具链可得作为基线足够。6.3 上线前最后一步归档版本和模块清单压测达标后最终要做的是留下现场证据。把ths -V和ths -M的输出存到服务器的一个固定文件里并让部署脚本每次发布后自动更新。这样下次谁报告“THS 有问题”你可以先对比模块清单而不是凭记忆猜。我自己就吃过亏环境里有五台机器只有一台加载了 mod_headers结果那台的跨域响应头正常其他四台全部缺失排查到最后才定位是二进制包不一致。希望这个习惯能帮到你。本文还有配套的精品资源点击获取