開發(fā)一個物流app需要多少錢優(yōu)化資源配置
一、背景
在SAAS(軟件即服務(wù))平臺中,用戶使用自行定制的Python腳本已經(jīng)成為司空見慣的做法,然而,由于不同用戶對Python三方庫的需求各不相同,而底層服務(wù)器一般只安裝了一個Python版本。舉例來說,假設(shè)用戶A需要pymysql=1.0.2版本,而用戶B需要pymysql=1.0.3版本,那么我們該如何應(yīng)對呢?
當(dāng)我們考慮將系統(tǒng)安裝的Python的pymysql三方庫依賴升級至1.0.3版本時,這必然會對用戶A產(chǎn)生潛在的風(fēng)險和影響。這就迫使我們需要一種解決方案,能夠滿足不同用戶或租戶對不同Python庫版本的需求,而不會相互干擾。這也是本文要深入闡述的關(guān)鍵內(nèi)容。
解決方案就在于Python虛擬環(huán)境。通過創(chuàng)建獨立的、隔離的Python運行環(huán)境,我們可以滿足不同用戶對Python庫的需求,而無需牽扯到底層服務(wù)器已安裝的Python版本。這使得每個用戶或租戶能夠擁有自己的Python環(huán)境,可以在其中自由地安裝、更新和管理所需的Python庫,而不會干擾其他用戶。
二、原理
2.1、Python依賴關(guān)系
在 Python 的生態(tài)系統(tǒng)中,依賴分為標(biāo)準庫和三方庫兩種,它們在開發(fā)過程中起著不同的作用:
- 標(biāo)準庫是由Python官方團隊維護和發(fā)布的一組模塊和庫。這些模塊和庫包含了豐富的工具和功能,涵蓋了文件I/O、字符串操作、網(wǎng)絡(luò)通信、數(shù)學(xué)計算、數(shù)據(jù)結(jié)構(gòu)、日期時間處理等方面。這些模塊是Python解釋器的一部分,在安裝Python時會一同安裝。標(biāo)準庫的模塊常被廣泛應(yīng)用于各類Python應(yīng)用程序中,因為它們保證了跨平臺的兼容性和穩(wěn)定性。
- 三方庫則是由Python社區(qū)貢獻和維護的庫,這些庫提供了豐富的功能,包括數(shù)據(jù)處理、Web開發(fā)、科學(xué)計算等領(lǐng)域。與標(biāo)準庫不同,三方庫不隨Python解釋器的安裝而自動包含,需要使用包管理工具如pip來安裝。它們的多樣性和靈活性為開發(fā)者提供了更廣泛的選擇空間,可以根據(jù)特定需求輕松獲取所需功能。
- 安裝目錄在文件系統(tǒng)中,Python標(biāo)準庫的模塊位于安裝目錄下的
Lib
目錄內(nèi),而三方庫則被安裝在Lib/site-packages
目錄下。這種結(jié)構(gòu)有助于開發(fā)者在系統(tǒng)中準確找到和管理所需的庫,如下圖:
2.2、虛擬環(huán)境依賴原理
Python虛擬環(huán)境實現(xiàn)了一種高效的依賴隔離機制,其核心原理在于充分利用系統(tǒng)Python的標(biāo)準庫,而三方庫則被完全隔離存儲于虛擬環(huán)境中的獨立目錄。
在Python虛擬環(huán)境中,標(biāo)準庫的管理與系統(tǒng)Python的標(biāo)準庫實現(xiàn)共享。這意味著虛擬環(huán)境不會單獨復(fù)制系統(tǒng)Python的標(biāo)準庫,而是通過指向系統(tǒng)Python標(biāo)準庫的符號鏈接進行訪問。這種方式確保了虛擬環(huán)境中的Python標(biāo)準庫與系統(tǒng)Python保持同步,同時避免了資源浪費。
與標(biāo)準庫不同,三方庫在虛擬環(huán)境中得到了徹底的隔離。每個虛擬環(huán)境都擁有自己獨立的Lib/site-packages
目錄,用于存儲安裝的三方庫。通過這種機制,不同虛擬環(huán)境內(nèi)的項目可以安全地使用不同版本或不同組合的三方庫,而無需擔(dān)心相互干擾或產(chǎn)生沖突,如下圖:
三、實戰(zhàn)
3.1、venv
、pyvenv
和 virtualenv
區(qū)別
創(chuàng)建Python虛擬環(huán)境通常有三種常用的命令:venv
、pyvenv
和 virtualenv
。
- venv:
venv
是 Python 3.3 及以上版本自帶的標(biāo)準庫模塊。- 這個命令能夠快速創(chuàng)建Python虛擬環(huán)境,并提供了一種簡潔而有效的方式來隔離項目的依賴關(guān)系。
- 使用方法是通過運行
python -m venv myenv
來創(chuàng)建一個名為myenv
的虛擬環(huán)境。
- pyvenv:
pyvenv
是 Python 3.3 之前版本中的一個命令,用于創(chuàng)建虛擬環(huán)境。- 它的功能與
venv
類似,但在較新的Python版本中已經(jīng)不再推薦使用,并被venv
替代。
- virtualenv:
virtualenv
是一個第三方庫,能夠在 Python 2.x 和 3.x 版本中使用。- 與前兩者不同,
virtualenv
提供了更多的靈活性和高級選項,可以為用戶提供更加定制化的虛擬環(huán)境。 - 通過運行
pip install virtualenv
安裝后,可以使用命令virtualenv myenv
創(chuàng)建一個名為myenv
的虛擬環(huán)境。
總體來說,venv
和 virtualenv
是創(chuàng)建Python虛擬環(huán)境最常用的方式。venv
是Python自帶的標(biāo)準庫模塊,提供了基本的虛擬環(huán)境功能,而 virtualenv
則提供了更多定制和高級選項,能夠滿足更復(fù)雜的需求。pyvenv
已在較新版本的Python中被棄用,建議使用更為推薦的 venv
。
3.2、創(chuàng)建虛擬環(huán)境
先通過執(zhí)行 venv 指令來創(chuàng)建一個 虛擬環(huán)境: 運行此命令將會生成一個目標(biāo)目錄(如果其父目錄不存在,也會被創(chuàng)建)
root@b3268f2479f8:~# python3 -m venv /usr/local/env/myenv
root@b3268f2479f8:~# ll /usr/local/env/myenv
total 16
drwxr-xr-x 2 root root 4096 Dec 15 06:48 bin
drwxr-xr-x 3 root root 4096 Dec 15 06:48 include
drwxr-xr-x 3 root root 4096 Dec 15 06:48 lib
lrwxrwxrwx 1 root root 3 Dec 15 06:48 lib64 -> lib
-rw-r--r-- 1 root root 177 Dec 15 06:48 pyvenv.cfg
同時在目標(biāo)目錄中會放置一個名為pyvenv.cfg
的文件。這個配置文件內(nèi)包含了一個home
鍵,指向運行此命令的 系統(tǒng) Python 命令位置:
root@b3268f2479f8:~# cat /usr/local/env/myenv/pyvenv.cfg
home = /usr/local/bin
include-system-site-packages = false
version = 3.12.1
executable = /usr/local/bin/python3.12
command = /usr/local/bin/python3 -m venv /usr/local/env/myenv
此外,命令還會在目標(biāo)目錄中創(chuàng)建一個bin
子目錄,其中包含了 Python 可執(zhí)行文件的拷貝或符號鏈接。同時,還會建立一個初始為空的lib/pythonX.Y/site-packages
子目錄,用于存放虛擬環(huán)境執(zhí)行pip安裝的三方庫:
3.3、激活虛擬環(huán)境
激活一個虛擬環(huán)境可以通過source 一個腳本來實現(xiàn)。在 linux 系統(tǒng)上,該腳本位于 bin 目錄下的 activate。這個激活操作的效果是將該目錄添加到你的 PATH 環(huán)境變量中。這樣,當(dāng)你運行 python 時,系統(tǒng)會調(diào)用虛擬環(huán)境的 Python 解釋器,使你能夠輕松運行虛擬環(huán)境中安裝的腳本,而無需使用完整的路徑信息,如下:
激活虛擬環(huán)境后,命令行頭部會顯示虛擬環(huán)境的名稱(myenv)以提示你當(dāng)前所處的環(huán)境,此時執(zhí)行pip依賴三方庫命令:由于虛擬環(huán)境被激活,故此時執(zhí)行的pip
命令會因為環(huán)境變量使用該虛擬環(huán)境中的pip
,而不是系統(tǒng)全局的pip
。
可以看到kafka依賴只存在于虛擬環(huán)境三方庫目錄,系統(tǒng)環(huán)境不受影響。
3.4、停用虛擬環(huán)境
停用(或退出)虛擬環(huán)境只需執(zhí)行 deactivate
命令即可。執(zhí)行該命令后,命令行提示符中不再顯示虛擬環(huán)境的名稱,并且系統(tǒng)的 $PATH
環(huán)境變量會回到默認狀態(tài),如下:
# 激活時$PATH
(myenv) root@b3268f2479f8:/usr/local/env/myenv# echo $PATH
/usr/local/env/myenv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# 停用時$PATH
(myenv) root@b3268f2479f8:/usr/local/env/myenv# deactivate
root@b3268f2479f8:/usr/local/env/myenv# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3.5、直接使用虛擬環(huán)境
其實激活虛擬環(huán)境并不是必須的,因為你可以直接指定特定虛擬環(huán)境的Python解釋器完整路徑來調(diào)用Python。更進一步地說,安裝在虛擬環(huán)境中的所有腳本也可以在不激活虛擬環(huán)境的情況下運行,例如:
此外,如果我們要使用虛擬環(huán)境的Python來執(zhí)行python腳本,我們可以在腳本中包含一個以“井號嘆號”開頭的行,用來指定虛擬環(huán)境的Python解釋器路徑,例如 #!/<path-to-venv>/bin/python
。這意味著無論$PATH
的取值如何,該腳本都將使用指定的解釋器來運行。
以下是一個示例,假設(shè)有一個名為example_script.py
的腳本,它指定了虛擬環(huán)境中Python解釋器的路徑:
#!/usr/local/env/myenv/bin/pythondef main():print("這個腳本安裝在虛擬環(huán)境中,并使用指定的解釋器運行!")if __name__ == "__main__":main()
在這個示例中,#!/usr/local/env/myenv/bin/python
表示腳本將使用位于虛擬環(huán)境中的Python解釋器來執(zhí)行。
因此,無需激活虛擬環(huán)境,該腳本都將使用特定虛擬環(huán)境中的解釋器來運行。
3.6、刪除虛擬環(huán)境
由于Python虛擬環(huán)境被視為可以隨時丟棄和重建的,你可以直接使用 rm
命令(在Unix或類Unix系統(tǒng)中)來刪除整個虛擬環(huán)境目錄。
假設(shè)你的虛擬環(huán)境名稱為 myenv
,你可以在命令行中執(zhí)行以下命令來刪除:
root@b3268f2479f8:/usr/local/env# rm -rf myenv/
請注意,這樣的刪除操作是不可逆的。刪除后,虛擬環(huán)境中的所有數(shù)據(jù)和安裝的包都將被永久移除。確保你刪除的是正確的虛擬環(huán)境路徑,以免不小心刪除了重要數(shù)據(jù)。
3.5、虛擬環(huán)境遷移部署
由于安裝在虛擬環(huán)境中的腳本不要求必須激活該虛擬環(huán)境,因此它們的“井號嘆號”行會包含虛擬環(huán)境的絕對路徑,如下圖:
這種情況下,虛擬環(huán)境是不可移植的。為確保便捷地重建虛擬環(huán)境,你應(yīng)當(dāng)提供簡便的方式(例如,若你已準備好需求文件 requirements.txt
,可使用虛擬環(huán)境的 pip
執(zhí)行 pip install -r requirements.txt
命令來安裝虛擬環(huán)境所需的所有軟件包)如下:
# 創(chuàng)建requirements.txt
(myenv) root@b3268f2479f8:/usr/local/env/myenv# pip freeze > requirements.txt
(myenv) root@b3268f2479f8:/usr/local/env/myenv# cat requirements.txt
certifi==2023.11.17
charset-normalizer==3.3.2
confluent-kafka==2.3.0
idna==3.6
requests==2.31.0
urllib3==2.1.0
如果因某種原因你需要將虛擬環(huán)境移動到新位置,你應(yīng)當(dāng)在目標(biāo)位置上重新創(chuàng)建虛擬環(huán)境,并刪除舊位置上的虛擬環(huán)境。同樣,如果你移動了虛擬環(huán)境的上級目錄,也應(yīng)在新位置上重新創(chuàng)建虛擬環(huán)境。否則,安裝在該虛擬環(huán)境中的軟件包可能無法正常運行。
舉例來說,假設(shè)你在 /usr/local/env/myenv
目錄下創(chuàng)建了一個虛擬環(huán)境,現(xiàn)在你想將它移動到 /usr/local/env/myenv2/
目錄。你可以執(zhí)行以下步驟:
-
在目標(biāo)位置上重建虛擬環(huán)境:
python3 -m venv /usr/local/env/myenv2 # 使用 venv 創(chuàng)建一個名為 myenv 的新虛擬環(huán)境
-
使用
requirements.txt
安裝所需的軟件包:cd /usr/local/env/myenv2 source bin/activate # 激活新的虛擬環(huán)境 pip install -r /usr/local/env/myenv/requirements.txt
這樣可以確保在新位置重新創(chuàng)建了虛擬環(huán)境,并安裝了相同的軟件包。移動虛擬環(huán)境時,務(wù)必謹慎操作以確保其中的軟件包能夠正常工作。
四、結(jié)語
Python虛擬環(huán)境是Python開發(fā)者不可或缺的利器。它為開發(fā)者提供了一個獨立、隔離的Python工作空間,使得不同項目之間的依賴管理更為靈活和高效。通過虛擬環(huán)境,開發(fā)者可以輕松地控制Python版本和安裝的庫,確保項目開發(fā)的穩(wěn)定性和可靠性。
五、相關(guān)資料
python虛擬環(huán)境官方文檔