ARTICLE DETAIL

资讯详情

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

Linux下东方通TongWeb7命令行静默安装与部署

Linux下东方通TongWeb7命令行静默安装与部署 1. 为什么我坚持用命令行把 TongWeb7 装到 Linux 上1.1 图形化安装看着省事实际是给自己挖坑第一次接触东方通 TongWeb7 的时候我和大多数人一样下意识地选了图形化安装。图形化安装确实友好一路下一步选路径、填端口、设管理员密码十几分钟就完事。但问题在于真正跑在机房里的那批机器多数是最小化安装的 Linux压根没装 X11 和桌面环境你连那个窗口都弹不出来。就算用 X11 转发勉强连上去安装过程中某个复选框点错了回退成本比重新装一遍还高而且整个过程没有任何可留存的记录过半年换个同事接手谁也不知道当初到底选了哪些参数。所以我的做法一直是第一次摸索阶段可以用图形化摸清安装器的参数项但正式交付的机器一律走命令行 / 静默安装。原因很直接——静默安装的应答文件本身就是一份部署文档参数写死在里面第二台、第三台机器照着跑就行出问题的时候安装日志会把每一步的选择原样记下来排查有据可依配合 Ansible 之类的批量工具十台机器和一台机器的操作成本几乎一样。这篇文章要聊的就是这套路子Linux 环境下东方通 TongWeb7 的部署全流程从环境准备、静默安装、实例与 JVM 参数规划到应用部署、systemd 服务化、生产加固再到我这些年踩过的坑。写这篇东西的起因是前阵子帮一个朋友的项目做中间件选型收尾。他们的应用原本跑在开源的应用服务器上后来甲方要求换成国产中间件运维团队里没人碰过 TongWeb7网上找到的资料要么是官方手册的摘抄要么是几年前的版本截图缺的恰恰是在真实 Linux 服务器上从零到能访问业务系统这一段。下面这些内容我会尽量按我当时实际敲过的顺序来写能贴命令的地方直接贴命令能写清楚为什么这么干的地方一定写清楚。看完之后一个会用 Linux 基础命令、懂一点 Java 的运维或开发应该能独立把一套 TongWeb7 跑起来并且知道哪里容易翻车。1.2 先搞清楚 TongWeb7 到底是个什么东西很多人把 TongWeb 简单理解成国产版的 Tomcat这个类比只对了一半容易误导后面的部署决策。TongWeb7 是一款企业级 Java 应用服务器从定位上讲更接近 WebSphere、WebLogic 那一类产品而不是轻量级的 Servlet 容器。它支持完整的 Java EE / Jakarta EE 规范栈Servlet、JSP、EJB、JMS、JTA、JNDI 这些都有实现同时提供了带图形界面的管理控制台可以管数据源、管连接池、管集群、管应用的启停和版本回滚。这个定位差异带来的直接影响是TongWeb7 的目录结构和配置模型比 Tomcat 复杂部署前必须做实例和域的规划。Tomcat 那种丢个 war 包到 webapps 里重启一下的玩法在小项目上也许还能凑合但只要涉及多应用隔离、独立数据源、独立 JVM 参数就必须走它自己的实例Domain机制。所以下面我会反复强调一件事先把目录、端口、内存、用户这四件事规划清楚再动手装顺序反了后面打补丁会很痛苦。1.3 部署前必须确认的四类信息动手之前我习惯先填一张表找项目负责人和相关方把信息确认齐避免装到一半发现缺东西。类别需要确认的内容缺失后的典型后果授权授权文件License是否已到位、有效期到什么时候、绑不绑 MAC 或 IP安装能成功启动时报授权错误实例起不来版本TongWeb7 的具体小版本号、对应的 JDK 版本要求JDK 版本不匹配启动直接抛版本异常应用待部署应用的 JDK 编译版本、是否依赖 JNDI 数据源、有没有用 EJB/JMS应用部署后启动失败或功能异常资源服务器 CPU、内存、磁盘、是否允许开多个端口、有无防火墙策略内存不够、端口被拦、磁盘写满导致日志报错这张表看着啰嗦但我见过太多项目卡在授权文件在甲方手里走流程走了一周这种事上。技术问题都好解决流程问题才是真正的时间黑洞。2. 环境准备地基没打平后面全是玄学问题2.1 JDK 选型别用系统自带的那个Linux 发行版自带的java命令多半是 OpenJDK版本还经常是老版本而且路径分散、被包管理器接管装中间件的时候特别容易出问题。我的建议很明确自己下载一套独立的 JDK解压到固定目录通过环境变量显式指定不要依赖系统包管理器。TongWeb7 在实际项目里最常见的搭配是 JDK 8较新的小版本也能跑在 JDK 11 上。到底支持到哪个版本必须查你手上这个安装包自带的发行说明不同小版本的支持矩阵是不一样的别人说能跑不代表你这个包能跑。判断依据很简单看安装目录里的release文件或者发行说明文档里面会写清楚 JDK 兼容范围。装 JDK 的过程没什么技术含量但有两个细节值得强调# 假设安装在 /usr/local 下 tar -zxvf jdk-8u381-linux-x64.tar.gz -C /usr/local/ ln -s /usr/local/jdk1.8.0_381 /usr/local/jdk # 配置环境变量写入 /etc/profile.d/java.sh 比直接改 /etc/profile 更好维护 cat /etc/profile.d/java.sh EOF export JAVA_HOME/usr/local/jdk export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar EOF source /etc/profile.d/java.sh java -version第一用软链接/usr/local/jdk指向具体版本目录。这样以后升级 JDK只需要改软链接环境变量和服务脚本都不用动。第二环境变量单独放在/etc/profile.d/下的一个文件里比往/etc/profile里塞一堆 export 干净得多卸载的时候删文件就行。注意source只对当前会话生效用ssh新开的会话才会读取/etc/profile.d/。如果后面用 systemd 托管服务systemd 根本不读 profile必须在 unit 文件里显式写EnvironmentJAVA_HOME...这一点后面会专门讲也是最容易漏的地方。2.2 系统层面必须调的几组参数中间件跑不起来八成的玄学问题都出在操作系统层面。我把这几组参数分成三类资源限制、内核网络参数、基础环境。资源限制主要解决文件句柄不够用和线程数不够的问题。Java 应用会开大量文件句柄每个 Socket 连接、每个打开的日志文件都算默认的 1024 在高并发下半天就耗光报错形式是Too many open files看起来像应用 bug其实和 JVM 没关系。# 临时生效用于验证 ulimit -n 65535 # 永久生效写进 limits 配置 cat /etc/security/limits.conf EOF * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535 EOF改完之后用ulimit -n验证注意必须重新登录才生效或者用su - 用户名切换一次。如果是 systemd 托管limits.conf 对 systemd 服务不生效得在 unit 文件里写LimitNOFILE65535这个坑我后面会再提一次。内核网络参数主要影响高并发连接下的表现cat /etc/sysctl.conf EOF net.core.somaxconn 65535 net.ipv4.tcp_max_syn_backlog 65535 net.ipv4.ip_local_port_range 1024 65000 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_fin_timeout 30 vm.swappiness 10 vm.max_map_count 262144 EOF sysctl -p简单解释几个关键项。somaxconn是全连接队列长度默认 128压测的时候如果发现连接被拒绝但 CPU 和内存都不高多半是这个值太小。ip_local_port_range决定客户端可用端口范围作为调用方去连数据库、连缓存的时候端口不够会出现连接超时但服务端没收到请求的诡异现象。swappiness调到 10 是让系统尽量别把 JVM 堆换到 swap 上——JVM 堆一旦被换出GC 停顿时间会飙到秒级甚至更长比直接 OOM 还难排查。基础环境这块有三件事要做时区、字符集、SELinux。# 时区统一日志时间戳和业务时间对齐排查问题的时候能省很多口舌 timedatectl set-timezone Asia/Shanghai date # 字符集 localectl set-locale LANGen_US.UTF-8字符集这里有个细节en_US.UTF-8和zh_CN.UTF-8都能支持中文区别只在于系统提示信息是英文还是中文。我一般用en_US.UTF-8因为报错信息搜起来方便。真正决定 Java 应用中文是否乱码的是 JVM 的file.encoding参数这个后面讲 JVM 参数的时候会展开。SELinux 这块我的态度是生产环境不要一上来就setenforce 0关掉。正确的做法是先确认它的状态然后针对 TongWeb 需要的端口按需放行。如果图省事直接关一方面是安全审计过不了另一方面是以后别的服务出问题你会失去一个重要的排查维度。getenforce # 如果是 Enforcing按需添加端口放行示例为 8080 semanage port -a -t http_port_t -p tcp 80802.3 目录规划和专用运行用户这块是我吃过亏的地方。早期的项目我直接拿 root 跑中间件结果有一次应用里有个文件上传功能写出来的文件属主是 root后续运维用普通用户清理的时候没权限又得回头找 root来回折腾。正确做法是创建一个专用的系统用户所有安装、运行、日志操作都用这个用户完成。groupadd -g 2000 tongweb useradd -u 2000 -g tongweb -m -s /bin/bash tongweb passwd tongweb目录规划我推荐这样的结构逻辑是程序、数据、日志、备份分开存放好处是以后做磁盘扩容、日志清理、备份策略的时候边界清晰目录用途建议/opt/tongweb程序安装目录单独挂盘更佳只放程序/data/tongweb/domains实例目录、应用包、上传文件数据盘容量要留足/data/tongweb/logs日志集中存放数据盘配 logrotate/data/backup/tongweb配置和应用的备份可以和日志同盘定期归档到别处mkdir -p /opt/tongweb /data/tongweb/domains /data/tongweb/logs /data/backup/tongweb chown -R tongweb:tongweb /opt/tongweb /data/tongweb /data/backup/tongweb chmod 750 /opt/tongweb /data/tongweb权限设成 750 而不是 777理由很朴素中间件目录里有配置文件配置文件里往往明文写着数据库密码777 等于把密码摊在桌上。3. 安装 TongWeb7静默安装才是正路3.1 拿到安装包之后先别急着解压安装包到手的第一件事是核对和校验不是解压。ls -lh TongWeb*.tar.gz md5sum TongWeb7.0.x.x.tar.gz # 和提供方给的校验值比对别嫌这一步多余。中间件安装包动辄几百 MB下载过程中断导致文件损坏的概率不低而且损坏的包有时候解压不报错装完启动才出问题那时候你根本不会怀疑到安装包头上。校验完之后看一眼包的结构。用tar -tzf列出内容不解压就能看清里面是什么tar -tzf TongWeb7.0.x.x.tar.gz | head -30常见的两种形式一种是纯解压即用的绿色包解压出来就是完整的程序目录另一种是带安装器的包里面有个install目录包含安装程序和应答文件模板。这两种的部署手法完全不一样先确定你是哪一种再往下走。我下面主要按带安装器的方式写因为这是企业项目里更常见的形式也是能体现静默安装价值的地方。3.2 静默安装的应答文件怎么写安装器通常是 InstallAnywhere 或 InstallShield 这类工具打包的这类工具基本都支持静默模式套路是提供一份应答文件response file把图形界面里所有需要人点选的项用变量名值的形式写死。安装介质里一般会自带一份应答文件模板或示例正确做法是先找到它复制一份再改而不是自己从零编。变量名不同厂商、不同版本都会变硬猜必错。# 找模板 find . -iname *response* -o -iname *silent* -o -iname *.properties | head -20找到之后复制出来重点改这几类变量安装路径、管理员密码、实例端口、是否创建桌面快捷方式Linux 上直接关掉、授权文件路径。cp installer/response.properties ./silent_install.properties vi silent_install.properties改完执行静默安装注意必须用 tongweb 用户执行而且要在目标目录有写权限的前提下执行su - tongweb cd /tmp/tongweb_install ./install -i silent -f ./silent_install.properties-i silent表示静默模式-f指定应答文件。执行过程中屏幕基本没输出别以为卡住了看进程和日志tail -f /tmp/tongweb_install/install.log安装结束后去应答文件里写的安装路径确认一下目录结构是否完整。如果安装失败日志里会明确说哪一步参数缺失或者权限不对按提示补就行。实操心得把改好的silent_install.properties连同安装包一起归档到/data/backup/tongweb下并在文件头用注释写清楚改了什么、为什么改。半年后要扩容的时候你会感谢当初的自己。3.3 授权文件与目录结构解读TongWeb7 是商业产品需要授权文件才能正常启动。授权文件的放置方式一般在安装时就指定了路径常见的是放在安装目录下的licenses或conf相关目录里。装完之后一定要验证授权状态方法通常是启动一次看日志或者在管理控制台里查看授权信息。这里有个很现实的提醒试用授权是有有效期的。我遇到过项目在测试环境跑得好好的上线前一天突然起不来一查是试用授权到期了。所以部署完成后第一件事就是确认授权到期时间并在项目排期里提前标记换证节点。安装完成后安装目录下通常会看到类似这样的结构不同小版本会有差异以实际为准目录/文件作用bin/启停脚本、命令行管理工具conf/全局配置文件、端口配置、日志配置lib/中间件自身的依赖包domains/实例目录每个实例独立配置、独立部署应用logs/运行日志licenses/授权文件相关uninstall/卸载程序我的习惯是先把conf下和端口相关的配置文件通读一遍把该改的端口一次改完再启动。理由很简单先启动再改端口等于启动过程中要处理一次端口冲突报错白白浪费一轮排查时间。4. 实例规划与 JVM 参数算出来的不是猜出来的4.1 端口规划表先定死TongWeb7 涉及的端口不少如果项目里一台机器要跑多个实例端口冲突几乎是必然的。我一般会在部署前做一张端口规划表写清楚每个实例占哪些端口然后统一申请防火墙策略。端口用途示例值说明HTTP 业务端口8080 / 8081应用对外访问入口HTTPS 端口8443有证书需求时使用管理控制台端口9060 / 9061建议只对内网管理网段开放JMX 监控端口9010接监控系统用需加认证AJP 端口8009不用的话建议关闭减少暴露面规划的时候有个原则管理控制台端口绝对不要暴露到公网。控制台权限很大能部署应用、能改数据源配置一旦被扫到并且密码强度不够等于服务器拱手让人。生产环境的通行做法是控制台只监听内网管理地址或者用 Nginx 加一层白名单和认证再做代理。4.2 JVM 堆内存到底该给多少这是我最常被问的问题也是最容易被拍脑袋决定的问题。我的算法分三步以一台 16GB 内存、跑单个实例的服务器为例。第一步扣掉操作系统和其他常驻进程。Linux 本身、监控 agent、日志 agent、可能的 Nginx保守留 3 到 4GB。剩下 12GB 给 JVM。第二步分配给堆之外的部分。JVM 内存不只是堆还有Metaspace放类元数据一般按 256MB 到 512MB 估线程栈默认每个线程 1MB按 500 个线程算就是 500MB直接内存Direct MemoryNIO 大量使用时不能忽略按 512MB 到 1GB 估JVM 自身代码、GC 结构等几百 MB。加起来堆外的部分大致要留 2 到 3GB。所以堆最多给到 9GB 左右。第三步堆内部还要分新生代和老年代。经验上面向 Web 的业务应用新生代占堆的 1/3 到 1/2 比较合适因为大量对象是朝生夕死的请求级对象。最终这套参数大概长这样-Xms8g -Xmx8g -Xmn3g -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m -XX:SurvivorRatio8 -XX:UseConcMarkSweepGC # JDK8 时代常用 -XX:CMSInitiatingOccupancyFraction70 -XX:UseCMSInitiatingOccupancyOnly -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/data/tongweb/logs/heapdump -XX:PrintGCDetails -XX:PrintGCDateStamps -Xloggc:/data/tongweb/logs/gc-%t.log -XX:UseGCLogFileRotation -XX:NumberOfGCLogFiles10 -XX:GCLogFileSize32M -Dfile.encodingUTF-8 -Duser.timezoneAsia/Shanghai -Djava.security.egdfile:/dev/./urandom几个参数单独解释一下。-Xms和-Xmx设成一样是为了避免堆动态伸缩带来的额外开销和抖动。GC 日志一定要开而且要开轮转不然一个文件能涨到几十 GB把磁盘吃满反而引发新故障。-Dfile.encodingUTF-8是中文乱码的正面解法比事后改代码靠谱。java.security.egd指向urandom是为了避免启动阶段阻塞在随机数生成上老内核上这个问题很明显表现为启动卡住几分钟不动。注意上面的 GC 参数是 JDK8 的写法。如果用的是 JDK11 及以上PrintGCDetails、CMS这些参数已经被移除或废弃写上去会直接报错起不来。换 JDK 的时候GC 参数必须跟着改这是升级 JDK 最常见的翻车点。4.3 这些参数写在哪里TongWeb7 的 JVM 参数一般有两种配置入口一是启动脚本同级目录下的环境变量配置文件二是实例自身的配置文件。具体文件名和变量名不同小版本差异较大需要看安装目录下的脚本内容来确定。我的做法是直接用文本编辑器打开bin下的启动脚本扫一眼搜索JAVA_OPTS、JVM_OPTS之类的关键词看它最终拼出来的启动命令长什么样grep -n JAVA_OPTS\|JVM\|Xmx bin/startserver.sh看清楚变量名之后再决定是改脚本、改配置文件还是通过外部环境变量传入。优先选配置文件或外部环境变量不要直接改启动脚本因为下次打补丁升级的时候脚本文件会被覆盖你改的东西就丢了。5. 应用部署控制台和命令行两条路都得会5.1 用管理控制台部署 WAR 包控制台是最直观的方式适合首次部署和排查。浏览器打开http://服务器IP:9060/console端口和路径以实际配置为准用安装时设置的管理员账号登录。部署流程大致是进入应用管理页面选择部署上传 WAR 包指定上下文根Context Root选择目标实例提交。中间有几个选项需要留意上下文根决定访问路径写app就是http://ip:8080/app写成/就是根路径。两个应用都想抢根路径会冲突规划好。类加载策略如果应用里带了和中间件冲突的第三方包比如不同版本的日志框架、JSON 库需要调整类加载顺序让应用优先加载自己的包。会话管理单机就保持默认将来要做集群的话这里要改成对应的会话共享方式。点击部署之后别急着关页面看部署日志。TongWeb 的部署日志会列出应用初始化过程中的异常很多时候部署成功了但应用上下文启动是失败的页面能打开但功能不可用。5.2 数据源配置JNDI 名字一定要对企业应用很少自己管理数据库连接通常是应用里通过 JNDI 名字去中间件拿数据源。这部分配置错一个字母应用就起不来报NameNotFoundException。配置步骤是在控制台的数据源模块新建数据源填 JDBC URL、驱动类、用户名密码、连接池参数。连接池参数里有两个值得特别关注参数建议值理由初始连接数5 到 10太大启动慢太小首次请求会等最大连接数按数据库承载能力定50 到 100数据库连接是稀缺资源不是越大越好空闲回收超时300 秒及时释放闲置连接避免数据库侧连接堆积连接有效性检测开启SQL 用轻量查询防止拿到已经被数据库断掉的死连接最大连接数千万不要拍脑袋往大了写。中间件这边开到 500数据库那边max_connections只有 200结果就是连接请求排队超时报错排查的时候还以为是网络问题。正确做法是数一数应用实例总数乘以单实例最大连接数留出余量再和 DBA 确认数据库侧的上限。还有一点JDBC 驱动包一定要放到中间件能加载到的位置而不是丢在应用包里的WEB-INF/lib就完事。数据源是中间件层面管理的驱动不在中间件的类路径里配置页面点测试连接就会失败。5.3 命令行工具批量部署和自动化的时候靠它控制台点一次两次还行十台机器上重复点就是折磨。TongWeb7 安装目录的bin下通常有命令行管理工具可以完成部署、启停、查询状态等操作。具体命令名和参数用--help看以实际安装的版本为准。命令行工具的典型用法是配合脚本做批量操作# 伪代码示意实际命令名和参数以安装版本为准 ./bin/twadmin deploy --host 127.0.0.1 --port 9060 \ --user admin --password ****** \ --file /data/packages/app.war --contextroot /app用命令行有两个必须注意的点。第一密码不要写在命令历史里用变量或者从权限受限的文件读取history里留明文密码是很常见的低级漏洞。第二批量脚本一定要加失败判断和日志记录否则中间某台机器失败了你不
返回列表