ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

麒麟aarch64系统源码编译nginx 1.23.2实战指南

麒麟aarch64系统源码编译nginx 1.23.2实战指南 简介本资源为 Nginx 1.23.2 在麒麟操作系统上的 AArch64ARM64架构编译版本面向需要在国产化服务器环境部署 Web 服务的运维与开发人员。包内共 21 个文件以 conf 配置、default 默认模板、html 页面、log 日志及 nginx 可执行文件为主涵盖 nginx.conf、mime.types、fastcgi_params、uwsgi_params、scgi_params 等核心配置以及 index.html、50x.html 等默认页面压缩包约 2.12MB目录结构完整解压即可对照使用。已有 1070 人学习下载。借助该资源读者可快速在麒麟 AArch64 平台搭建 Nginx 服务理解反向代理、负载均衡、HTTP/2 与 TLS 优化、PHP-FPM 集成及日志管理等关键配置并掌握 nginx -t 测试与平滑重载等运维思路适合作为国产化 Web 服务部署的实践参考。1. nginx1.23.2 在麒麟 aarch64 上到底难在哪手上有一台银河麒麟 V10 SP1 的机器CPU 是飞腾或鲲鹏uname -m出来是aarch64现在要在这上面跑 nginx 1.23.2。这个组合看着平平无奇真动手才知道坑不少官方 nginx.org 只给 x86_64 的预编译包麒麟自带的软件源里 nginx 版本又老得离谱直接yum install nginx装出来大概率是 1.14 甚至 1.16配置写法跟 1.23 差了一截。更麻烦的是很多人习惯性地去搜「nginx下载教程」照着 x86 的步骤走结果./configure一跑就报缺 pcre、缺 zlib或者编译过了但启动时报error while loading shared libraries。这篇东西就是把这个组合从零跑通的完整路径讲清楚源码编译怎么配参数、麒麟系统上依赖怎么补、systemd 怎么接、以及那些只有 aarch64 上才会遇到的玄学问题。适合两类人看——一类是刚拿到麒麟机器、要在上面搭 Web 服务或反向代理的运维另一类是想把现有 x86 上的 nginx 配置迁移到国产化平台、但不确定哪些参数要改的工程师。读完你应该能自己编译出一个带 stream 模块、带 http2、能正常跑 systemd 的 nginx 1.23.2并且知道出问题时先看哪里。2. 编译前的环境准备与依赖补齐2.1 先确认系统版本和 CPU 架构麒麟系统有好几个分支银河麒麟 V10 SP1、SP2、SP3 的包管理行为不完全一样动手前先把底摸清楚。执行下面几条命令把输出记下来后面选依赖包版本的时候要用。# 确认系统版本 cat /etc/kylin-release cat /etc/os-release # 确认 CPU 架构必须是 aarch64 uname -m lscpu | grep -E Architecture|Model name|CPU\(s\) # 确认包管理器是 yum 还是 dnf which yum dnf/etc/kylin-release里会写明是 V10 SP1 还是 SP2uname -m必须是aarch64如果是x86_64那说明你拿错机器了。包管理器方面V10 系列默认是yum部分新版本已经切到dnf两者命令基本兼容但dnf对依赖解析更严格后面装开发包时如果yum报冲突可以换dnf试。2.2 补齐编译 nginx 需要的开发库nginx 1.23.2 编译依赖三样东西PCRE正则rewrite 和 location 匹配要用、zlibgzip 压缩、OpenSSLHTTPS 和 http2。麒麟系统默认装的是运行时库开发头文件得单独装。另外编译工具链本身也要确认。# 安装编译工具链 yum install -y gcc gcc-c make automake # 安装 nginx 编译依赖的开发包 yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel # 确认 gcc 版本麒麟自带的一般是 7.x 或 9.x gcc --version这里有个血泪经验麒麟 V10 SP1 自带的 gcc 如果是 7.3.0编译 nginx 1.23.2 没问题但如果你之前手动升级过 gcc 到 10 以上可能会遇到configure阶段检测 OpenSSL 失败的情况原因是新版 gcc 对某些废弃 API 的警告被当成了错误。遇到这种就临时降回系统自带 gcc或者给./configure加--with-cc-opt-Wno-error。装完依赖后验证一下头文件在不在# 确认 pcre 头文件 ls /usr/include/pcre.h # 确认 zlib 头文件 ls /usr/include/zlib.h # 确认 openssl 头文件 ls /usr/include/openssl/ssl.h # 确认 openssl 版本1.23.2 要求 1.0.2 以上 openssl version如果pcre.h找不到说明pcre-devel没装上或者装到了非标准路径。麒麟有些版本会把 64 位库放在/usr/lib64头文件在/usr/include这是正常的。OpenSSL 版本低于 1.0.2 的话http2 模块编译会失败要么升级 OpenSSL要么编译时去掉--with-http_v2_module。2.3 下载 nginx 1.23.2 源码包nginx 1.23.2 是 2022 年 10 月发布的稳定版源码包在 nginx.org 上。麒麟机器如果没外网就提前在能上网的机器上下好用 U 盘或内网传过去。# 创建工作目录 mkdir -p /usr/local/src/nginx-build cd /usr/local/src/nginx-build # 下载源码包如果没有外网就跳过这步手动上传 # 注意这里不写具体下载链接按实际可用的镜像地址替换 # wget nginx-1.23.2.tar.gz 的实际地址 # 解压 tar -zxvf nginx-1.23.2.tar.gz cd nginx-1.23.2解压后先看一眼目录结构确认auto/、src/、conf/都在。如果解压报错gzip: stdin: not in gzip format说明下载的文件不对可能下到了 HTML 错误页重新下。3. configure 参数怎么配才不翻车3.1 最小可用配置和完整配置的取舍nginx 的./configure参数决定了哪些模块编进去。参数给少了后面要用 stream 做四层转发发现没编参数给多了编译时间翻倍不说还可能引入不必要的依赖。我一般分两步走先跑一个最小配置确认工具链没问题再跑完整配置。最小配置只开 http 和基本模块./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_gzip_static_module \ --with-http_stub_status_module这个配置能跑起来一个支持 HTTPS、HTTP/2、gzip 静态压缩和状态页的 nginx适合只做 Web 服务的场景。--prefix指定安装路径我习惯放/usr/local/nginx跟系统包管理的路径分开避免冲突。完整配置加上 stream 和 realip./configure \ --prefix/usr/local/nginx \ --sbin-path/usr/local/nginx/sbin/nginx \ --conf-path/usr/local/nginx/conf/nginx.conf \ --pid-path/usr/local/nginx/logs/nginx.pid \ --lock-path/usr/local/nginx/logs/nginx.lock \ --error-log-path/usr/local/nginx/logs/error.log \ --http-log-path/usr/local/nginx/logs/access.log \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --with-http_sub_module \ --with-stream \ --with-stream_ssl_module \ --with-stream_realip_module \ --with-threads \ --with-file-aio \ --with-cc-opt-O2 -Wno-error \ --with-ld-opt-Wl,-rpath,/usr/local/nginx/lib逐项说明关键参数--with-stream是四层代理模块做 MySQL、Redis 转发必须加--with-http_realip_module在 nginx 前面还有一层负载均衡时用来取真实客户端 IP--with-cc-opt-O2 -Wno-error里的-Wno-error是给新版 gcc 兜底的防止警告变错误--with-ld-opt里的 rpath 是防止运行时找不到动态库aarch64 上这个坑比 x86 更常见。提示--with-file-aio在部分麒麟内核上可能不生效如果编译报aio相关错误去掉这个参数即可不影响基本功能。3.2 configure 报错怎么排查./configure阶段最常见的三类报错第一类checking for PCRE library ... not found。这说明pcre-devel没装或者头文件路径不对。先rpm -qa | grep pcre确认包在不在在的话用find / -name pcre.h 2/dev/null找头文件位置如果不在/usr/include就加--with-pcre/path/to/pcre指定源码目录或者建软链接。第二类checking for OpenSSL library ... not found。麒麟上 OpenSSL 可能装在/usr/local/openssl而不是/usr这时候要显式指定--with-openssl/usr/local/openssl。注意这个参数指向的是 OpenSSL 源码目录不是安装目录如果只有安装好的库没有源码就用--with-cc-opt和--with-ld-opt手动指定头文件和库路径。第三类C compiler cc is not found。这是 gcc 没装或者 PATH 不对yum install gcc解决。如果装了还报检查echo $PATH里有没有/usr/bin。3.3 编译和安装configure 通过后make和make install两步走。aarch64 上编译时间比 x86 长飞腾 2000 系列大概 3 到 5 分钟鲲鹏 920 快一些。# 编译-j 后面跟 CPU 核心数加速编译 make -j$(nproc) # 编译成功后安装 make installmake -j$(nproc)会自动用满所有核心nproc在麒麟上返回的是可用核心数。如果编译过程中报virtual memory exhausted说明内存不够去掉-j参数单线程编或者临时加 swap。安装完成后验证# 确认二进制文件存在 ls -l /usr/local/nginx/sbin/nginx # 查看编译进去的模块 /usr/local/nginx/sbin/nginx -Vnginx -V的输出里会列出所有--with-参数确认你需要的模块都在。特别注意--with-stream和--with-http_ssl_module有没有出现这两个是最容易漏的。4. 启动、systemd 接管与开机自启4.1 手动启动和配置文件检查安装完先别急着配 systemd手动跑一遍确认二进制没问题。# 检查配置文件语法 /usr/local/nginx/sbin/nginx -t # 启动 /usr/local/nginx/sbin/nginx # 确认进程和端口 ps -ef | grep nginx ss -tlnp | grep nginxnginx -t会输出syntax is ok和test is successful如果有报错会指明行号。启动后ss -tlnp应该能看到 80 端口在监听。如果启动报bind() to 0.0.0.0:80 failed (13: Permission denied)说明不是 root 用户麒麟上 1024 以下端口需要 root 或CAP_NET_BIND_SERVICE权限。4.2 写一个靠谱的 systemd unit 文件手动启动只能临时用生产环境必须交给 systemd 管。麒麟 V10 用的是 systemdunit 文件放/usr/lib/systemd/system/nginx.service。[Unit] Descriptionnginx - high performance web server Documentationhttps://nginx.org/en/docs/ Afternetwork-online.target remote-fs.target nss-lookup.target Wantsnetwork-online.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStartPre/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload/bin/kill -s HUP $MAINPID ExecStop/bin/kill -s TERM $MAINPID PrivateTmptrue LimitNOFILE65535 Restarton-failure RestartSec5 [Install] WantedBymulti-user.target关键点说明Typeforking是因为 nginx 默认以 daemon 方式启动主进程 fork 后退出systemd 需要靠PIDFile追踪真正的 master 进程。ExecStartPre里加nginx -t是后悔药配置写错了 systemd 直接拒绝启动不会把旧进程杀掉。LimitNOFILE65535解决「nginx 最大并发连接数老是用超」的问题麒麟默认的nofile限制是 1024不改的话worker_connections设再大也没用。写完 unit 文件后# 重载 systemd 配置 systemctl daemon-reload # 设置开机自启 systemctl enable nginx # 启动 systemctl start nginx # 查看状态 systemctl status nginxsystemctl status显示active (running)就对了。如果显示failed用journalctl -u nginx -n 50看日志大部分问题是路径写错或者权限不对。4.3 麒麟上开机自启的额外注意点麒麟 V10 有些版本默认启用了NetworkManager-wait-online如果网络没就绪 nginx 就启动会报bind() to 0.0.0.0:80 failed。unit 文件里的Afternetwork-online.target和Wantsnetwork-online.target就是解决这个的但前提是network-online.target本身能正常触发。用systemctl status network-online.target确认一下如果是inactive可能需要systemctl enable NetworkManager-wait-online。另外麒麟的防火墙默认可能是开着的80 和 443 端口没放行的话外部访问不了# 查看防火墙状态 systemctl status firewalld # 放行 80 和 443 firewall-cmd --permanent --add-port80/tcp firewall-cmd --permanent --add-port443/tcp firewall-cmd --reload如果 firewalld 没装或者用的是 iptables对应命令不一样用iptables -L -n看规则。5. 避坑aarch64 上特有的五个翻车现场5.1 启动报error while loading shared libraries: libpcre.so.1现象编译安装都成功nginx -V也能跑但一启动就报找不到libpcre.so.1或libssl.so.1.1。原因aarch64 上库文件默认装在/usr/lib64或/usr/local/lib64但 nginx 二进制里记录的 rpath 可能指向/usr/local/lib运行时链接器找不到。解决先ldd /usr/local/nginx/sbin/nginx | grep not found确认缺哪个库然后两种办法——一是把库路径加到/etc/ld.so.conf.d/下再ldconfig二是编译时加--with-ld-opt-Wl,-rpath,/usr/lib64重新编。我一般用第一种改完ldconfig立即生效不用重编。5.2nginx -t报unknown directive stream现象配置文件里写了stream { ... }nginx -t报未知指令。原因编译时没加--with-stream或者加了但nginx -V输出里没有。解决nginx -V确认没有的话重新./configure加上--with-stream再make make install。注意make install会覆盖二进制但不会动配置文件所以配置不用重写。5.3 反向代理 HTTPS 后端报net::ERR_CERT_COMMON_NAME_INVALID现象nginx 反代一个 HTTPS 后端浏览器访问报证书 CN 不匹配。原因nginx 作为客户端去连后端时默认不校验后端证书的 CN但如果后端证书是自签的或者 CN 跟实际访问的域名不一致某些客户端比如浏览器经过 nginx 转发后会报这个错。本质是proxy_ssl_name没设对。解决在location里显式指定location / { proxy_pass https://backend; proxy_ssl_server_name on; proxy_ssl_name backend.example.com; proxy_ssl_verify off; }proxy_ssl_server_name on让 nginx 在 TLS 握手时发送 SNIproxy_ssl_name指定 SNI 里的域名proxy_ssl_verify off是临时关掉证书校验生产环境应该配proxy_ssl_trusted_certificate指向正确的 CA 证书。5.4worker_connections调大了但并发上不去现象nginx.conf里worker_connections 65535worker_processes auto但压测时并发到几千就上不去了。原因系统级的nofile限制没改。worker_connections是 nginx 内部的但每个连接对应一个文件描述符系统不给那么多 fdnginx 也拿不到。解决三步走——/etc/security/limits.conf加* soft nofile 65535和* hard nofile 65535systemd unit 里加LimitNOFILE65535/etc/sysctl.conf加fs.file-max 1000000然后sysctl -p。改完systemctl restart nginx用cat /proc/$(cat /usr/local/nginx/logs/nginx.pid)/limits | grep open files确认生效。5.5 麒麟系统升级后 nginx 起不来现象系统打了一批补丁重启后 nginx 启动失败报symbol lookup error或version OPENSSL_1_1_1 not found。原因系统升级把 OpenSSL 从 1.1.1 升到了 3.xnginx 编译时链接的是旧版符号新版库里没有。解决openssl version确认当前版本如果确实升级了重新编译 nginx./configure时确保--with-http_ssl_module链接到新版 OpenSSL。如果不想重编临时办法是把旧版libssl.so.1.1和libcrypto.so.1.1从备份里恢复但这不是长久之计。我一般建议在麒麟上编译 nginx 时静态链接 OpenSSL--with-openssl/path/to/openssl-source加上no-shared这样系统升级 OpenSSL 不影响 nginx。6. 用 stub_status 和日志把线上问题钉死nginx 跑起来只是开始线上出问题时能快速定位才是关键。1.23.2 自带的stub_status模块和日志格式定制是两个最实用的手段。先看stub_status怎么配server { listen 127.0.0.1:8080; location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } }stub_status只监听本地回环外部访问不了安全。curl http://127.0.0.1:8080/nginx_status输出类似Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106Active connections是当前活跃连接数accepts是总接受连接数handled是成功处理的requests是总请求数。如果accepts和handled不相等说明有连接被丢弃通常是worker_connections不够或者 fd 限制。Reading是读请求头的连接数Writing是写响应的Waiting是 keepalive 空闲连接。Waiting特别高说明 keepalive 超时设太长了可以调keepalive_timeout。再看日志格式定制。默认的combined格式信息不够我一般加$request_time、$upstream_response_time、$upstream_addrlog_format main $remote_addr - $remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for rt$request_time urt$upstream_response_time ua$upstream_addr; access_log /usr/local/nginx/logs/access.log main;$request_time是 nginx 从收到第一个字节到发完响应的总时间$upstream_response_time是后端响应时间两者差值大说明 nginx 本身处理慢比如 gzip 压缩耗 CPU差值小但总时间长说明后端慢。$upstream_addr在有多台后端时能看出请求打到了哪台。配合stub_status和日志线上排查的套路是先看Active connections和Waiting判断连接状态再看 access.log 里rt和urt的分布如果urt普遍高就是后端问题如果rt高但urt低就是 nginx 配置问题比如proxy_buffering没开、gzip 级别太高。最后说一个我自己的习惯每次在麒麟上编译完 nginx第一件事是把nginx -V的输出和ldd的结果存到一个文件里跟配置文件一起归档。下次系统升级或者迁移机器直接对比这个文件能省掉大量「上次好好的这次怎么不行」的排查时间。aarch64 上的库依赖比 x86 脆弱留个底比什么都强。希望帮到你。本文还有配套的精品资源点击获取
返回列表