
最近在配合客户做一个老项目的国产化中间件替换任务很明确把原先跑在WebLogic上的Java应用迁到东方通TongWeb上并且完成一套可交给运维的环境部署。说实话这类需求在国产化中间件选型里非常典型参考资料却常常只写“支持JavaEE、部署方便”这种销售话术真正关于TongWeb环境安装部署的细节文档少得可怜。我这次从拿到安装包到控制台跑出第一个应用前后踩了不少坑这篇文章就把完整过程写下来包括安装、建服务、部署war包、调内存、查日志适合刚接触东方通TongWeb的运维和开发照着操作。1. 先弄清TongWeb在系统里干的活再谈安装1.1 TongWeb到底负责哪一层TongWeb是东方通旗下的Java应用服务器中间件和Tomcat、Jetty这些Servlet容器不一样它更像是WebLogic、WebSphere在国产化替代里的“平替”角色。一个典型的Java Web系统请求链路是浏览器先打到NginxNginx再把动态请求转发给TongWebTongWeb跑你的Servlet、JSP、EJB最后通过数据源连数据库。也就是说TongWeb负责的是整个业务应用运行环境这一层它不直接面对用户但用户能不能用上系统完全取决于它运行得稳不稳。很多刚接触的人会拿它和Tomcat比然后发现部署war包的方式有点像于是直接照着Tomcat习惯来用。这个思路能用但不完全对。TongWeb自带管理系统支持数据源配置、连接池管理、集群、会话同步还带一套独立的管理控制台。你做国产化中间件替代不是简单把Tomcat目录覆盖一下而是要把它当作一个完整Java EE运行平台来对待。1.2 给从WebLogic迁过来的同事一张对应表我在迁移过程中发现凡是能熟练操作WebLogic的人上手TongWeb都会快很多因为两者的功能模块在逻辑上几乎是互相对应的。这里给一张我在项目里整理的功能对照表方便迁移时找对应入口功能点WebLogicTongWeb备注管理控制台ConsoleTongWeb控制台都是浏览器访问端口不同部署单元Applications应用管理/部署支持war、ear包JDBC数据源Data Sources数据源管理连接池参数位置类似JVM参数配置setDomainEnv.sh启动脚本JAVA_OPTS改完必须重启应用目录domain/applicationsdeploy目录对应war解压位置日志domain/servers/logslogs目录需要看实际目录名集群会话复制Cluster集群/会话共享配置项名称有差异这张表并不会百分之百匹配你手头的版本不同发行版的菜单名称和目录布局会有差异但对应关系是一致的。如果你过去管理过WebLogic遇到问题先想“这个功能在WebLogic里叫什么名字”再按这个名去TongWeb控制台里找基本都能找到。1.3 本次部署的环境基线为了避免后面操作内容太空泛我先交代一下这次部署的基线环境。操作系统是x86_64架构的Linux内核版本是3.10以上的老牌发行版JDK用的是1.8.0_291TongWeb版本是商业发行版中的常见版本。为什么用JDK 8因为被迁移的老应用是基于JDK 8开发的TongWeb当前主流版本对JDK 8支持最成熟很多依赖第三方组件的应用直接上JDK 11、17大概率会踩类加载问题。另外我强烈建议生产环境用独立系统用户运行中间件而不是直接用root。后面讲systemd托管TongWeb的时候会细说。安装目录我规划在/opt/tongweb应用部署目录独立在/data/tongweb-deploy这么做是为了将来磁盘满了或者要单独备份时不用把整个安装包一起折腾。2. 安装前先干完这5件事能省一下午2.1 确认JDK版本和JAVA_HOMETongWeb本身是基于Java开发的没有JDK它就是一堆脚本和class文件。绝大多数商用发行版要求JDK 1.8以上部分新版本已经支持更高版本但在没确认应用兼容性之前不要贸然用最新JDK。安装前第一件事就是执行java -version确认系统默认的Java版本。如果机器上有多个JDK我建议在启动脚本里显式指定JAVA_HOME而不是依赖PATH否则很容易出现“我明明装了JDK启动却说找不到Java”的情况。还有一个细节有些操作系统自带的OpenJDK只有JRE没有完整开发工具链。中间件运行一般不强制要javac但某些TongWeb管理功能或JSP编译会用到JDK里的工具类。保险起见装一个完整JDK不要只依赖系统精简版。2.2 看清操作系统和CPU架构国产化环境里经常遇到ARM架构服务器或者麒麟、统信UOS这类操作系统。TongWeb安装包有x86_64和aarch64版本之分如果拿错包启动时经常报“bad ELF interpreter”或者直接提示无法执行二进制文件。安装前用两行命令确认基线uname -m cat /etc/os-releaseuname -m输出x86_64就选x86_64安装包输出aarch64就选ARM版本。操作系统发行版影响不大但会影响你装systemd服务、防火墙规则等外围操作。我这次是在x86_64的老Linux上部署所以下文命令都是基于这个环境写的。2.3 授权文件与安装介质TongWeb商业版是需要授权文件的一般随安装介质一起提供常见文件名类似license.dat也可以在管理控制台的“授权管理”里导入。不同厂商项目拿到的授权形式不太一样有的给单独文件有的给一个授权码。我的经验是拿到介质后先把授权文件放到一个固定位置并备份然后在安装目录或控制台里完成激活再启动服务。不要等到控制台都打不开了才开始找授权那会浪费很多时间。有一点必须提醒授权文件绑定机器信息的情况是存在的比如有些授权是绑定IP或MAC地址的。如果之后虚拟机迁移、网卡名变了授权可能会失效。生产环境做快照迁移前先确认授权是否支持迁移否则装完新环境发现中间件起不来问题就大了。2.4 目录规划与运行账号安装目录最好不要直接放在根分区下。我之前见过有人把TongWeb装在/usr下结果磁盘满把系统分区撑爆了。建议单独规划一个数据盘目录比如/opt/tongweb安装程序/data/tongweb-deploy放应用日志也独立一个目录。这样后续备份、扩容、清理日志都清晰。运行账号方面创建一个名为tongweb的系统账号useradd -r -s /sbin/nologin tongweb mkdir -p /opt/tongweb /data/tongweb-deploy chown -R tongweb:tongweb /opt/tongweb /data/tongweb-deploy使用/sbin/nologin是防止有人直接切到这个账号下执行命令对中间件来说降低了运维误操作风险。后面用systemd托管时直接指定Usertongweb比传统startserver.sh裸奔更可控。2.5 端口规划与防火墙放通TongWeb默认管理控制台端口是9060业务HTTP端口常见8080实际以你安装包的配置为准。部署前先查一下目标端口有没有被占用netstat -lnp | grep -E 8080|9060如果端口被占用要么清掉占用进程要么改TongWeb配置二选一。改配置的话要同步改Nginx反向代理很容易漏。防火墙需要放通控制台端口和业务端口firewall-cmd --add-port9060/tcp --permanent firewall-cmd --add-port8080/tcp --permanent systemctl reload firewalld如果是内网环境且安全策略允许也可以临时关闭防火墙做验证但生产环境不要这么干。放通后先在本机用curl验证控制台端口是否通再去浏览器访问否则你很难分清楚是防火墙的问题还是中间件没起来。3. 从解压到看到控制台登录页全流程实操3.1 解压安装包并看目录结构TongWeb安装包通常是tar.gz或zip格式。我这次拿到的是tar.gz包解压到/opt/tongwebtar -zxvf TongWeb.tar.gz -C /opt/tongweb/解压完成后不要急着启动先花两分钟看目录结构。常见目录大致如下/opt/tongweb/ ├── bin/ # 启动、停止脚本 ├── conf/ # 全局配置文件 ├── deploy/ # 应用部署目录 ├── lib/ # 中间件运行依赖库 ├── logs/ # 日志目录 └── domains/ # 实例级配置目录部分版本存在不同版本目录名会有一点差异有的版本把日志放在domains/xxx/logs下有的版本没有deploy目录而是统一用控制台管理。我的建议是进目录先找两个文件一个是启动脚本一个是安装说明或README。TongWeb很多发行版会自带简版部署手册里面写了默认端口、初始账号这一系列关键信息网上找半天不如先看包内文档。3.2 设置环境变量并执行启动脚本启动前先把JAVA_HOME在启动脚本里定义好或者临时在会话里导出export JAVA_HOME/usr/local/jdk1.8.0_291 export PATH$JAVA_HOME/bin:$PATH然后切到安装目录的bin下找到启动脚本。不同版本这个脚本的名字不一样常见是startserver.sh或start.sh。启动时使用tongweb用户执行su - tongweb -s /bin/bash -c export JAVA_HOME/usr/local/jdk1.8.0_291; /opt/tongweb/bin/startserver.sh如果启动成功终端会输出一段提示同时后台开始初始化。这里有个特别容易犯的错误直接双击执行后看不到任何报错就以为启动成功其实进程在几十秒后因为端口冲突或授权失效又退出了。所以下一步必须看日志和端口。3.3 首次启动日志该看哪些关键信息启动后先找日志文件。TongWeb日志路径不统一有的在安装根目录的logs下有的在domains下。最快的定位方法是看启动脚本里的LOG_FILE变量或者通过find命令找最新的日志文件find /opt/tongweb -name *.log -mmin -5日志里需要重点确认几件事控制台端口是否监听、业务端口是否监听、有没有“started successfully”类似的关键字、有没有报错堆栈。日志文件末尾显示Server open for business或者“启动完成”才说明中间件真的起来了。不要只看终端里输出几行就放心中间件属于典型的重型服务终端退出了进程可能还在跑反过来终端没退出但进程已经崩了也常发生。端口监听状态用这条命令确认netstat -lnp | grep java看到9060和8080都在监听这才算过了第一关。3.4 控制台登录与初始账号问题浏览器访问http://服务器IP:9060/console正常情况下会看到TongWeb控制台登录界面。这里是最容易翻车的地方不同版本的初始用户名密码差异很大有人说是admin有人说是thanos还有人说是eosadmin。我自己的经验是千万别盲猜直接查安装包内的说明文档或介质上贴的账号信息。如果安装包内提供了初始化脚本首次启动时会让你设置管理员密码那就在初始化时把密码设成符合公司密码策略的强密码。登录控制台后第一件事不是去部署应用而是找到“系统管理”或“服务器配置”里的密码策略、会话超时配置把默认安全选项改掉。控制台默认账号如果没改相当于把你中间件管理入口暴露在网络上这是安全问题。实在忘记密码的话最稳妥的办法是查介质包内的管理员手册看恢复密码部分的说明。不要自己乱删配置文件我在现场见过有人删了用户配置文件结果控制台直接登录不了最后只能重新初始化环境。3.5 用systemd把TongWeb托管成服务传统部署方式是直接跑启动脚本但机器重启后中间件不会自动拉起还得专门写开机启动项。我建议直接用systemd管理配置示例[Unit] DescriptionTongWeb Application Server Afternetwork.target [Service] Typeforking Usertongweb Grouptongweb EnvironmentJAVA_HOME/usr/local/jdk1.8.0_291 ExecStart/opt/tongweb/bin/startserver.sh ExecStop/opt/tongweb/bin/stopserver.sh Restarton-failure [Install] WantedBymulti-user.target把这个文件保存到/usr/lib/systemd/system/tongweb.service然后执行systemctl daemon-reload systemctl enable tongweb --now注意Typeforking能否用对取决于启动脚本到底是后台启动还是前台启动。如果你的启动脚本会一直占住终端不退出应该把Type改成simple并且脚本里不要自己调nohup。判断方法很简单直接手动执行脚本如果执行完终端还能返回到命令提示符说明是forking型如果终端被卡住就改成simple型并去掉脚本里的后台化处理。4. 部署第一个应用控制台部署和目录部署两条路4.1 通过管理控制台上传war包登录TongWeb控制台后找“应用管理”或“部署”菜单。整个菜单在不同版本里显示中文或英文不同中文化版本一般在“应用管理”里英文版本在“Deployments”里。上传war包的流程大致是选择war包文件并上传设置应用名称和上下文路径确认部署目标实例点击部署再点击启动。上下文路径决定应用的访问URL。比如应用包名是oa.war上下文路径默认可能是/oa那么启动后访问地址是http://IP:8080/oa/。如果项目希望直接用根路径访问比如http://IP:8080/就进系统可以把上下文路径设置为/或者留空具体看版本支持情况。上传完成后控制台会把war包复制到中间件的部署目录并完成解压。这里有我非常想强调的一点控制台部署时war包在部署过程中处于半更新状态如果同时有其他管理员在操作同一个应用会互相覆盖。生产环境发布窗口内最好协调所有人都不要登录控制台乱点。4.2 直接丢到deploy目录的部署方式有些维护场景不适合用控制台比如自动化发布脚本要批量替换应用这时可以直接将war包拷贝到部署目录。TongWeb的deploy目录相当于一个应用放置区把app.war复制进去后有版本支持自动解压部署有版本需要重启中间件或手动在控制台刷新才能识别。直接部署的好处是快适合发布流程已经固化的项目坏处是容易留下旧目录。比如你重新上传了app.war但旧的app解压目录可能还在同名覆盖时旧class文件没清理干净会出现修改了代码但行为不变这种诡异问题。我处理的顺序是先停应用删除旧的应用解压目录再拷贝新war包最后启动应用。别图省事直接覆盖。4.3 项目目录到底指什么很多入行不久的同学问“项目目录放哪”其实这里的项目目录有两层意思一是war包解压后的物理目录二是应用的上下文路径。物理目录通常在TongWeb的deploy目录下比如deploy/oa/里面是WEB-INF/classes、static等。上下文路径则决定了外部访问URL。如果应用里需要读取配置文件建议让应用把配置外置不要打包进war里。TongWeb部署后war包会解压到项目目录你直接修改解压出来的配置文件是能生效的但下次重新部署war包时这些修改会被覆盖。正确做法是使用TongWeb控制台里的配置项或系统属性引用外部目录让应用从/data/appconfig/这类路径读配置发布时只更新war包不动配置。4.4 前端静态资源项目怎么部署现在的项目经常是前后端分离前端打出来是纯静态文件没有war包。这种情况下不需要特意打成war再部署。两种做法一是把打包出来的dist目录直接放到一个静态目录下由TongWeb的HTTP端口直接访问二是在前面再架一个Nginx用Nginx托管静态资源动态API请求再代理到TongWeb。我倾向第二种。因为Nginx处理静态文件性能比Java中间件强很多而且还能一并解决证书、跨域、负载均衡。部署的时候注意Nginx的proxy_pass要指向TongWeb实际监听端口如果不改中间件端口那默认就是8080。如果Nginx和后端TongWeb之间有超时需求比如报表导出很耗时需要单独调整Nginx代理超时时间默认的60秒不够用。5. TongWeb内存溢出排查实录从卡死到定位5.1 一次典型的内存溢出现场热搜里“tongweb内存溢出”这么高频说明这确实是使用TongWeb时绕不开的坑。我遇到的一次现场是一个TongWeb实例上部署了三个应用运行两周后其中一个应用突然响应变慢最后直接无法访问但另外两个应用还正常。查看日志发现反复出现java.lang.OutOfMemoryError: Java heap space紧接着还有GC overhead limit exceeded。很多人第一次看到OOM会直接怀疑中间件有问题但内存溢出绝大多数是应用本身或整体配置导致的。TongWeb只是Java进程它不会自己把内存吃掉真正吃内存的是跑在它里面的业务代码。可能是某个应用缓存设计不当、数据源连接池开得太大、批量任务没有释放引用。遇到OOM第一步是看日志确认是堆内存还是持久代/Metaspace问题第二步再看物理内存剩余情况。5.2 修改JVM启动参数的正确姿势确认是堆内存不足后最直接的调整是修改TongWeb启动脚本里的JVM参数。找到启动脚本里的JAVA_OPTS示例JAVA_OPTS-Xms2048m -Xmx2048m -XX:MaxMetaspaceSize512m -XX:UseG1GC这里有两个细节。第一生产环境建议-Xms和-Xmx设成一样避免JVM运行时动态扩容触发性能抖动第二如果物理内存只给机器分配了4G非要设置-Xmx4096m那JVM启动就可能会因为无法申请到内存直接退出。调参前先看物理内存free -h结合机器上其他进程的占用情况把堆大小控制在物理内存的一定比例内。比如机器总内存8G其他进程占2G那TongWeb堆设置3G到4G比较合理别贪。5.3 确保参数真的生效改完启动脚本后不要重启完就完事了一定要确认参数被实际使用。检查方法jps -lv这个命令会列出Java进程以及启动参数如果你的-Xmx2048m出现在输出里说明脚本里的配置生效了。如果没生效大概率是启动脚本里还有其他地方定义了JVM参数或者你修改的JAVA_OPTS变量根本就没被引用。还有一种情况是脚本里使用-D方式传递了配置文件路径但JVM内存参数在另一处定义需要仔细看脚本里的命令拼接顺序。另外TongWeb控制台通常也会显示当前JVM内存使用情况。如果它有图形化监控可以直接看到堆内存曲线这比命令行方式直观得多适合给不熟悉jps的运维同事用。5.4 调完内存还溢出的下一步加大堆内存只能延缓问题不代表根治。如果-Xmx4g跑几天又OOM了就该做线程和堆转储分析了。先用jstack看所有线程状态重点找有没有大量阻塞的线程再用jmap导出堆转储文件用MAT分析大对象。这一步需要一点JVM排查经验不是运维一两句话能说清的但作为中间件管理员至少要做到能导出这些现场资料然后交给开发人员去定位。还有一种情况是应用不再OOM但TongWeb管理控制台响应特别慢这通常是多个应用共用一个实例导致的。一个应用的内存泄漏会拖垮整个实例包括控制台。这种场景下最干净的方案是把应用拆到多个TongWeb实例里隔离故障。代价是每个实例都要占用一定的内存和端口资源但稳定性提升是非常值得的。6. 部署落地之后容易踩的坑端口、日志、多实例6.1 端口冲突启动失败最常见的直接原因TongWeb启动失败一半以上是端口被占用。常见情况有两种一是8080业务端口被另一个Web服务占用比如你自己装的Tomcat或者Nginx二是上一次启动没有正常停止残留Java进程还占着9060端口。排查命令netstat -lnp | grep 8080找到占用进程的PID后确认是什么进程再处理。如果是遗留的TongWeb进程直接杀掉kill -9 PID但如果是其他重要服务就不要随便杀。这时候改TongWeb端口更安全。TongWeb业务端口一般在conf目录下的配置里改完端口后记得同步修改Nginx、防火墙规则、快捷访问链接。我见过一个人改完端口忘了改运维脚本第二天批量发布脚本对着旧端口探测一直报服务不可用。6.2 日志到底在哪怎么找“日志找不到”也是提问最多的问题之一。很多网上资料会说TongWeb日志在logs目录但具体到某个版本可能日志在/opt/tongweb/domains/xxx/logs下面。找日志的正确方式不是背路径而是看启动脚本里的LOG_FILE和配置里的日志路径。手动启动时终端输出通常也会提示日志文件路径。日志文件权限问题也要注意。如果你用root启动过TongWeb再用tongweb用户重启日志文件的所有者可能变成root导致新用户进程写不进去启动时直接报权限错误。解决办法是把整个安装目录的所有者重新chown给tongwebchown -R tongweb:tongweb /opt/tongweb日志滚动也是需要关注的。TongWeb自带的日志策略一般会按大小滚动但业务量大的系统一天能产生好几GB访问日志。建议在部署完成后配一个crontab定期清理历史日志或者交给elk系统收集后本地保留几天即可。日志分区独立也是这个原因避免日志写满系统分区。6.3 多实例部署的目录规划在国产化项目里同一个中间件版本很多公司会选择一台物理机部署多套环境比如一套给核心业务一套给非核心业务或者一套给开发、一套给测试。多实例最忌讳的是所有人都把应用往同一个deploy目录里塞。这样不仅互相争抢内存连重启也无法单独操作一个应用。我推荐的方式是复制安装目录为多个实例目录或者按TongWeb官方多实例方式创建domain。每个实例使用独立的端口组合、独立的日志目录、独立的应用部署目录。比如/data/tongweb/node1业务端口8081、控制台9061/data/tongweb/node2业务端口8082、控制台9062两个实例之间互不影响一个实例内存溢出重启另一个实例继续对外提供服务。缺点是多实例会让机器内存占用变高部署前要根据物理内存算好每个实例堆大小别一个实例分2G结果机器总共就4G内存。6.4 旧应用迁移中的ClassLoader和jar包冲突从WebLogic或WebSphere迁到TongWeb最隐蔽的坑不是中间件装不上而是应用能启动但运行时报ClassNotFoundException、NoSuchMethodError这类类加载问题。核心原因是WebLogic默认的类加载优先级和TongWeb不同应用里打包了一些旧版本的第三方jar之前跑在WebLogic时被中间件屏蔽了换到TongWeb环境后这些jar和中间件自带的类冲突了。处理思路也和WebLogic迁移时一样清理应用WEB-INF/lib目录里重复的旧jar特别是Servlet API、JSP API这类提供者jar不要打包进应用应该由中间件来提供。遇到NoSuchMethodError通常是jar版本冲突用jar tf看包里的类确认哪个jar提供该类再统一版本。迁移一个新应用部署时间可能只要十分钟但类加载问题排查可能花一天这个心理准备要有。7. 我整理的一份TongWeb运维检查清单7.1 启动后必看的三类信息每次中间件重启完不要只看到“启动完成”就离开。我个人习惯按固定顺序确认三件事进程状态、端口监听、控制台登录。命令组合如下ps -ef | grep tongweb netstat -lnp | grep java curl -I http://127.0.0.1:9060/consoleps确认进程在跑netstat确认9060和8080端口都在监听curl确认管理控制台确实有HTTP响应。如果进程在但端口没监听基本可以判断中间件没有完整加载需要看日志如果端口监听但curl无响应可能是控制台应用异常。这套检查做完整个环境状态才叫真的确认完成。7.2 升级补丁时的备份策略TongWeb版本升级或打补丁前一定要备份的可不止安装目录。至少要把这几样单独复制一份conf目录、deploy目录下的所有应用、授权文件。lib目录一般不需要全备因为补丁包会替换它备份了反而可能恢复出错时版本混淆。我的备份习惯是打成时间戳压缩包tar -czf tongweb-backup-$(date %Y%m%d).tar.gz /opt/tongweb/conf /data/tongweb-deploy /opt/tongweb/license升级过程中如果遇到问题第一时间不是去翻补丁包而是把备份恢复到原路径先让业务恢复再分析升级失败原因。这个顺序不能反业务可用永远优先于排查原因。7.3 给接触TongWeb不久的人一句话建议接触这套中间件的人多多少少都带着“国产软件不好用”的预期而来。我实际用下来的感受是TongWeb的核心功能和部署逻辑和主流Java应用服务器没有本质区别出问题的地方往往是对它不熟悉拿习惯了的东西直接套上去。安装部署是最简单的一环难的是应用适配和后续调优这两件事都需要你在生产环境里一遍遍试出来。只要保留好变更记录稳扎稳打TongWeb跑生产完全没问题。最后再分享一个小习惯我会在每次部署完成后把安装路径、JDK路径、端口列表、控制台账号、JVM参数和日志路径写进项目交接文档。看起来多花十分钟但下次不管是环境迁移还是同事接手都能省下大半天时间。中间件运维这件事细节记下来比记在脑子里可靠得多。