简介:面向国产化环境运维与开发人员的 Nginx 1.23.2 麒麟版 AArch64 资源包,基于麒麟操作系统与 ARM64 指令集编译,用于在飞腾等国产芯片服务器上快速部署高性能 Web 服务与反向代理。包体共 21 个文件,涵盖 conf 配置、html 默认站点、log 日志、nginx 可执行文件及 fastcgi_params、mime.types 等标准模块模板,其中 conf 用于定义虚拟主机和负载均衡规则,html 提供默认测试页面,log 记录访问与错误信息;整体压缩后约 2.12MB,目录结构贴近官方默认布局。该版本针对 HTTP/2、TLS 及 Stream 模块做了更新,支持最新加密套件,可在 64 位 ARM 平台稳定承载大规模并发连接。资源已有 1071 人学习,适合需要掌握麒麟系统下 Nginx 安装配置、反向代理、PHP-FPM 集成与安全日志管理的中级运维人员。通过解压后可直接查看 Nginx 的核心配置、默认页面与日志样例,为内网部署、性能调优或二次开发提供现成参考。
1. nginx 1.23.2 在麒麟 aarch64 上为什么不能直接套用 x86 的部署思路
一台刚拆箱的麒麟 aarch64 服务器,系统是 Kylin Linux V10,架构是 ARM64,你拿着在 x86 上编译好的 nginx 1.23.2 二进制直接丢上去,大概率会收到一句 "cannot execute binary file: Exec format error"。这不是权限问题,也不是磁盘问题,是架构不匹配。国产化替换这两年,最常被问到的问题就是:nginx 1.23.2 在麒麟 aarch64 上到底怎么装?为什么源里只有老版本,能不能用现成 rpm?严格来说,麒麟的软件源里确实有 nginx,但版本往往停留在 1.14 或 1.16 左右,面对安全审计和等保要求根本扛不住。这篇笔记就是围绕 nginx 1.23.2 在麒麟 aarch64 上的源码编译、configure 参数选型、systemd 托管和排错展开,适合正在做信创迁移的运维和实施工程师,也是一条把 ARM 服务器上的 Web 服务底座真正握在自己手里的路径。
2. 准备构建环境:麒麟版本、aarch64 工具链与依赖安装
2.1 先摸清系统底细再动手,避免装错依赖
很多人拿到机器第一件事就是敲 yum install,结果报一堆依赖错误,原因就是没分清楚麒麟 V10 是基于 CentOS 8 还是 CentOS 7 的。麒麟 V10 的 aarch64 版本大量沿用 CentOS 8 的用户态,能兼容大部分 EL8 的 rpm 包,但不同小版本之间也有些差异。我一般会先跑三组命令确认基础信息,再决定用 dnf 还是 yum 装依赖:
uname -m && uname -r cat /etc/os-release gcc --version | head -1三个命令的用途分别是:uname -m确认是否 aarch64,uname -r看内核版本,内核版本能反映系统有没有启用 64K 页表;/etc/os-release里的 VERSION 字段能告诉你这是 V10 的哪个 SP 版本,很多故障报错和这个 SP 版本直接相关;gcc --version确认编译器是否存在,如果提示 command not found,说明 build-essential 这类基础工具链都没装。麒麟 V10 上 dnf 和 yum 都能用,但 dnf 在处理依赖时会更快也更准确,推荐优先用 dnf。
这步有个容易忽略的细节:如果/etc/os-release里写的是 CentOS 8,那依赖包就按 EL8 来,如果写的是 CentOS 7.x 兼容,就要用 yum 且注意 openssl-devel 版本。aarch64 架构下 glibc 版本如果太老,会导致 nginx 1.23.2 的 configure 阶段检测失败,后面会专门讲这个坑。内核版本还有个作用,uname -r如果带.aarch64后缀,说明是标准 ARM64 内核,这个不影响。总之第一件事不是下载源码,而是记录清楚系统指纹,后面排错全靠它。
2.2 安装编译依赖,离线环境记得挂本地源
nginx 1.23.2 的源码编译依赖并不复杂,核心就四样:编译器 gcc、make 构建工具、PCRE 正则库、zlib 压缩库、openssl 加解密库。在麒麟 aarch64 上,这些依赖全部有 aarch64 的 rpm 包,直接 dnf 安装即可。这里给出的命令是完整依赖组,不是只装一个 gcc 就够,少一个都会在 configure 阶段报错:
dnf install -y gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel逻辑说明:gcc 负责把 nginx 的 C 源码编译成 aarch64 指令集的机器码;pcre-devel 这个包提供了编译时所需的头文件和动态链接库,nginx 的 rewrite 模块在 configure 阶段强制检测 pcre;zlib-devel 是 gzip 压缩模块的依赖,打开--with-http_gzip_static_module就必须有它;openssl-devel 提供 TLS 相关的头文件,--with-http_ssl_module必须依赖它。这里有个细节,麒麟 V10 默认可能自带 openssl 运行库,但没有 openssl-devel,如果你只装运行库就去 configure,会直接报 "the HTTP SSL module requires the OpenSSL library"。
在离线环境下,dnf 源往往指向一个不存在的远程地址,这时候要先确认/etc/yum.repos.d/里的 repo 文件是否指向本地光盘或镜像服务器。麒麟 V10 安装完以后,repo 文件经常残留http://的开源镜像地址,内网环境根本访问不了,导致 dnf 一直在联网超时。常见做法是先dnf makecache试一下,如果失败,就去改 repo 文件的 baseurl 指向本地的 DVD 挂载点。
2.3 下载 nginx 1.23.2 源码并做完整性校验
依赖装好以后,下一步就是拿源码。nginx 1.23.2 是 mainline 版本,可以从 nginx 官网的下载目录取,也可以在能访问外网的主机上下好再传进内网。这里要注意一点:1.23.2 这个版本在 nginx 官方的归档里是真实存在的,下载路径有固定规律,但不要从第三方站点随便拉,源码包被篡改的后果是编译出带后门的二进制,这个风险在信创环境里尤其敏感:
wget https://nginx.org/download/nginx-1.23.2.tar.gz echo "根据你拿到的官方校验值替换下面这一行" md5sum nginx-1.23.2.tar.gz tar -xzf nginx-1.23.2.tar.gz cd nginx-1.23.2参数说明:wget把源码包拉下来,md5sum计算本地文件的哈希值,拿这个值跟官方发布的校验值比对,一致才继续。比对这一步看起来多余,但在等保环境下不做的后果是,你连自己跑的是什么代码都不知道。tar -xzf解压后进入nginx-1.23.2目录,后续所有操作都在这个目录下执行。如果内网不能直接访问外网,就在有网的环境下载后用 scp 或 U 盘拷贝,拷贝之后同样要算一遍 md5,防止传输过程中文件损坏。
源码目录里有两个文件要提前认识一下:configure是生成 Makefile 的脚本,auto/目录存放所有平台检测逻辑,nginx 在哪个 CPU 架构上编译,靠的就是这一整套 auto 检测。aarch64 架构下,configure 检测到的 CPU 类型是 ARM64,编译器会默认生成 ARMv8 指令集的代码。
3. configure 参数选型:aarch64 环境下的最小参数与专项优化
3.1 一组经过验证的最小 configure 参数
nginx 1.23.2 的 configure 阶段是整个编译过程里最容易翻车的地方,参数太少会导致模块缺胳膊少腿,参数太多又可能引入无谓的依赖。我先给出在麒麟 aarch64 上验证过的一组最小参数,然后逐个解释为什么选它,再给出适合你按需修改的选项。
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-cc-opt='-O2'逻辑说明:--prefix指定安装路径,所有编译产物都会落在/usr/local/nginx下,包括配置文件和二进制本体,这个路径对系统管理最友善,卸载的时候直接删目录就行;--with-http_ssl_module必须带上,否则 HTTPS 功能完全不可用,这是信创环境的基本要求;--with-http_v2_module启用 HTTP/2,现在很多审计项要求 nginx 必须支持 HTTP/2;--with-http_stub_status_module提供/nginx_status页面,监控系统拿数据全靠它;--with-http_gzip_static_module是静态 gzip 预压缩,减少 CPU 开销;--with-pcre强制使用系统 PCRE 库,而不是 nginx 自带的旧版,这个参数在 aarch64 上更稳妥,因为自带的 PCRE 编译在某些内核配置下会出现无法解释的信号错误。
--with-cc-opt='-O2'这个参数很多人会忽略,它直接透传给 gcc 编译选项,-O2是兼顾性能和体积的标准优化级别。在 aarch64 上不建议不加优化直接用默认值,那样生成的二进制跑起来性能会明显偏弱。如果对性能有更高要求,可以在这个参数里追加-march=armv8-a+crc,启用 ARMv8 的 CRC 指令,但这要求目标机器的 CPU 必须是 ARMv8 及以上架构,大部分鲲鹏、飞腾新平台都满足,老平台就未必了。
3.2 aarch64 特有编译选项:跑满 ARMv8 指令集
configure 完成后会生成 Makefile,但真正决定生成代码质量的是 gcc 的-march和-mtune参数,这两个参数对 x86 和 aarch64 的含义差距很大。在 x86 上-march=nocona是主流,但你把它照搬到 aarch64 会直接报错,因为 gcc 在 aarch64 上不认识 x86 的 CPU 代号。麒麟 aarch64 机器上更合理的一组编译参数是:
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-cc-opt='-O2 -march=armv8-a+crc -mtune=generic' \ --with-ld-opt='-Wl,-z,relro -Wl,-z,now'参数说明:-march=armv8-a+crc指明生成 ARMv8 指令集代码并启用 CRC 扩展,这是 aarch64 上比较安全的优化档位,兼容性比-march=armv8.2-a更广泛,同时比默认的-march=armv8-a多拿到 CRC 指令,能加速某些校验运算。-mtune=generic表示不针对特定核心做调优,避免在混合服务器集群里出现代码在最老核心上表现不佳的情况。--with-ld-opt的两个参数是链接选项:-z relro和-z now是安全加固,把 GOT 表设为只读并且立即绑定,对所有 ELF 可执行文件有防护效果,等保检查里有加分项意义,代价是启动时间略微增加,这个代价对 Web 服务可以忽略。
3.3 模块裁剪:去掉用不上的模块,减少攻击面
aarch64 的机器通常承担的是高性能或高密度 Web 服务场景,模块裁剪比 x86 环境更重要,因为每个编译进去的模块都是一份额外的内存和攻击面。nginx 1.23.2 默认编译的模块包含 mail 相关能力和一些 stream 旧协议支持,如果你只是做 HTTP 反向代理和静态服务,这些模块都是多余的。一组常用的裁剪参数如下:
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --without-http_mail_module \ --without-http_geo_module \ --without-http_map_module \ --without-http_limit_conn_module \ --without-http_limit_req_module \ --without-http_memcached_module \ --without-http_userid_module \ --without-http_access_module \ --with-cc-opt='-O2'逻辑说明:--without-http_mail_module去掉邮件代理功能,绝大多数业务用不到;--without-http_geo_module和--without-http_map_module去掉按 IP 和变量映射的模块,如果配置里不需要geo和map指令就可以裁剪,但需要注意,某些第三方模块可能隐式依赖 map,裁掉以后第三方模块编译不过,所以裁剪前要看清楚你的业务配置。--without-http_limit_conn_module和--without-http_limit_req_module是限流模块,如果业务没有限流需求可以裁掉,但有防爬需求的必须保留。--without-http_access_module这个要特别谨慎,它去掉的是allow/deny指令,如果你的配置里依赖 IP 黑白名单就千万不能裁。
裁剪的原则只有一个:配置里用到的指令必须有对应模块,没用到的不确定就先保留,等业务稳定后再二次裁剪。每裁掉一个模块,编译时间会缩短几秒,内存占用也会下降,但最核心的好处是减少漏洞暴露面。裁太狠的后果是某个深夜业务上线后才发现缺了必需指令的报错,到时候加模块就得重新编译,一次教训吃够。
4. 编译、安装与 systemd 托管:从 make 到开机自启
4.1 make 编译与常见编译报错
configure 没有报错后,就进入真正的编译阶段。aarch64 机器核心数一般不少,用并行编译能大幅缩短时间,但并行编译遇到报错时日志会乱,这点要有心理准备。先单线程编译一次,确认能过再并行,是更稳妥的做法。
make -j$(nproc)逻辑说明:-j$(nproc)用 nproc 命令获取 CPU 核心数,然后按这个数量并行编译。如果机器是 128 核,一次性跑 128 个编译任务,内存占用会比较明显,建议内存小于 16G 的机器改用make -j4或make -j8。编译过程中如果出现 "error: unknown type name" 或 "fatal error: openssl/ssl.h: No such file or directory",基本可以断定是依赖缺失,回第 2 章补装对应 devel 包,不需要动 configure 参数。如果出现 "pcre.h: No such file or directory",就是 pcre-devel 没装;出现 "zlib.h: No such file" 就是 zlib-devel 没装。
编译成功后会生成objs/nginx这个可执行文件,这是一个 ELF 格式的 aarch64 二进制,可以用file objs/nginx验证格式,输出里应该包含 "ELF 64-bit LSB executable, ARM aarch64"。看到这个输出基本可以确定编译产物架构正确,不会出现前面说的 "Exec format error"。这一步是很多人的盲区,明明有交叉编译工具链,却没人验证产物架构,等到落地时才发现二进制是 x86 的。
4.2 安装与 nginx -t 前置检查
编译无误后,安装本身很简单,但安装之后的配置校验一定要做。很多人在这一步直接复制网上 x86 环境的 nginx.conf,结果在 aarch64 的麒麟上启动报错,问题往往出在路径和模块支持上。
make install /usr/local/nginx/sbin/nginx -t逻辑说明:make install会把二进制、配置目录、日志目录全部装到--prefix指定的位置。默认安装路径下,/usr/local/nginx/conf/nginx.conf是主配置,/usr/local/nginx/html/是默认站点目录,/usr/local/nginx/logs/是日志目录。nginx -t是测试配置文件语法的命令,输出syntax is ok表示配置可以正常加载,输出test is successful表示测试通过。这一步必须在启动前做,但要注意,nginx -t只会检查语法和文件路径,不会检查端口占用和权限问题,真正的启动错误会在 nginx 的 error.log 里出现。
麒麟 aarch64 环境下,/usr/local/nginx/conf/nginx.conf里的默认 user 指令是user nobody;,但如果系统中没有 nobody 用户,启动时会有告警。建议改成user nginx;并提前建好 nginx 用户和日志目录的属主,具体命令在下一节 systemd 单元里一并处理。安装完成后先别急着启动,先改好配置、建好用户,再走 systemd 流程。
4.3 写 systemd 单元文件,托管 nginx 生命周期
麒麟系统默认用 systemd 管理服务,如果你不写 systemd 单元,直接手动执行 sbin/nginx,那么服务器重启后 nginx 是无法自动拉起服务的,这在生产环境是绝对不可接受的。一个可用的单元文件如下:
cat > /etc/systemd/system/nginx.service <<'EOF' [Unit] Description=nginx - high performance web server After=network-online.target Wants=network-online.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target EOF逻辑说明:Type=forking告诉 systemd,nginx 主进程会 fork 出 worker 进程,服务启动完成的标志是主进程成功 fork;PIDFile指向 nginx 的 pid 文件,systemd 靠它跟踪主进程状态;ExecStart不能加-g daemon off前缀,因为 forking 类型本身就是让 nginx 后台化,这与 Docker 里跑的玩法正好相反;PrivateTmp=true是安全加固选项,给服务独立的临时目录,防止其他进程通过 /tmp 攻击 nginx,这个选项在等保环境里建议保持开启。
单元文件写好后,需要重新加载 systemd 配置,然后 enable 开机自启并启动服务。如果开机自启没做,机房断电重启后 nginx 不会拉起,这个坑很多人踩过。
systemctl daemon-reload systemctl enable nginx systemctl start nginx systemctl status nginx参数说明:daemon-reload让 systemd 重新读取单元文件;enable创建符号链接,使 nginx 在 multi-user.target 下开机自启;start立即启动;status查看运行状态。状态显示 active (running) 基本就成功了。如果状态里显示 failed,先不要慌,执行journalctl -u nginx -n 50看 systemd 视角的日志,再去看/usr/local/nginx/logs/error.log,两个日志分别对应启动器和 nginx 自身的视角,能覆盖九成启动问题。
5. 麒麟 aarch64 上挂载 nginx 的避坑清单:从 glibc 到安全模块
5.1 配置报错 rewrite 模块需要 PCRE,但库装不全
现象:configure 执行到一半,输出the HTTP rewrite module requires the PCRE library,然后直接退出,整个配置过程失败。很多人明明装了 pcre-devel,却还是报这个错。
原因:麒麟 V10 的 aarch64 版本可能有多个 pcre 版本共存,系统默认 pcre2,而 nginx 1.23.2 的 rewrite 模块检测的是 pcre1。如果只装了 pcre2-devel,configure 检测不到 pcre1 的头文件,就会误判为库不存在。
解决:确认 pcre-devel 这个包名确实装上,而不是 pcre2-devel。执行rpm -qa | grep pcre看输出里是否有pcre-版本,如果是pcre2-开头的,需要用 dnf 显式安装 pcre 包,命令是dnf install -y pcre pcre-devel。装完再重新执行 configure,不需要删掉之前的产物,因为 configure 是幂等操作,失败后重新执行即可。这个坑的问题在于 pcre 和 pcre2 是两个完全不同的库,API 不兼容,nginx 1.23.2 和更早的所有版本都使用 pcre1,这是一个历史包袱。
5.2 启动时报错找不到 libpcre.so.1 共享库
现象:make install 很顺利,nginx -t 也提示 syntax ok,但 service nginx start 之后,journalctl 里面写着error while loading shared libraries: libpcre.so.1: cannot open shared object file,或者执行 sbin/nginx 直接报同样的错。
原因:编译时链接的动态库路径没有登记到系统动态链接器的缓存里。/usr/local/nginx 下编译的二进制在运行时需要动态查找libpcre.so.1,但它不在 ldconfig 默认搜索目录里。
解决:先定位库文件位置,然后写入 ldconfig 配置并刷新缓存:
find /usr -name 'libpcre.so.1' 2>/dev/null echo '/usr/lib64' > /etc/ld.so.conf.d/nginx-aarch64.conf ldconfig逻辑说明:第一行 find 是为了确认库的实际路径,麒麟 aarch64 上通常是/usr/lib64/libpcre.so.1;第二行把/usr/lib64写进动态链接器的搜索配置;ldconfig刷新缓存。这个问题在 x86 环境也常见,但 aarch64 上因为系统的库目录可能是/usr/lib64或/usr/lib/aarch64-linux-gnu,需要先确认再写配置,否则刷新了也找不到。更稳的做法是在编译前检查pkg-config --libs libpcre是否正常输出,编译时加上--with-ld-opt=-Wl,-rpath,/usr/lib64把运行时路径固化到二进制里,一劳永逸。
5.3 安全管控模块拦截 nginx 启动或配置写入
现象:服务启动后几秒内自动退出,journalctl 里出现Operation not permitted或Permission denied,而且这些错误和文件权限无关,用户、属主全部正确,换一台普通 CentOS 机器同样配置就能启动。
原因:麒麟 V10 自带的安全管控模块(在一些版本里叫 ksec,在不同 SP 版本行为略有区别)对二进制文件的执行、配置文件的写入有额外的安全策略限制。默认策略会拦截对关键防护目录的可疑写入和未签名二进制的执行,而 nginx 的 worker 进程需要写日志、写 pid 文件,这些动作刚好被策略拦下。
解决:先临时关闭模块验证假设,再配置白名单。临时关闭命令因版本而异,较常见的是sudo ksec --disable或者执行系统自带的安全中心工具关闭防护,关闭后再启动 nginx 测试。如果确认是模块拦截,就把/usr/local/nginx、/var/log/nginx等路径加入可信目录白名单。这里要注意,关闭安全模块后必须重新打开,不要为省事直接把模块永久禁用,等保审计看到防护模块被关会有麻烦。这个问题的排查顺序应该在配置里确认 pid 路径可写、selinux 是否 enforcing 都确认之后,才去动安全模块开关,免得误伤。
5.4 高并发下 aarch64 机器出现莫名的 worker 进程崩溃
现象:压测到每秒几千请求时,nginx error.log 里出现segfault at ...或worker process exited on signal 11,但低并发完全正常。同一份二进制放到 x86 机器同样压力下却没事。
原因:aarch64 架构下的内存序和原子指令跟 x86 差异较大,最常见的诱因是 nginx 运行时依赖的 pcre 库做 JIT 编译时生成的缓存与机器指令集不匹配。另一个常见原因是系统页大小异常,如果麒麟启用了 64K 页(内核 CONFIG_ARM64_VA_BITS 相关配置),而 nginx 或 pcre 编译时使用了针对 4K 页的假设,会导致共享内存映射异常。
解决:在 configure 阶段显式关掉 pcre JIT,并重新编译:
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-pcre \ --without-pcre-jit \ --with-cc-opt='-O2'参数说明:--without-pcre-jit这个参数很多线上教程不会提,但它在 aarch64 上是防崩溃的保命参数。PCRE JIT 在 ARM64 上的实现成熟度不如 x86,开启后在高并发下有概率生成非法指令,触发 segment fault。关掉 JIT 的正则性能下降大约 20%,但对绝大多数 Web 场景来说这 20% 根本感知不到,稳定性的收益远大于性能损失。编译前还要用getconf PAGESIZE查看页大小,输出如果是 65536,说明系统用了 64K 页,需要在编译内核参数上额外注意;如果是 4096,就是标准 4K 页,不用额外处理。这个问题是 aarch64 平台独有的,x86 机器无论如何复现都没有,判断时要注意不要被常规的 ulimit 排查带偏。
6. 验证压测与离线分发:把 nginx 1.23.2 固化成可复制的产物
nginx 编译安装完以后,只算完成了一半,另一半是验证它确实能在麒麟 aarch64 上稳定扛住真实流量,以及如何把这次编译的成果复制到同架构的其他机器上。压测命令我一般选 ab,它是 Apache 自带的工具,在麒麟源里可以直接装,不需要额外引入 wrk 这类工具。先压一个小并发峰值,确认没有崩溃,再压一个长时间稳定性测试,观察 worker 进程是否稳定:
dnf install -y httpd-tools ab -n 100000 -c 500 http://127.0.0.1/-n 100000是总请求数,-c 500是并发数,这两个数字根据机器性能可以调整,重点看输出里的 Requests per second 和 Failed requests 两项。如果 Failed requests 是 0,并且 Requests per second 的数值和同配置 x86 机器的差距在合理范围内,说明编译产物可用。压测过程中要同时盯systemctl status nginx和 error.log,任何 worker 进程异常退出都不能放过。这一步我在类似项目上吃过大亏,某次压测 60 秒没问题,但压到 5 分钟时 worker 进程就崩了一个,查到最后是 pcre JIT 的问题,加上--without-pcre-jit重新编译才稳定。
压测通过后,就要考虑离线分发的问题了。麒麟 aarch64 的机器往往不止一台,每台都重新编译是浪费,而且编译环境可能不一致导致产物有细微差异。常见做法是把本次编译好的产物直接打包,用 tar 归档后分发到相同架构、相同系统版本的其他机器解压即可:
tar -czf nginx-1.23.2-kylin-aarch64.tar.gz /usr/local/nginx这个包在目标机器解压后,需要确认两件事:一是动态链接库是否存在,用ldd /usr/local/nginx/sbin/nginx | grep "not found"检查,有 not found 就在目标机器上装对应 devel 包;二是把第 4 章的 systemd 单元文件一并拷过去,执行 daemon-reload 和 enable。这样分发出去的产物和你压测过的完全一致,不需要二次编译,目标机器越多,省的时间越明显。
还有一个更进一步的玩法是做成 rpm 包,用 rpmbuild 把编译产物和配置文件打包成当前机器架构的 rpm,在相同系统的其他机器上一条rpm -ivh nginx-1.23.2-kylin-aarch64.rpm就能装好。rpm 包的好处是卸载、升级、校验都走系统标准流程,适合几十台以上的批量交付。rpmbuild 的 spec 文件写起来稍繁琐,但如果你已经有了一套手工编译加分发流程,把它固化成 rpm 只是时间问题。我在这个方向上用过几次以后,反而再也不想回到 tar 包分发的模式了,tar 包在目标机器上的文件散落路径太容易出乱子,rpm 一条命令搞定还要每台机器去手动解压、建用户、写 systemd,效率差了几倍。
这套流程跑完,nginx 1.23.2 在麒麟 aarch64 上能不能用、怎么用、坑在哪,基本已经摆清楚了。到最后我还是想提醒一句,aarch64 不是 x86 的等比例缩放,任何从 x86 抄来的编译参数和启动方式都要先在这个架构上重新验证一遍。我自己在 pcre JIT 上翻过车,在安全模块上折腾过大半夜,这些血泪经验写进上面的避坑清单里了,希望帮到你。
本文还有配套的精品资源,点击获取