[转]应用系统迁移ARM环境经验总结(非Docker环境部署)
文章来自同事大神昆神的文章,也算是经验总结。授权转载收藏记录一下。
目前政府侧国产化之风渐浓,已经有多个政府场地开始采购国产品牌服务器,其中一些国产品牌服务器CPU是ARM架构,和常用的X86架构指令集不能直接兼容,导致X86上编译的程序无法在ARM上运行,因此涉及到适配工作。
现在公司常用的应用开发语言有Java、Python、Go、PHP等,其中以Java的适配最为简单。因Java字节码是平台无关的,只要安装了对应架构的JVM,Java字节码可以直接跨平台运行,无需重新编译。目前,OpenJDK从11起,已经提供了ARM版本的OpenJDK,因此迁移只需要更换对应的JDK即可,绝大部分jar包可以直接拷贝移植(极少部分依赖平台编译动态库的除外)。
Go语言开发的应用系统也较为方便,因Go语言支持跨平台交叉编译,只要在环境内安装有ARM平台的编译工具链以及依赖库,可以直接在X86环境完成ARM应用程序的编译,并拷贝到ARM环境运行(根据网上文档查阅,未实操)。
Python的移植比较繁琐,如果使用的是比较常用的第三方库还好,若是使用了较为冷门的第三方库,过程会很长,非常考验耐心(PHP类似,但PHP一般的依赖都比较通用,容易满足)。以下特别针对Python的移植做出介绍:
政府的服务器一般都在内网环境,不提供外网的访问,因此安装过程一般在离线环境,需要下载好依赖的Python包。Python的运行环境目前看Anaconda是一个很好的选择,Anaconda已经提供了ARM版本的安装包,如果应用程序依赖的包在Anaconda内
(列表参见:https://docs.anaconda.com/anaconda/packages/pkg-docs/) ,根据Python版本和架构方式点击对应的链接)直接可以找到,那么基本上直接安装Anaconda就可以了,一键完成。
如果依赖包在Anaconda中默认没有提供,那么还有几种选择:
1、在Anaconda网站上搜索(如搜索numpy:https://anaconda.org/search?q=numpy)。这个方法一般可以解决80%以上的依赖包需求,也提供了多个架构集的实现,参加下图:
2.向系统供应商索要rpm包。一般情况下,系统供应商会为常用的依赖库提供预先编译好的安装包,如华为银河麒麟系统提供的安装包列表:
http://update.cs2c.com.cn:8080/NS/V10/V10SP1/os/adv/lic/base/aarch64/Packages/ ,除了系统依赖外,也包含部分常用的python依赖包。
3.通过pip下载二进制包。命令如下:
pip download <包名> -d <下载到的目录> --only-binary=:all: --no-deps --platform linux_aarch64 --python-version 39 --implementation cp -i https://mirror.baidu.com/pypi/simple
--only-binary=:all: 表示下载二进制文件
--no-deps 表示不下载依赖包
--platform linux_aarch64 表示下载aarch64包,linux有时用manylinux代替,platform为any或者noarch表示此包可以跨平台使用,也能在aarch64环境安装
--python-version 39 表示下载的python版本是3.9,3.7写为37,3.8写为38即可
--implementation cp 表示下载cpython包,这个一般不需要加
-i 表示指定从哪个源上下载,国内一般使用百度源,下载很快
更多的命令选项参考:
https://pip.pypa.io/en/stable/cli/pip_download/
命令成功执行后在-d指定的目录中能找到下载的whl文件,使用pip可以直接安装:pip install <whl文件>
4. 通过pip下载源码包。命令格式基本等同下载二进制包,将--no-binary=:all:替换--only-binary=:all:即可。下载成功后得到一个压缩包,解压缩后如果里面有setup.py则执行python setup.py build和python setup.py install即可。
5.如果通过以上方式都找不到合适的依赖包,那么就在搜索引擎上查找下,或者在pypi网站上搜索。比如查找torch的安装包时发现在https://pypi.org/project/torch/#files有manylinux2014_aarch64版本的包,可以支持aarch64环境的安装。
另外kmtea网站也提供了aarch64版本的安装包:https://torch.kmtea.eu/
Python依赖包的查询:
可以下载安装pipdeptree这个工具,安装后在命令行执行:pipdeptree -p <包名> 即可,例如,想查看fastNLP这个包有哪些依赖,执行 pipdeptree -p fastNLP:
即可根据依赖包的名称和版本情况,进行查找安装。
Python从不同来源的包可能会出现安装无异常,但是运行时会有异常的情况(包括报错和非报错异常,无法得到正确结果),这个时候要仔细排查问题,找到相关的包进行替换(如在安装torch包时,出现过来自Anaconda和kmtea的包无法正确计算全连接参数值的问题,换了pypi网站的包就好了),对于线上使用要做好回归测试工作。
ARM服务的适配比较需要耐心,要根据错误提示灵活采用不同手段进行解决,过程可能比较曲折,祝适配顺利!