接手一个老项目的运维部署,核心是在鲲鹏aarch64架构的openEuler服务器上,部署一套基于Perl编写的定时任务脚本,用于内网日志清洗和文件传输。这套脚本在x86架构的centos服务器上运行了3年,从来没出过错,部署流程也很简单——装完Perl和相关依赖模块,直接执行脚本即可。本以为半小时就能搞定,结果执行脚本时直接翻车,反复提示“Can't locate LWP/UserAgent.pm in @INC”,明明通过yum装了对应的依赖,却始终报模块缺失。
整个排查过程,几次陷入僵局,明明x86上无需关注的细节,在鲲鹏上却成为痛点,尤其是Perl的编译参数和KAE依赖的适配,稍有疏忽就会导致脚本无法执行。下面再完整复盘一下。
第一时间排查Perl版本和基础依赖,服务器上默认装了Perl 5.26.3,是openEuler系统自带的aarch64适配版,执行perl -v能正常输出版本信息,排除Perl本身未安装或损坏的问题。报错提示缺失LWP/UserAgent.pm,这个模块属于perl-LWP-Protocol-https包,在x86服务器上,执行yum install -y perl-LWP-Protocol-https就能搞定,我这边也按同样的命令安装,yum提示“已安装最新版本”,但执行脚本还是报同样的缺失错误。
尝试手动查找缺失的模块文件,执行find / -name UserAgent.pm,发现文件确实存在,路径是/usr/share/perl5/vendor_perl/LWP/UserAgent.pm,而执行perl -e 'print join("\n", @INC)'查看Perl的模块搜索路径,也包含/usr/share/perl5/vendor_perl这个目录,路径和文件都对得上,怎么会提示找不到?
怀疑是模块权限问题,查看文件权限,UserAgent.pm的权限是644,属主和属组都是root,和其他正常的Perl模块权限一致,排除权限问题。又尝试将模块文件手动复制到Perl的另一个搜索路径下(/usr/lib64/perl5),重新执行脚本,还是报同样的错误,甚至提示“Can't locate LWP/UserAgent.pm in @INC (you may need to install the LWP::UserAgent module)”,仿佛复制的文件不存在一样。
这时候开始怀疑是Perl模块的架构适配问题,鲲鹏是aarch64架构,x86是32/64位架构,会不会yum安装的perl-LWP-Protocol-https包,虽然标注了aarch64适配,但实际是x86版本打包过来的,导致Perl无法识别?执行rpm -qa --qf '%{NAME}-%{VERSION}-%{ARCH}\n' perl-LWP-Protocol-https,输出显示“perl-LWP-Protocol-https-6.07-9.el8.aarch64”,确实是aarch64架构的包,排除包架构错误的问题。
接下来尝试用cpanm安装依赖模块,毕竟yum安装可能存在适配隐患,在x86服务器上,cpanm能自动下载适配架构的模块。先通过yum安装cpanm,执行yum install -y perl-App-cpanminus,安装顺利完成,但执行cpanm LWP::UserAgent时,却出现了编译失败的报错,提示“gcc: error: unrecognized command line option '-m64'”。
看到gcc报错,瞬间反应过来,可能是Perl编译依赖时,默认使用了x86架构的编译参数(-m64),而鲲鹏aarch64架构的gcc编译器不支持这个参数,导致编译失败。之前在x86服务器上,gcc默认支持-m64参数,用于指定64位编译,鲲鹏aarch64架构不需要这个参数,甚至不识别,这应该是cpanm安装失败的核心原因。
进一步排查发现,系统自带的Perl,在编译时默认保留了x86架构的编译配置,导致执行脚本或安装模块时,会自动调用不兼容的编译参数,而且部分Perl核心模块的路径配置,也存在架构适配缺陷,导致明明存在的模块,却无法被正常识别。
重新编译安装Perl并配置环境变量后,执行cpanm安装LWP::UserAgent,终于不再报编译错误,模块安装成功。本以为这下执行脚本就能正常运行,结果又出现了新的报错:“Can't locate Digest/MD5.pm in @INC”,这个模块是Perl的核心模块,按道理编译Perl时会默认安装,怎么会缺失?
排查发现,编译Perl时,虽然禁用了不适配的扩展模块,但鲲鹏aarch64架构下,Digest::MD5模块需要依赖KAE MD5摘要算法,而系统默认没有启用KAE加速引擎,导致该模块编译失败,未被正常安装。x86服务器上不需要依赖KAE,所以默认会安装该模块,鲲鹏上缺少这个适配步骤,导致核心模块缺失。
安装完KAE依赖并重新编译Digest::MD5模块后,再次执行Perl脚本,终于不再报任何错误,脚本正常启动,日志清洗和文件传输功能都能正常执行。后续测试定时任务,将脚本加入crontab,执行也正常,没有再出现依赖缺失或编译相关的报错。
接手一个老项目的运维部署,核心是在鲲鹏aarch64架构的openEuler服务器上,部署一套基于Perl编写的定时任务脚本,用于内网日志清洗和文件传输。这套脚本在x86架构的centos服务器上运行了3年,从来没出过错,部署流程也很简单——装完Perl和相关依赖模块,直接执行脚本即可。本以为半小时就能搞定,结果执行脚本时直接翻车,反复提示“Can't locate LWP/UserAgent.pm in @INC”,明明通过yum装了对应的依赖,却始终报模块缺失。
整个排查过程,几次陷入僵局,明明x86上无需关注的细节,在鲲鹏上却成为痛点,尤其是Perl的编译参数和KAE依赖的适配,稍有疏忽就会导致脚本无法执行。下面再完整复盘一下。
第一时间排查Perl版本和基础依赖,服务器上默认装了Perl 5.26.3,是openEuler系统自带的aarch64适配版,执行perl -v能正常输出版本信息,排除Perl本身未安装或损坏的问题。报错提示缺失LWP/UserAgent.pm,这个模块属于perl-LWP-Protocol-https包,在x86服务器上,执行yum install -y perl-LWP-Protocol-https就能搞定,我这边也按同样的命令安装,yum提示“已安装最新版本”,但执行脚本还是报同样的缺失错误。
尝试手动查找缺失的模块文件,执行find / -name UserAgent.pm,发现文件确实存在,路径是/usr/share/perl5/vendor_perl/LWP/UserAgent.pm,而执行perl -e 'print join("\n", @INC)'查看Perl的模块搜索路径,也包含/usr/share/perl5/vendor_perl这个目录,路径和文件都对得上,怎么会提示找不到?
怀疑是模块权限问题,查看文件权限,UserAgent.pm的权限是644,属主和属组都是root,和其他正常的Perl模块权限一致,排除权限问题。又尝试将模块文件手动复制到Perl的另一个搜索路径下(/usr/lib64/perl5),重新执行脚本,还是报同样的错误,甚至提示“Can't locate LWP/UserAgent.pm in @INC (you may need to install the LWP::UserAgent module)”,仿佛复制的文件不存在一样。
这时候开始怀疑是Perl模块的架构适配问题,鲲鹏是aarch64架构,x86是32/64位架构,会不会yum安装的perl-LWP-Protocol-https包,虽然标注了aarch64适配,但实际是x86版本打包过来的,导致Perl无法识别?执行rpm -qa --qf '%{NAME}-%{VERSION}-%{ARCH}\n' perl-LWP-Protocol-https,输出显示“perl-LWP-Protocol-https-6.07-9.el8.aarch64”,确实是aarch64架构的包,排除包架构错误的问题。
接下来尝试用cpanm安装依赖模块,毕竟yum安装可能存在适配隐患,在x86服务器上,cpanm能自动下载适配架构的模块。先通过yum安装cpanm,执行yum install -y perl-App-cpanminus,安装顺利完成,但执行cpanm LWP::UserAgent时,却出现了编译失败的报错,提示“gcc: error: unrecognized command line option '-m64'”。
看到gcc报错,瞬间反应过来,可能是Perl编译依赖时,默认使用了x86架构的编译参数(-m64),而鲲鹏aarch64架构的gcc编译器不支持这个参数,导致编译失败。之前在x86服务器上,gcc默认支持-m64参数,用于指定64位编译,鲲鹏aarch64架构不需要这个参数,甚至不识别,这应该是cpanm安装失败的核心原因。
进一步排查发现,系统自带的Perl,在编译时默认保留了x86架构的编译配置,导致执行脚本或安装模块时,会自动调用不兼容的编译参数,而且部分Perl核心模块的路径配置,也存在架构适配缺陷,导致明明存在的模块,却无法被正常识别。
# 鲲鹏openEuler Perl脚本执行适配操作(单独排查步骤) # 1. 卸载系统自带Perl及相关依赖,避免配置冲突 yum remove -y perl perl-LWP-Protocol-https perl-App-cpanminus # 2. 从华为开源镜像站下载适配鲲鹏aarch64的Perl源码包 wget https://mirrors.huaweicloud.com/perl/CPAN/src/5.0/perl-5.32.1.tar.gz # 3. 解压源码包,编译安装(禁用x86编译参数,适配aarch64) tar -zxvf perl-5.32.1.tar.gz cd perl-5.32.1 ./Configure -des -Dprefix=/usr/local/perl \ -Dcc=aarch64-linux-gnu-gcc \ -Dnoextensions='ODBM_File NDBM_File' # 禁用不适配的扩展模块 make && make install # 4. 配置Perl环境变量,替代系统默认Perl echo "export PATH=/usr/local/perl/bin:$PATH" >> /etc/profile echo "export PERL5LIB=/usr/local/perl/lib/perl5/site_perl/5.32.1:aarch64-linux" >> /etc/profile source /etc/profile # 5. 验证Perl版本及架构适配 perl -v perl -e 'print join("\n", @INC)' # 6. 重新安装所需Perl模块,使用适配的编译参数 cpanm LWP::UserAgent --install-args "--cc=aarch64-linux-gnu-gcc"重新编译安装Perl并配置环境变量后,执行cpanm安装LWP::UserAgent,终于不再报编译错误,模块安装成功。本以为这下执行脚本就能正常运行,结果又出现了新的报错:“Can't locate Digest/MD5.pm in @INC”,这个模块是Perl的核心模块,按道理编译Perl时会默认安装,怎么会缺失?
排查发现,编译Perl时,虽然禁用了不适配的扩展模块,但鲲鹏aarch64架构下,Digest::MD5模块需要依赖KAE MD5摘要算法,而系统默认没有启用KAE加速引擎,导致该模块编译失败,未被正常安装。x86服务器上不需要依赖KAE,所以默认会安装该模块,鲲鹏上缺少这个适配步骤,导致核心模块缺失。
安装完KAE依赖并重新编译Digest::MD5模块后,再次执行Perl脚本,终于不再报任何错误,脚本正常启动,日志清洗和文件传输功能都能正常执行。后续测试定时任务,将脚本加入crontab,执行也正常,没有再出现依赖缺失或编译相关的报错。