今年有段时间一直在折腾国产化办公环境,统信UOS和银河麒麟两台机器轮流装系统、配服务。WebScannerService这个服务,名字看上去像个扫描组件,实际上是一套以Web API形式对外提供扫描能力的常驻服务,常常被用于内容审核、文件检测或安全巡检这类场景。起初以为“装上Java环境、跑起来就好”,结果在UOS上踩完一轮坑,又在麒麟上重新踩了一遍。整个过程走完,我觉得很有必要把这套兼容性实测记录下来,给后续要在国产Linux系统上部署WebScannerService的同行提供一个参考。

这篇文章不打算只写“怎么装”,我会把两个系统的差异、依赖处理的思路、systemd托管服务的细节、问题排查的方法都讲清楚。适合正在做信创适配、国产系统运维,或者准备把自己的服务迁移到统信UOS/银河麒麟上的朋友阅读。已经踩过的坑,你就别再踩了。

1. 整体设计与思路拆解

1.1 为什么选WebScannerService做兼容性测试

很多人第一次接触国产系统,习惯性以为“不过是个Linux换皮”,装软件就用yum/apt,跑服务就用systemd。实际遇到的第一个问题不是系统本身,而是软件的运行环境是否完整、依赖组件是否齐全、授权认证是否兼容。

WebScannerService这个服务我比较熟悉,它本身是Java系服务,启动不复杂,但对外依赖不少:需要Java运行时、HTTP端口、日志目录、配置文件,可能还要连外部存储或数据库。这类服务的安装过程恰好能覆盖国产Linux适配中的常见难点:包管理差异、依赖缺失、目录权限、systemd集成、防火墙和selinux策略。测完这两个系统,基本就能摸清一套业务服务在国产环境中“能不能跑、跑起来稳不稳、出问题怎么定位”。

还有一个好处,WebScannerService本身是跨平台的,在x86_64架构下编译,统信UOS和银河麒麟都支持这个架构。如果你的环境是ARM架构(比如鲲鹏、飞腾),流程基本一样,只是安装包需要选aarch64版本,下文我会单独提。

1.2 两个系统的特性差异与安装策略

统信UOS桌面版和银河麒麟桌面版,底层都有Debian的影子,但具体实现已经各自分化。我实测下来的感受:

对比维度 统信UOS 银河麒麟
底层基础 Debian系(dpkg/apt) 偏CentOS体系时用rpm/yum,V10 ARM版也有dpkg系
内核版本 5.x内核为主 V10多为4.19/5.4,V11新内核
默认Shell bash bash
服务管理 systemd systemd
软件安装 apt/dpkg为主,支持deb rpm/yum/dnf为主,也支持源码编译
常见问题 依赖库哪里找 依赖库太老、源过期

所以安装WebScannerService时,我先确定了安装包格式。统信UOS走deb方式,银河麒麟走rpm或者通用tar包方式。如果你只是把WebScannerService做成一个免安装的tar.gz目录,那两边流程就可以统一成“解压+配环境+写systemd单元”,这是最省心的做法。

我最终采用的就是tar包形式,再把服务做成systemd unit,这样两边共用一套方案,差异只在于依赖库的补充和权限调整。这一点值得大家借鉴:跨发行版部署时,不要一开始就纠结打包格式,先用通用方式跑通,再考虑要不要改造成deb/rpm。

2. 环境准备与识别

2.1 确认架构、系统版本和基础依赖

在动手之前,先把机器信息摸清楚。三条命令能解决:

uname -a
cat /etc/os-release
getconf LONG_BIT

我在UOS上执行时,系统显示为UOS Desktop 20,x86_64架构。银河麒麟那台跑的是V10 SP1,同样x86_64。确认完架构,接下来确认Java环境:

java -version

如果提示没有Java,两个系统都需要单独安装。UOS上直接:

sudo apt update
sudo apt install openjdk-11-jre-headless

银河麒麟如果用yum源还能拉包,试一下:

sudo yum install java-11-openjdk-headless

我遇到过一种情况:麒麟机器的yum源是内网离线源,里面软件包不全,Java装不上。这种时候只能从其他机器拷贝JDK目录,或者干脆下载对应架构的JDK tar包解压到 /opt/jdk ,然后通过环境变量指向它。国产系统离线部署是常事,建议提前准备好JDK 8/11的x86_64和aarch64安装包,指不定哪台机器就用上了。

2.2 WebScannerService运行基础配置

WebScannerService解压后一般会有这几个目录: bin 、 conf 、 lib 、 logs 、 data 。它启动时读取 conf 下的配置文件,默认监听一个HTTP端口,比如8080或8443。

解压之前注意一点,目录名字不要带中文和空格,否则部分脚本解析路径时会出错。我习惯统一放到 /opt/webscanner 下面:

sudo mkdir -p /opt/webscanner
sudo tar -zxvf WebScannerService.tar.gz -C /opt/webscanner

接下来需要创建专用账号,避免用root跑业务服务。这一点在国产系统上同样重要,root启动的服务权限过大,一旦有漏洞,影响面会波及整个系统。创建账号并授权:

sudo useradd -r -s /sbin/nologin websvc
sudo chown -R websvc:websvc /opt/webscanner

有些同事习惯用 chmod 777 一步到位,我在实际运维中非常不建议对服务目录这么做。正确的做法是给目录755权限,给日志目录单独可写权限,给配置目录600权限。权限给得太宽,日志和配置文件容易被其他用户读取甚至篡改。

3. 统信UOS上的安装与配置

3.1 安装步骤与依赖处理

在统信UOS上,我先确认了系统是否自带libcap、libltdl之类的动态库。WebScannerService里某些二进制组件会依赖这些库,缺了启动时会直接报 error while loading shared libraries 。

比较稳妥的方式是用ldd检查启动器依赖:

ldd /opt/webscanner/bin/scanner-server

缺哪些库就补哪些。UOS有桌面源,很多库可以直接装:

sudo apt install libltdl7 libcap2-bin

如果某个依赖库在UOS源里找不到,试试安装 libffi-dev 、 libpcre3-dev 这类开发包,有时把开发包装上,运行时库也会一起带上。

另外,统信UOS默认发行版的glibc版本不算旧,大多数Release构建的Java服务和原生组件都能跑。我唯一一次遇到so库不兼容,是因为WebScannerService里一个内置组件是为CentOS 7编译的,链接的是老版本 libstdc++ 。这种情况下我建议优先换组件版本,不要试图强行替换系统的 libstdc++ ,否则会引发更大范围的不兼容。

3.2 配置WebScannerService参数并做冒烟测试

配置方面,主要关注三块:监听IP和端口、日志路径、数据目录。编辑 conf/application.yml (或者类似名称的配置),做以下修改:

server:
  address: 0.0.0.0
  port: 8080
logging:
  file: /opt/webscanner/logs/scanner.log
storage:
  path: /opt/webscanner/data

注意,地址设置为 0.0.0.0 意味着监听所有网卡。如果这台机器只在局域网内提供服务,建议把监听地址设成具体的内网IP,稍微降低暴露面。

改完配置后,先手动启动一次看看能不能跑起来:

cd /opt/webscanner
sudo -u websvc ./bin/scanner-server start

然后看日志和端口:

tail -f /opt/webscanner/logs/scanner.log
ss -tnl | grep 8080

日志里出现“Server started successfully”说明服务起来了。用 curl 做一次接口探测:

curl -i http://127.0.0.1:8080/health

看到HTTP 200就说明基本没问题。

3.3 把WebScannerService托管为systemd服务

手动启动只是第一步,真正的生产环境必须做成系统服务,开机自启、崩溃自动拉起。在 /etc/systemd/system/webscanner.service 新建单元文件:

[Unit]
Description=WebScannerService
After=network.target

[Service]
Type=forking
User=websvc
Group=websvc
ExecStart=/opt/webscanner/bin/scanner-server start
ExecStop=/opt/webscanner/bin/scanner-server stop
Restart=on-failure
RestartSec=5
PIDFile=/opt/webscanner/run/scanner.pid

[Install]
WantedBy=multi-user.target

之所以用 Type=forking ,是因为这类服务脚本启动时会在后台生成子进程,主进程退出,实际服务进程挂在后台。如果你用 Type=simple ,systemd会认为主进程一退出服务就结束了,这会导致服务状态错误。

写完后执行:

sudo systemctl daemon-reload
sudo systemctl enable --now webscanner.service
systemctl status webscanner.service

这里有一个坑:有些启动脚本不会自动创建 run 目录,导致 PIDFile 指定的pid文件写不进去。解决方法是提前建好目录并赋予websvc用户写权限:

sudo mkdir -p /opt/webscanner/run
sudo chown websvc:websvc /opt/webscanner/run

4. 银河麒麟上的安装与适配

4.1 银河麒麟的差异化处理

换到银河麒麟V10后,最直观的感受是软件管理方式回到了rpm体系。WebScannerService的tar包两边通用,所以解压部分直接重复上面的操作即可,但环境依赖和系统设置需要调整。

银河麒麟离线场景特别多,内网机器没法访问公网yum源。我建议先把常用的rpm包备份在一个U盘/共享目录里,包括 java-11-openjdk-headless 、 libnsl 、 zlib 等。装包的时候用:

sudo rpm -ivh java-11-openjdk-headless-11.0.x.x86_64.rpm

注意, rpm -ivh 遇到依赖缺失会直接报错,这时候不要急着加 --nodeps 强制跳过,否则Java装上了也可能起不来。先看看缺什么,缺哪个就补哪个。V10上最常缺的依赖是 libnsl.so.1 ,老程序会用到。可以从CentOS 8的仓库里找到 libnsl 包,装上就安静了。

4.2 权限、SELinux和防火墙的进一步处理

银河麒麟桌面版默认没有强制开启SELinux,但有些服务器级定制版默认会开。如果WebScannerService端口无法访问,优先排查SELinux:

getenforce

如果输出 Enforcing ,可以临时放行端口:

sudo semanage port -a -t http_port_t -p tcp 8080

没有semanage命令就先安装 policycoreutils-python-utils 。当然,如果你觉得维护SELinux策略麻烦,也可以临时设置 setenforce 0 测试,但生产环境不建议长期关闭,最好维护对应策略。

银河麒麟的防火墙默认叫 firewalld ,跟CentOS一样:

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

这一步容易漏。我在UOS上装完服务能通,是因为UOS默认防火墙规则比较宽松;到了麒麟上,端口不通先检查防火墙,再检查监听地址,顺序不要反。先看 ss -tnl 确认服务在监听,再动手改防火墙,别一上来就关防火墙。

4.3 源码方式替代安装的适用场景

银河麒麟V10的软件源比较“有个性”,WebScannerService如果某个原生组件需要编译安装,就会出现 gcc 版本过老的兼容问题。我实测中遇到过需要编译一个扫引擎插件的情况,麒麟V10自带的gcc 7.x编译出来的so,运行时会有告警但不至于崩溃,所以多数场景直接用预编译so更合适。

但如果确实需要源码方式安装,我总结一下流程:

sudo yum install gcc gcc-c++ make cmake
tar -zxvf scanner-plugin-src.tar.gz
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/opt/webscanner/plugins
make && sudo make install

编译出错的,先确保系统locale是UTF-8,部分老代码在GBK环境下编译会报编码错误:

export LANG=en_US.UTF-8

然后再重新编译。这个细节虽然小,但在麒麟系统上遇到概率不低。

5. 常见问题排查与实战避坑

5.1 systemd启动失败与日志定位

两个系统上我都遇到过systemd启动WebScannerService失败,但日志信息很少的情况。排查时先看unit状态:

systemctl status webscanner.service -l

如果看不到有效信息,去翻 journalctl :

journalctl -u webscanner.service -n 100 --no-pager

实际遇到最多的失败原因是上述的pid目录权限不足、Java路径不对、配置文件中模板变量未被替换。

配置文件里有 ${JAVA_HOME} 这类占位符,如果没有被脚本正确解析,启动脚本会把路径拼错。我的排查顺序是:先手动以websvc用户执行启动命令(用 sudo -u websvc ),看能不能跑起来;能跑起来说明脚本没问题,问题在systemd环境;不能跑起来,跟着日志往前走。

如果手动能跑、systemd起不来,十有八九是Environment或EnvironmentFile没配好。Java路径不写在脚本里,写在service文件里更直观:

Environment=JAVA_HOME=/opt/jdk11
Environment=PATH=/opt/jdk11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

5.2 依赖库缺失、权限和端口冲突速查表

我把两个系统安装过程中遇到的高频问题汇总成一张速查表,方便大家直接对照:

问题现象 可能原因 解决办法
启动报错 error while loading shared libraries 缺libnsl/libltdl等 安装对应库或用ldd逐一定位
端口8080已占用 其他服务占用了端口 ss -tnlp 找到占用进程,改WebScannerService端口
日志报Permission denied 服务目录或日志目录属主不对 chown -R websvc:websvc /opt/webscanner
systemd启动后立刻退出 Type类型不对或pid文件路径错误 改用 Type=forking ,确认PIDFile目录存在
curl内网IP不通 防火墙未放行或监听地址为127.0.0.1 修改监听地址为0.0.0.0,放行防火墙端口
页面能开但接口超时 后端组件需要libpcap之类权限 检查so库权限,必要时添加capabilities
Java版本过低 系统自带jre版本太老 安装JDK 11,并设置JAVA_HOME

第三项比较容易被忽视,WebScannerService日志里权限报错经常被误判为配置错误,我一开始也以为是配置文件格式不对,折腾了半天才发现是解压时用了root,日志目录虽然能看但websvc用户根本写不进去。所以解压完第一步就做属主修改,能少走很多弯路。

5.3 跨平台部署前必须养成的三个习惯

第一,备份配置再修改。修改 application.yml 前先复制一份 application.yml.bak ,改坏了可以瞬间还原。这个习惯在UOS和麒麟上都救过我。

第二,先小范围验证再批量推广。我在UOS上跑通之后,先把服务开放给测试环境的三个业务方试用,观察了两天日志,确认没有异常才部署到麒麟生产测试节点。不要一上来就在所有机器上铺开。

第三,把操作记录写成内部文档。每个系统和版本的差异点都记下来,日后同类型的JDK服务也好、其他扫描组件也好,都能复用这套笔记。尤其要记“为什么这么改”,比如“为什么这台机器不能加--nodeps”,因为跳过依赖检查会导致运行时找不到so库,这类信息比命令本身更有价值。

写在最后

统信UOS和银河麒麟虽然都是国产Linux的扛把子,但实际适配时各有脾气。我觉得最核心的差别不在包管理,而在系统里默认软件的完整度。UOS的桌面体验更贴近Windows用户习惯,但源里的开发组件偏少;麒麟V10对服务器场景更友好,然而离线源一旦缺包,补依赖特别考验耐心。这次WebScannerService的安装让我把两套系统的脾气都摸了一遍,也验证了一个道理:跨平台部署国产系统,服务本身能不能跑是一回事,系统里有没有配套的依赖、权限、服务管理策略是另一回事。后来我再装类似的Java服务,基本都能预判问题出在哪,速度比第一次快了很多。

如果你手上也正在做类似的国产化适配,我的建议是不要被系统的图形界面吓到,也不要因为命令行风格变化乱了阵脚。先用通用tar包跑通核心流程,再逐步打磨成deb/rpm包,最后针对每个系统的防火墙、SELinux、目录权限做差异化调整。这个过程走完,你会发现国产系统并没有那么难相处。

更多推荐