python环境安装直接看第二部分即可。

1.背景

部署一个线上任务时,相同的代码本地开发机正常产出数据,线上产出数据为0,排查到原因是:

...
  File "/home/disk1/wangdeyong/venv/python3_shapely_new/lib/python3.9/site-packages/mcpack/pack.py", line 15, in <module>
    import ctypes
  File "/home/disk1/wangdeyong/venv/python3_shapely_new/lib/python3.9/ctypes/__init__.py", line 8, in <module>
    from _ctypes import Union, Structure, Array
ImportError: libffi.so.5: cannot open shared object file: No such file or directory

报错线上的python环境_ctypes模块缺少文件libffi.so.5,不知道这是个啥文件,查看开发机环境中_ctypes模块路径:

map@gzdt-map-poi-yingxiang-offline04 bin$ python
Python 3.6.5 (default, May 22 2023, 13:31:24)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _ctypes
>>> _ctypes.__file__
'/home/map/envs/fdbenv/python3/lib/python3.6/lib-dynload/_ctypes.cpython-36m-x86_64-linux-gnu.so'
>>> exit()

该模块在lib-dynload目录下,切换到线上环境的对应目录下,通过ldd命令查看cpython-36m-x86_64-linux-gnu.so文件的动态链接库是否存在not found的依赖:

map@gzdt-map-poi-yingxiang-offline04 bin$ cd ../lib/python3.9/lib-dynload/
map@gzdt-map-poi-yingxiang-offline04 lib-dynload$ ll | grep _ctypes
-rwxr-xr-x 1 map map  652608 2021-10-21 17:16:53 _ctypes.cpython-39-x86_64-linux-gnu.so
-rwxr-xr-x 1 map map   72808 2021-10-21 17:16:49 _ctypes_test.cpython-39-x86_64-linux-gnu.so
map@gzdt-map-poi-yingxiang-offline04 lib-dynload$ ldd _ctypes.cpython-39-x86_64-linux-gnu.so
	linux-vdso.so.1 (0x00007ffd2dff0000)
	libffi.so.5 => not found
	libdl.so.2 => /opt/compiler/gcc-8.2/lib/libdl.so.2 (0x00007fbce979e000)
	libpthread.so.0 => /opt/compiler/gcc-8.2/lib/libpthread.so.0 (0x00007fbce977f000)
	libc.so.6 => /opt/compiler/gcc-8.2/lib/libc.so.6 (0x00007fbce95da000)
	/opt/compiler/gcc-4.8.2/lib64/ld-linux-x86-64.so.2 (0x00007fbce95b2000)
map@gzdt-map-poi-yingxiang-offline04 lib-dynload$

该文件确实没有,关于该文件的作用查了一下gpt:

libffi.so.5是一个动态链接库文件,属于libffi库的第5个版本。libffi库是一个用于调用外部函数的库,它提供了一个接口,允许在运行时动态地创建函数调用接口,并将这些接口传递给外部函数。这对于与C语言编写的动态库进行交互非常有用。

在Linux系统中,动态链接库通常以.so结尾,后面跟着版本号。libffi.so.5表示libffi库的第5个版本。动态链接库可以在运行时被加载到内存中,以提供程序运行所需的函数和功能。

可以手动下载该文件到lib-dynload下解决问题,但为了保持线上环境和开发机环境的一致,避免后续其他环境问题,下面选择重新部署一个和开发机环境相同的python环境。

2.python安装

https://www.python.org/downloads/source/
下载需要的版本源码:
在这里插入图片描述
两个压缩包任意,区别只是压缩方式不同,解压后得到的文件夹是一样的。本次下载的是Gzip方式压缩的。

上传到linux服务器,tar -zxf Python-3.6.5.tgz -C ./解压缩,得到Python-3.6.5文件夹
=> cd Python-3.6.5进入文件夹
=> 执行命令./configure --prefix=/home/disk1/wangdeyong/venv/python365配置需要安装的文件夹位置(不存在会自动创建)
=> 执行命令make,作用是编译生成二进制安装文件
=> 最后执行命令make install安装,等待执行完就ok。

执行完成后会生成一个和前面配置名相同的文件夹,进入到该文件夹中可以看到文件目录如下:

map@gzdt-map-poi-yingxiang-offline04 python365$ cd /home/disk1/wangdeyong/venv/python365 && ll
总用量 16
drwxr-xr-x 2 map map 4096 2024-08-12 11:51:58 bin
drwxr-xr-x 3 map map 4096 2024-08-12 11:38:17 include
drwxr-xr-x 4 map map 4096 2024-08-12 11:38:17 lib
drwxr-xr-x 3 map map 4096 2024-08-12 11:38:17 share

此时已经成功安装完成,为了方便可以cd到bin目录下创建个python软连接:

map@gzdt-map-poi-yingxiang-offline04 python365$ cd bin/
map@gzdt-map-poi-yingxiang-offline04 bin$ ln -s python3.6 python
map@gzdt-map-poi-yingxiang-offline04 bin$ ll
总用量 24836
lrwxrwxrwx 1 map map        8 2024-08-12 11:38:17 2to3 -> 2to3-3.6
-rwxrwxr-x 1 map map      130 2024-08-12 11:38:17 2to3-3.6
-rwxrwxr-x 1 map map      271 2024-08-12 11:38:19 easy_install-3.6
lrwxrwxrwx 1 map map        7 2024-08-12 11:38:17 idle3 -> idle3.6
-rwxrwxr-x 1 map map      128 2024-08-12 11:38:17 idle3.6
-rwxrwxr-x 1 map map      243 2024-08-12 11:38:19 pip3
-rwxrwxr-x 1 map map      243 2024-08-12 11:38:19 pip3.6
lrwxrwxrwx 1 map map        8 2024-08-12 11:38:17 pydoc3 -> pydoc3.6
-rwxrwxr-x 1 map map      113 2024-08-12 11:38:17 pydoc3.6
lrwxrwxrwx 1 map map        9 2024-08-12 11:46:08 python -> python3.6
lrwxrwxrwx 1 map map        9 2024-08-12 11:38:17 python3 -> python3.6
-rwxr-xr-x 2 map map 12694446 2024-08-12 11:38:04 python3.6
lrwxrwxrwx 1 map map       17 2024-08-12 11:38:17 python3.6-config -> python3.6m-config
-rwxr-xr-x 2 map map 12694446 2024-08-12 11:38:04 python3.6m
-rwxr-xr-x 1 map map     3146 2024-08-12 11:38:17 python3.6m-config
lrwxrwxrwx 1 map map       16 2024-08-12 11:38:17 python3-config -> python3.6-config
lrwxrwxrwx 1 map map       10 2024-08-12 11:38:17 pyvenv -> pyvenv-3.6
-rwxrwxr-x 1 map map      470 2024-08-12 11:38:17 pyvenv-3.6

map@gzdt-map-poi-yingxiang-offline04 bin$ ./python -V
Python 3.6.5

这种安装方式会将python安装到指定目录,不会影响系统中其他的python环境。

3.包环境复制

通过python -m pip freeze > requirements.txt导出包列表
=> python -m pip install -r requirements.txt安装的过程中,因为原python环境存在手动安装的包,一直报找不到包路径的错误,所以直接将原python环境site-packages下的全部内容copy到新python环境的site-packages中。

# 查看原环境的模块查找路径
map@gzdt-map-poi-yingxiang-offline04 bin$ python -m site
sys.path = [
    '/home/disk1/wangdeyong/venv/python365/bin',
    '/home/map/envs/fdbenv/python3/lib/python36.zip',
    '/home/map/envs/fdbenv/python3/lib/python3.6',
    '/home/map/envs/fdbenv/python3/lib/python3.6/lib-dynload',
    '/home/map/envs/fdbenv/python3/lib/python3.6/site-packages',
]
USER_BASE: '/home/map/.local' (exists)
USER_SITE: '/home/map/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

# 查看新环境的模块查找路径
map@gzdt-map-poi-yingxiang-offline04 bin$ ./python -m site
sys.path = [
    '/home/disk1/wangdeyong/venv/python365/bin',
    '/home/disk1/wangdeyong/venv/python365/lib/python36.zip',
    '/home/disk1/wangdeyong/venv/python365/lib/python3.6',
    '/home/disk1/wangdeyong/venv/python365/lib/python3.6/lib-dynload',
    '/home/disk1/wangdeyong/venv/python365/lib/python3.6/site-packages',
]
USER_BASE: '/home/map/.local' (exists)
USER_SITE: '/home/map/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

map@gzdt-map-poi-yingxiang-offline04 bin$ cp -r /home/map/envs/fdbenv/python3/lib/python3.6/site-packages/* /home/disk1/wangdeyong/venv/python365/lib/python3.6/site-packages

这种直接复制的方式用pip list命令一样能显示已复制安装的包,相对于pip安装有什么弊端暂时还未发现,优先推荐pip的安装方式。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐