ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

TongWeb7 Linux部署实战:授权、调优、systemd与排障

TongWeb7 Linux部署实战:授权、调优、systemd与排障 1. 先把 TongWeb7 这层窗户纸捅破它到底解决什么问题前阵子接了个活客户那边一套跑了七八年的 Java Web 系统要从 Tomcat 挪到 TongWeb7 上要求在 Linux 上重新部署一遍。我原本估摸着半小时收工结果整整折腾了一下午——先是解压出来一堆乱码文件名接着 License 文件放错目录导致启动脚本悄无声息地退出了最后发现系统的文件句柄数只有 1024压测一上来连接就被拒。这类部署活儿难的不是会不会而是那些文档里从来不写、但一定会遇到的边角问题。TongWeb7 是东方通推出的一款企业级 Java 应用服务器实现了 Java EE 7 规范涵盖 Servlet 3.1、JSP 2.3、EJB 3.2、JMS 2.0、JPA 2.1 这一整套能力。它和 Tomcat 最大的区别在于Tomcat 本质是个 Servlet 容器而 TongWeb 是完整的应用服务器自带管理控制台、集群会话复制、JNDI 资源管理、国密算法支持这些企业级特性。很多项目之所以指定用它是因为系统集成的中间件清单里写死了这一款或者老应用用了 EJB、JMS 这类 Tomcat 原生不支持的东西迁不过去。这篇文章面向的是需要在一台干净的 Linux 服务器上从零把 TongWeb7 跑起来的运维和开发同学。不管你用的是 CentOS、Ubuntu还是麒麟、统信这类国内发行版部署路径基本一致。我会把安装、授权、调优、服务化、排障这条完整链路掰开揉碎讲一遍重点放在那些真正会卡住你的地方。1.1 它和 Tomcat、WebLogic 的实际差异在哪先做个横向对比心里有个谱维度TomcatTongWeb7WebLogic规范覆盖仅 Servlet/JSP完整 Java EE 7完整 Java EE管理方式改 XML、命令行Web 控制台 命令行 配置文件控制台 WLST部署单元warwar / earwar / ear集群会话需自行搭建内置会话复制内置授权模式Apache 开源商业 License商业 License安装体积十几 MB数百 MB上 GB从表里能看出来TongWeb7 的定位是轻量一些的 WebLogic但比 Tomcat 重。它的安装包通常有几百兆解压后目录结构和 Tomcat 有几分神似但多了license、deploy、domains这类目录。熟悉 Tomcat 的人上手会有种似曾相识但又处处不同的感觉这也是为什么很多人第一次部署会踩坑——按 Tomcat 的习惯去操作往往行不通。1.2 版本和 CPU 架构必须先核对清楚这一步千万别跳过。TongWeb7 的安装包是按 CPU 架构分发的常见的有x86_64Intel/AMD/海光和aarch64鲲鹏/飞腾两种个别版本还有龙芯 LoongArch 的包。拿错包解压后一执行报错非常直接bash: ./startserver.sh: /bin/sh: bad ELF interpreter # 或者 cannot execute binary file: Exec format error看到这两个报错别急着怀疑 JDK先执行下面几条命令确认底数uname -m # 输出 x86_64 还是 aarch64 cat /etc/os-release # 看发行版和版本号 getconf LONG_BIT # 32 还是 64安装包的文件名里一般会带架构标识比如TongWeb7.0.x.x_x86_64.tar.gz。如果文件名里没有就找厂商要一份架构对照说明别靠猜。2. 装之前的环境底数JDK、句柄数、安全策略一个都不能少部署这类中间件八成以上的启动失败其实发生在 TongWeb 启动之前问题出在操作系统这一层。我见过太多人上来就解压、就跑脚本然后卡在莫名其妙的报错上。正确的做法是先把系统环境捋一遍逐项确认后面能省下大量返工时间。2.1 JDK 的版本选择和 JAVA_HOME 的坑TongWeb7 主流版本要求 JDK 8 及以上多数项目用 1.8较新的小版本开始支持 JDK 11 和 JDK 17。选哪个版本取决于你的应用编译时用的字节码版本不是越新越好——老应用在 JDK 17 上很可能因为模块化限制直接起不来。装完 JDK 后有几件事必须做which java # 看当前用的是哪个 readlink -f $(which java) # 追到真实路径 java -version # 确认版本和位数关键在于JAVA_HOME。TongWeb 的启动脚本会去读这个变量如果没设或者设错了脚本会在早期阶段就退出。建议写进/etc/profile.d/java.shexport JAVA_HOME/usr/local/jdk1.8.0_361 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar写完之后source /etc/profile生效再用echo $JAVA_HOME验证。这里有个细节如果你是通过su - tongweb切换用户环境变量会重新加载但如果用su tongweb不带减号环境变量不会刷新很容易出现root 下测得好好的切用户就起不来的情况。这是我踩过的第一个坑。另外提一句如果系统里装了多个 JDK比如系统自带一个 openjdk、你手动又装了一个务必确认 TongWeb 用的到底是哪个。有些启动脚本内部会硬编码 JDK 路径改配置文件比改环境变量更可靠。2.2 文件句柄数和内核参数要提前放量默认的 Linux 单进程文件句柄限制通常是 1024这个数值对中间件来说完全不够用。TongWeb 一个进程打开的 socket、日志文件、jar 包句柄加起来轻松超过这个数压测或者并发一高就是Too many open files。修改/etc/security/limits.conf追加tongweb soft nofile 65535 tongweb hard nofile 65535 root soft nofile 65535 root hard nofile 65535同时在/etc/security/limits.d/下确认没有被别的文件覆盖掉。改完重新登录该用户用ulimit -n验证。注意这个参数对已经登录的会话不生效必须重新开一个终端。还有两个常被忽略的参数sysctl -w net.core.somaxconn32768 sysctl -w net.ipv4.tcp_max_syn_backlog16384somaxconn决定了 accept 队列长度默认值在很多发行版上只有 128高并发下会出现连接被丢弃的情况。写进/etc/sysctl.conf持久化。2.3 SELinux、防火墙、时区、字符集这四件事这四个每一件单独拎出来都能让你排查半天。SELinux先getenforce看状态如果是EnforcingTongWeb 读写某些目录、绑定非标准端口时会被拦。临时用setenforce 0验证是不是它的问题确认后要么改成Permissive要么老老实实写 SELinux 策略。生产环境我倾向于配置策略而不是直接关但过渡阶段先关掉确认问题来源也是常规做法。防火墙别以为开放了 Web 端口就完事了。TongWeb 至少涉及三个端口——业务端口默认 8080、管理控制台端口通常是 9060以启动日志为准、关闭端口默认 8005。少开一个就会出现能访问应用但进不去控制台的迷惑现象。时区用timedatectl确认。时区不对会让日志时间线错乱更麻烦的是 License 校验依赖系统时间时间偏差大了会直接判为无效。字符集locale看一下如果输出里全是POSIX那中文乱码几乎是必然的。生成 UTF-8 localelocaledef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 localedef -c -f UTF-8 -i en_US en_US.UTF-8然后写进/etc/locale.conf设LANGzh_CN.UTF-8。3. 安装包落地账号、解压、权限的完整链路环境捋顺了接下来才是真正动手。这一段的操作看着简单但每一步都有讲究尤其是解压和权限这两块做错了后面全是麻烦。3.1 创建一个专用的运行账号绝对不要用 root 跑 TongWeb。这是原则问题不是习惯问题——中间件被拿下的例子不少root 身份运行意味着整个系统都在风险敞口里。groupadd -r tongweb useradd -r -g tongweb -m -d /home/tongweb -s /bin/bash tongweb passwd tongweb-r表示系统账号-m创建家目录。建完之后把安装目录的所有权交给它mkdir -p /opt/tongweb chown -R tongweb:tongweb /opt/tongweb这里有个实操建议安装目录别放在/root下面也别放在/tmp里。/tmp在很多发行版上配置了noexec挂载选项脚本根本执行不了而且系统重启会被清理。3.2 解压时中文文件名乱码的真正原因这一条是热词里高频出现的Linux 解压文件乱码我专门说一下。关键点在于tar.gz 本身几乎不会乱码zip 才是重灾区。原因是 tar 打包时保存的是文件名的原始字节流解包时原样写回跟编码无关。而 zip 格式的历史包袱比较重Windows 上的压缩工具默认用 GBK 编码存文件名Linux 解压时按 UTF-8 解释就成了一堆问号或者方块。如果你手上是 zip 包有几种解法# unzip 6.0 及以上支持指定编码 unzip -O CP936 package.zip # 用 libarchive 的 bsdtar bsdtar -x --charsetGBK -f package.zip # 用 unarmacOS 移植过来的工具中文字符处理很稳 unar -e GBK package.zip如果是 tar.gz 且确实有乱码少数从特殊工具打包出来的包会这样GNU tar 1.28 以上支持转换tar --iconvGBK,UTF-8 -xzvf package.tar.gz上传之前先校验一下文件完整性别传输中断了都不知道md5sum TongWeb7.0.x.x_x86_64.tar.gz # 和厂商给的校验值比对解压后进入目录第一件事是ls -l bin/看看脚本都是什么名字。不同小版本的脚本命名可能不一样我见过startserver.sh、tongweb.sh、startup.sh好几种别照着某篇教程硬套。看启动脚本里的注释和变量定义比看教程靠谱得多。3.3 目录结构与权限规划解压出来的目录大致长这样目录作用bin启停脚本、工具脚本conf主配置文件、日志配置、License 相关lib依赖 jar 包deploy应用部署目录热部署扫描logs运行日志、访问日志temp/work临时文件、JSP 编译产物license授权文件存放位置部分版本权限上bin下的.sh脚本需要可执行位chmod x bin/*.sh。logs和temp目录需要写权限用tongweb账号运行就没这个问题。整体做一次chown -R tongweb:tongweb最省心。4. License 与首次启动最容易卡住的十分钟TongWeb 是商业中间件没有 License 起不来。这一步是新手最容易翻车的地方因为失败时的表现往往是脚本跑了一下就退出了什么提示都没有。4.1 License 文件的获取与放置位置License 通常需要向厂商申请申请时要提供服务器的 MAC 地址、IP、主机名等信息各家规则略有差异以厂商交付说明为准。拿到的是一个license.dat或者类似名字的文件需要放到指定目录。放置位置不同版本有差异常见的是conf目录或者独立的license目录。判断方法很简单看启动日志。启动失败时把logs下的日志翻出来一般会有明确提示比如License file not found License is expired License does not match this machinedoes not match this machine这句意味着绑定的机器信息变了——换网卡、改主机名、迁移虚拟机都会导致。虚拟化环境下要特别注意克隆虚拟机时 MAC 会变License 会直接失效。提示拿到 License 后先备份一份到别的地方并且记录申请时用的主机名和 IP。后面做迁移、扩容时能省很多沟通成本。4.2 第一次启动要盯住什么启动命令执行之后别扭头就走前一两分钟的输出信息量最大。su - tongweb cd /opt/tongweb/TongWeb7.0 ./bin/startserver.sh观察几个关键信息JVM 有没有正常初始化、有没有绑定端口、License 校验有没有通过、最后有没有打印出控制台访问地址。同时另开一个窗口看端口ss -lntp | grep -E 8080|9060端口起来了不代表应用能用但端口都起不来那一定是路径、权限或者配置的问题。如果启动脚本一闪就退出用下面的方式追一下bash -x ./bin/startserver.sh-x会把每条命令的执行过程打出来卡在哪一行一目了然。4.3 控制台登录和必须做的三件事浏览器打开http://服务器IP:管理端口/console管理端口以启动日志实际打印为准常见为 9060。默认凭据各版本不一样老版本常见admin/admin123新版本首次登录会强制改密具体以安装包内说明或厂商交付文档为准。进去之后先做三件事改掉默认密码并且改成一个符合密码复杂度要求的强口令。确认端口配置把管理端口限制在内网访问别暴露到公网。检查 JVM 参数默认的堆大小通常偏小生产环境必须调整。5. 按生产标准调优从能跑到跑得稳默认配置只保证能启动离能扛住生产流量还有距离。这一节讲几个关键参数的调整思路。5.1 JVM 堆内存怎么定堆大小的经验值物理内存的 50% 到 60%且不超过 32GB。为什么强调 32GB因为 JVM 在堆超过约 32GB 后会失去指针压缩Compressed OOPs的优化对象引用从 4 字节变成 8 字节实际内存占用反而涨得比堆增长更快得不偿失。参数一般在bin下的启动脚本里或者conf目录下某个vmoptions之类的外部配置文件里。典型配置-Xms8g -Xmx8g \ -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m \ -XX:UseG1GC \ -XX:MaxGCPauseMillis200 \ -XX:HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath/opt/tongweb/dumps \ -Xloggc:/opt/tongweb/logs/gc.log \ -XX:PrintGCDetails -XX:PrintGCDateStamps-Xms和-Xmx设成一样大避免运行期反复扩容缩容带来抖动。GC 策略上JDK 8 环境如果堆不大4GB 以内用 Parallel 更省 CPU堆大了就上 G1停顿更可控。HeapDumpOnOutOfMemoryError一定要开出问题的时候这份 dump 就是唯一的救命线索。5.2 端口、连接器和线程池端口配置在conf下的主配置文件里或者通过控制台图形界面改。除了改端口本身还要关注连接器参数参数含义建议值maxThreads最大工作线程数200~500按业务 IO 特性调minSpareThreads最小空闲线程maxThreads 的 10%acceptCount等待队列长度与 somaxconn 匹配connectionTimeout连接超时20000~30000 毫秒maxConnections最大连接数视并发量而定maxThreads不是越大越好。业务如果是 CPU 密集型线程数超过核数太多只会加剧上下文切换如果是 IO 密集型大量数据库、外部接口调用可以适当放大。我一般的做法是先在测试环境做一轮压测从 200 起步观察 CPU、线程栈和响应时间再往上加。5.3 字符编码的三层链路中文乱码几乎每个项目都会碰到而且往往是应用代码没问题、数据库也没问题就是显示乱码。原因在于编码链路有三层任何一层断了都会出问题JVM 层加-Dfile.encodingUTF-8同时确认系统 locale 是 UTF-8。容器层连接器上配置 URI 编码为 UTF-8POST 请求体编码同理。数据库层JDBC 连接串里加characterEncodingutf8MySQL 还要注意表和列的字符集是不是utf8mb4。排查的时候用二分法先写一个最简单的 JSP 或者接口直接输出中文字符串看是哪一层开始乱的。如果是终端里cat日志乱码那多半是 SSH 客户端编码没设对跟服务器无关——这一条我自己就误判过好几次。6. 应用部署的三种姿势按场景挑TongWeb7 部署应用的方式比较灵活控制台、目录、脚本三条路各有适用场景。6.1 控制台部署适合首次和调试登录管理控制台找到应用部署入口上传 war 包指定上下文路径提交。整个过程图形化能直接看到部署日志和异常堆栈调试阶段最省事。缺点是上传大包几百兆时容易超时而且每次都要人工操作。6.2 目录部署适合自动化发布把 war 包丢进deploy或autodeploy目录容器按扫描周期自动检测并部署。这种方式特别适合配合 CI/CD 做自动化——构建流水线最后一步用scp把包推过去剩下的交给容器。需要注意的是自动扫描有间隔改完包不会立刻生效急的时候还是得手动触发或者重启。上下文路径的命名也值得一提。默认按 war 包文件名生成中文名和带特殊字符的名字一定要改掉否则 URL 里会出现百分号编码前端调接口时容易出玄学问题。6.3 脚本化部署批量场景的标配多实例环境下人工操作迟早出错。我的做法是写一个发布脚本固定流程停服务 → 备份旧包 → 替换新包 → 启动服务 → 健康检查。健康检查这一步别省简单的curl -I看返回码就够用#!/bin/bash set -e APP_DIR/opt/tongweb/TongWeb7.0 WAR/tmp/app.war BACKUP/opt/backup/$(date %Y%m%d%H%M%S) $APP_DIR/bin/stopserver.sh || true sleep 5 mkdir -p $BACKUP mv $APP_DIR/deploy/app.war $BACKUP/ 2/dev/null || true cp $WAR $APP_DIR/deploy/app.war chown tongweb:tongweb $APP_DIR/deploy/app.war su - tongweb -c $APP_DIR/bin/startserver.sh for i in $(seq 1 30); do if curl -s -o /dev/null -w %{http_code} http://127.0.0.1:8080/app/health | grep -q 200; then echo deploy success exit 0 fi sleep 2 done echo deploy failed, check logs exit 1脚本里set -e让任何一步失败就中断避免带着半成品状态继续跑。健康检查最多等 60 秒超时就报错退出让流水线标红。7. 交给 systemd 托管让它像系统服务一样活着手动敲脚本启动的服务服务器一重启就没了运维半夜还得爬起来。用 systemd 托管是标准做法。7.1 unit 文件怎么写在/etc/systemd/system/tongweb.service里写[Unit] DescriptionTongWeb 7 Application Server Afternetwork.target remote-fs.target Wantsnetwork-online.target [Service] Typeforking Usertongweb Grouptongweb EnvironmentJAVA_HOME/usr/local/jdk1.8.0_361 EnvironmentLANGzh_CN.UTF-8 PIDFile/opt/tongweb/TongWeb7.0/logs/tongweb.pid ExecStart/opt/tongweb/TongWeb7.0/bin/startserver.sh ExecStop/opt/tongweb/TongWeb7.0/bin/stopserver.sh ExecReload/bin/kill -HUP $MAINPID Restarton-failure RestartSec10 LimitNOFILE65535 TimeoutStartSec180 TimeoutStopSec120 StandardOutputappend:/opt/tongweb/logs/systemd-out.log StandardErrorappend:/opt/tongweb/logs/systemd-err.log [Install] WantedBymulti-user.target几个关键点解释一下Typeforking适用于脚本自己 fork 到后台的场景。如果启动脚本本身是前台阻塞的改成simple。PIDFile必须和启动脚本实际写出的 pid 文件路径一致路径错了 systemd 会认为启动失败即使进程其实活着。LimitNOFILE在 unit 里再设一遍防止 limits.conf 没生效。Restarton-failure让进程意外挂掉时自动拉起配合RestartSec避免疯狂重启打爆日志。TimeoutStartSec给足 180 秒中间件启动本来就慢默认 90 秒经常不够。7.2 生效与验证systemctl daemon-reload systemctl enable tongweb systemctl start tongweb systemctl status tongweb验证的时候别只看active (running)那只能说明主进程还在。真正的验证要访问一次业务接口确认返回正常。另外重启一次机器看服务是不是自动起来了。8. 排障实战那些让我熬到深夜的问题前面讲的都是按部就班这一节讲出了事怎么查。我把这些年遇到的典型问题整理成一张表后面挑几个展开说。现象常见原因排查手段启动脚本闪退JAVA_HOME 未设 / License 缺失bash -x跟踪看 logs端口未监听端口被占用 / 权限不足ss -lntplsof -i:8080进程无故消失被 OOM Killer 杀掉dmesg | tail -50中文乱码locale / file.encoding / DB 字符集三层二分排查访问缓慢GC 频繁 / 线程池打满jstat、jstackLicense 失效主机信息变化 / 时间漂移核对 MAC、timedatectl8.1 启动失败要按从下往上的顺序查排查链路应该是这样的先看进程有没有起来再看端口有没有监听再看日志有没有报错最后才怀疑应用本身。顺序颠倒的话容易在应用层瞎折腾半天结果发现是端口被占了。具体操作ps -ef | grep -i tongweb | grep -v grep ss -lntp | grep 8080 ls -lt logs/ | head # 看最新日志文件 tail -200 logs/server.log # 看有没有异常堆栈 dmesg | tail -50 # 看有没有 OOM Killer 记录dmesg这一条特别容易被忽略。进程自己消失了且日志里没有任何异常十有八九是被内核的 OOM Killer 干掉了dmesg里会有明确的Killed process记录。这种情况下光加堆内存没用得先看是不是堆设得太大导致物理内存不够。8.2 启动特别慢可能是熵池不够这是个比较冷门但确实存在的问题。JVM 初始化安全随机数生成器时会读/dev/random在虚拟机上熵池积累很慢会导致启动卡住几十秒甚至几分钟。表现是日志停在某个位置长时间不动。验证方式cat /proc/sys/kernel/random/entropy_avail如果数值长期低于 200那基本可以确定。解决办法是安装haveged或者rng-tools来补充熵源yum install -y haveged systemctl enable --now haveged另一个规避方式是在 JVM 参数里把随机数源指定为非阻塞的/dev/urandom。具体用哪种看你的安全要求。8.3 内存溢出和线程泄漏的现场取证线上跑着跑着变慢最典型的两类原因内存回收不掉内存泄漏和线程堆积线程泄漏。这两个问题事后补救没用必须在慢的时候抓现场。内存方面jstat -gcutil pid 1000 10 # 每秒采样看老年代使用率是否持续上涨 jmap -histo:live pid | head -30 # 看哪些对象占得最多 jmap -dump:live,formatb,file/tmp/heap.hprof pid # 抓堆快照如果老年代使用率在 Full GC 之后还是不降那就是有对象被长期持有堆快照拿去用 MAT 一分析就能定位。线程方面jstack pid /tmp/thread.txt grep -c java.lang.Thread.State /tmp/thread.txt # 总线程数 grep java.lang.Thread.State /tmp/thread.txt | sort | uniq -c如果发现大量线程卡在WAITING且堆栈相同那就是有地方在无限制地创建线程或者等待锁。隔几分钟抓两次对比能看出哪些线程一直没动。8.4 日志暴涨把磁盘撑爆这条听起来低级但我见过不止一次。访问日志加上调试日志高峰期一天几十 GB磁盘一满整个服务全部挂掉连带数据库连接池都报错。防护措施有三层一是日志级别调成INFO或WARN别在生产开DEBUG二是配置按天滚动加保留天数比如保留 15 天三是配 logrotate 兜底/opt/tongweb/TongWeb7.0/logs/*.log { daily rotate 15 missingok notifempty compress copytruncate }copytruncate这个选项要注意——它不移动文件而是清空适用于进程一直持有文件句柄的场景。如果不加这个选项日志会被轮转走但进程还在往老句柄里写导致磁盘空间不释放这是个很隐蔽的坑。另外单独给日志挂一个分区即使写满了也不影响系统盘。9. 前置代理和日常巡检的几条实战经验服务跑起来只是开始后面还有长期的运维。这一节讲几个我认为最有价值的实践。9.1 Nginx 前置该怎么配直接让 TongWeb 对外提供服务不是好主意一来不好做统一入口和证书管理二来静态资源交给 Nginx 处理效率高得多。典型配置upstream tongweb_backend { server 127.0.0.1:8080 weight1 max_fails3 fail_timeout30s; keepalive 64; } server { listen 443 ssl; server_name app.example.com; client_max_body_size 100m; charset utf-8; location / { proxy_pass http://tongweb_backend; proxy_http_version 1.1; proxy_set_header Connection ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 30s; proxy_read_timeout 120s; proxy_send_timeout 120s; } location /static/ { root /data/www; expires 7d; } }几个容易忽略的点proxy_set_header Connection 配合keepalive才能复用长连接少了这行等于白配client_max_body_size默认 1MB文件上传场景不加会直接返回 413X-Forwarded-For不传的话应用里拿到的客户端 IP 全是 127.0.0.1做风控和审计时会很尴尬。9.2 日常巡检该看什么我习惯写一个巡检脚本每天跑一次输出几个关键指标进程是否存活、端口是否监听、JVM 堆使用率、GC 次数和耗时、日志里的 ERROR 数量、磁盘使用率。堆使用率持续超过 80% 或者 Full GC 次数陡增就要提前介入别等到真出故障。PID$(pgrep -f tongweb | head -1) echo 进程 [ -n $PID ] echo running: $PID || echo NOT RUNNING echo 堆使用 jstat -gcutil $PID 2/dev/null | tail -1 echo 日志错误 grep -c ERROR logs/server.log echo 磁盘 df -h /opt这类脚本的价值在于把发现问题的时机从用户投诉提前到故障发生前。我做过一个统计加了日常巡检之后紧急故障的数量下降了一大截因为大部分问题在变成故障之前就已经被发现了。9.3 我踩过的几个坑直接告诉你结论最后分享几个具体到操作层面的经验都是真金白银换来的别在生产上直接用kill -9。虽然大部分情况下能重启成功但正在写的会话、日志缓冲可能丢失。先用正常停止脚本给足 60 秒实在不行再强杀。配置文件改动前先备份改动后用diff核对。中间件的配置项动辄几百个改错一个字符可能引发连锁反应尤其是缩进敏感的 XML 和 YAML。JVM 参数不要在启动脚本里硬编码堆大小。把它抽到独立的环境变量文件里测试环境和生产环境用同一套脚本只换变量减少环境不一致类问题。扩容或者迁移之前先把 License 的绑定规则搞清楚。有的绑定 MAC有的绑定 IP有的绑定主机名。搞清楚之后再动比动完了发现起不来要省事得多。别在业务高峰期做变更。这条听着像废话但每年都有团队在流量最大的时候去调 JVM 参数。部署这件事本身的复杂度其实不高真正耗时间的是环境差异和那些文档没覆盖的细节。把这套流程跑通一次写成脚本固化下来后面再部署就是几分钟的事。我自己维护的那套发布脚本从最开始手动敲十几个命令到现在一条命令搞定省下来的时间全用来处理真正的业务问题了。
返回列表