使用微服務(wù)架構(gòu)部署應(yīng)用程序有幾個優(yōu)點:更容易進行主系統(tǒng)集成、更簡單的測試和可重用的代碼組件。 FastAPI 最近已成為 Python 中用于開發(fā)微服務(wù)的最流行的 web 框架之一。 FastAPI 比 Flask ( Python 中常用的 web 框架),因為它是基于 異步服務(wù)器網(wǎng)關(guān)接口( ASGI ) 而不是 Web 服務(wù)器網(wǎng)關(guān)接口( WSGI ) 。
什么是微服務(wù)
微服務(wù)定義了構(gòu)建軟件應(yīng)用程序的架構(gòu)和組織方法。微服務(wù)的一個關(guān)鍵方面是它們是分布式的,并且具有松散耦合。實現(xiàn)更改不太可能破壞整個應(yīng)用程序。
您還可以將使用微服務(wù)架構(gòu)構(gòu)建的應(yīng)用程序視為由幾個通過應(yīng)用程序編程接口( API )通信的小型獨立服務(wù)組成。通常,每個服務(wù)都由一個較小的、自包含的團隊擁有,負責(zé)在必要時實現(xiàn)更改和更新。
使用微服務(wù)的一個主要好處是,它們使團隊能夠快速為其應(yīng)用程序構(gòu)建新組件。這對于與不斷變化的業(yè)務(wù)需求保持一致至關(guān)重要。
另一個好處是它們使按需擴展應(yīng)用程序變得多么簡單。企業(yè)可以加快上市時間,以確保不斷滿足客戶需求。
微服務(wù)和整體服務(wù)的區(qū)別
單片是另一種軟件體系結(jié)構(gòu),它為設(shè)計軟件應(yīng)用程序提供了一種更傳統(tǒng)、統(tǒng)一的結(jié)構(gòu)。這里有一些不同之處。
微服務(wù)是解耦的
想想微服務(wù)如何將應(yīng)用程序分解為其核心功能。每個功能都稱為服務(wù),并執(zhí)行單個任務(wù)。
換句話說,服務(wù)可以獨立構(gòu)建和部署。這樣做的好處是,單個服務(wù)在不影響其他服務(wù)的情況下工作。例如,如果一項服務(wù)比其他服務(wù)的需求更大,則可以獨立擴展。
巨石是緊密耦合的
另一方面,整體架構(gòu)是緊密耦合的,并作為單個服務(wù)運行。缺點是,當(dāng)一個進程遇到需求高峰時,必須擴展整個應(yīng)用程序,以防止該進程成為瓶頸。由于單個進程故障會影響整個應(yīng)用程序,因此應(yīng)用程序停機的風(fēng)險也會增加。
對于單片架構(gòu),隨著代碼庫的增長,更新或向應(yīng)用程序添加新功能要復(fù)雜得多。這限制了實驗的空間。
何時使用微服務(wù)或巨石?
這些差異并不一定意味著微服務(wù)比單一服務(wù)更好。在某些情況下,使用單體仍然更有意義,例如構(gòu)建一個不需要太多業(yè)務(wù)邏輯、優(yōu)異的可伸縮性或靈活性的小型應(yīng)用程序。
然而,機器學(xué)習(xí)( ML )應(yīng)用程序通常是具有許多運動部件的復(fù)雜系統(tǒng),必須能夠擴展以滿足業(yè)務(wù)需求。通常需要為 ML 應(yīng)用程序使用微服務(wù)架構(gòu)。
包裝機器學(xué)習(xí)模型
在我深入了解用于此微服務(wù)的體系結(jié)構(gòu)的細節(jié)之前,有一個重要的步驟需要完成:模型打包。只有當(dāng) ML 模型的預(yù)測可以提供給最終用戶時,您才能真正實現(xiàn) ML 模型的價值。在大多數(shù)情況下,這意味著從筆記本電腦到腳本,以便將模型投入生產(chǎn)。
在本例中,將用于訓(xùn)練和預(yù)測新實例的腳本轉(zhuǎn)換為 Python 包。軟件包是編程的重要組成部分。沒有它們,大部分開發(fā)時間都浪費在重寫現(xiàn)有代碼上。
為了更好地理解包是什么,從腳本開始,然后介紹模塊要容易得多。
腳本:預(yù)期將直接運行的文件。每個腳本執(zhí)行都執(zhí)行開發(fā)人員定義的特定行為。創(chuàng)建腳本就像保存擴展名為.py 的文件以表示 Python 文件一樣簡單。
模塊:為導(dǎo)入其他腳本或模塊而創(chuàng)建的程序。一個模塊通常由幾個類和函數(shù)組成,這些類和函數(shù)用于其他文件。將模塊視為代碼的另一種方式是反復(fù)重用。
包可以被定義為相關(guān)模塊的集合。這些模塊以特定的方式相互作用,從而使您能夠完成任務(wù)。在 Python 中,包通常通過 PyPi 并且可以使用 pip ,一個 Python 包安裝程序。
圖 1 顯示了該模型的目錄結(jié)構(gòu)。

圖 1.模型的目錄結(jié)構(gòu)
包模塊包括以下內(nèi)容:
config.yml: YAML 文件以定義常量變量。
pipeline.py:執(zhí)行所有特征轉(zhuǎn)換和建模的管道。
predict.py:使用訓(xùn)練模型對新實例進行預(yù)測。
train_pipeline.py:進行模型培訓(xùn)。
版本:當(dāng)前版本。
config/core.py:用于解析 YAML 文件的模塊,以便可以在 Python 中訪問常量變量。
資料/:用于項目的所有數(shù)據(jù)。
模型/:經(jīng)過訓(xùn)練的序列化模型。
processing/data_manager.py:用于數(shù)據(jù)管理的實用功能。
processing/features.py:要在管道中使用的特征轉(zhuǎn)換。
processing/validation.py:數(shù)據(jù)驗證架構(gòu)。
該模型沒有針對這個問題進行優(yōu)化,因為本文的主要重點是展示如何使用微服務(wù)架構(gòu)構(gòu)建 ML 應(yīng)用程序。
現(xiàn)在該模型已經(jīng)準備好分發(fā),但存在一個問題。通過 PyPi 索引分發(fā)包意味著它可以在全球范圍內(nèi)訪問。對于模型中沒有業(yè)務(wù)價值的場景,這可能是可以的。然而,在真實的業(yè)務(wù)場景中,這將是一場徹底的災(zāi)難。
您可以使用第三方工具,如 Gemfury 完成此操作的步驟超出了本文的范圍。有關(guān)詳細信息,請參閱 安裝專用 Python 軟件包 。
圖 2 顯示了我的 Gemfury 存儲庫中的私有打包模型。我做了這個 用于演示目的的包公開 。

圖 2.Gemfury 存儲庫中的打包模型
微服務(wù)系統(tǒng)設(shè)計
在訓(xùn)練并保存模型后,您需要一種向最終用戶提供預(yù)測的方法。 RESTAPI 是實現(xiàn)這一目標的好方法。有幾種應(yīng)用程序架構(gòu)可用于集成 RESTAPI 。圖 3 顯示了我在本文中使用的嵌入式體系結(jié)構(gòu)。

圖 3.嵌入式方法的可視化表示
嵌入式體系結(jié)構(gòu)指的是一個系統(tǒng),其中訓(xùn)練的模型嵌入到 API 中并作為依賴項安裝。
在簡單性和靈活性之間有一個自然的權(quán)衡。嵌入式方法比其他方法簡單得多,但靈活性較差。例如,每當(dāng)進行模型更新時,必須重新部署整個應(yīng)用程序。如果你的服務(wù)是在手機上提供的,那么你必須發(fā)布新版本的軟件。
使用 FastAPI 構(gòu)建 API
構(gòu)建 API 時需要考慮的是依賴關(guān)系。您將不會創(chuàng)建虛擬環(huán)境,因為您正在使用運行應(yīng)用程序 tox ,這是一個命令行驅(qū)動的自動化測試工具,也用于通用 虛擬人 經(jīng)營因此,調(diào)用tox創(chuàng)建虛擬環(huán)境并運行應(yīng)用程序。
盡管如此,以下是依賴項。
--extra-index-url="https://repo.fury.io/kurtispykes/" car-evaluation-model==1.0.0 uvicorn>=0.18.2, <0.19.0 fastapi>=0.79.0, <1.0.0 python-multipart>=0.0.5, <0.1.0 pydantic>=1.9.1, <1.10.0 typing_extensions>=3.10.0, <3.11.0 loguru>=0.6.0, <0.7.0
如果在 PyPI 中找不到包,pip還有一個額外的索引,用于搜索包。這是到托管打包模型的 Gemfury 帳戶的公共鏈接,因此,您可以從 Gemfurry 安裝經(jīng)過訓(xùn)練的模型。這將是專業(yè)設(shè)置中的私有包,這意味著鏈接將被提取并隱藏在環(huán)境變量中。
另一件需要注意的事情是uvicorn.Uvicorn 是實現(xiàn) ASGI 接口的服務(wù)器網(wǎng)關(guān)接口。換句話說,它是一個專門的 web 服務(wù)器,負責(zé)處理入站和出站請求。它在Procfile中定義。
web: uvicorn app.main:app --host 0.0.0.0 --port $PORT
既然指定了依賴項,您就可以繼續(xù)查看實際的應(yīng)用程序了。 API 應(yīng)用程序的主要部分是main.py腳本:
from typing import Any from fastapi import APIRouter, FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse from loguru import logger from app.api import api_router from app.config import settings, setup_app_logging # setup logging as early as possible setup_app_logging(config=settings) app = FastAPI( title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json" ) root_router = APIRouter() @root_router.get("/") def index(request: Request) -> Any: """Basic HTML response.""" body = ( "" "" "Welcome to the API
" "" "Check the docs: here" "" "" "" ) return HTMLResponse(content=body) app.include_router(api_router, prefix=settings.API_V1_STR) app.include_router(root_router) # Set all CORS enabled origins if settings.BACKEND_CORS_ORIGINS: app.add_middleware( CORSMiddleware, allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) if __name__ == "__main__": # Use this for debugging purposes only logger.warning("Running in development mode. Do not run like this in production.") import uvicorn # type: ignore uvicorn.run(app, host="localhost", port=8001, log_level="debug")
如果你不能跟上,不要擔(dān)心。需要注意的關(guān)鍵是,主應(yīng)用程序中有兩個路由器:
-
root_router:此端點定義返回 HTML 響應(yīng)的主體。您幾乎可以將其視為稱為索引的主端點。 -
api_router:此端點用于指定允許其他應(yīng)用程序與 ML 模型交互的更復(fù)雜的端點。
深入了解api.py模塊以更好地理解api_router。首先,本模塊中定義了兩個端點:health和predict。
看看代碼示例:
@api_router.get("/health", response_model=schemas.Health, status_code=200)
def health() -> dict:
"""
Root Get
"""
health = schemas.Health(
name=settings.PROJECT_NAME, api_version=__version__, model_version=model_version
)
return health.dict()
@api_router.post("/predict", response_model=schemas.PredictionResults, status_code=200)
async def predict(input_data: schemas.MultipleCarTransactionInputData) -> Any:
"""
Make predictions with the Fraud detection model
"""
input_df = pd.DataFrame(jsonable_encoder(input_data.inputs))
# Advanced: You can improve performance of your API by rewriting the
# `make prediction` function to be async and using await here.
logger.info(f"Making prediction on inputs: {input_data.inputs}")
results = make_prediction(inputs=input_df.replace({np.nan: None}))
if results["errors"] is not None:
logger.warning(f"Prediction validation error: {results.get('errors')}")
raise HTTPException(status_code=400, detail=json.loads(results["errors"]))
logger.info(f"Prediction results: {results.get('predictions')}")
return results
health端點非常簡單。當(dāng)您訪問 web 服務(wù)器時,它返回模型的健康響應(yīng)模式(圖 4 )。您在schemas目錄中的health.py模塊中定義了此架構(gòu)。

圖 4.來自健康端點的服務(wù)器響應(yīng)
predict端點稍微復(fù)雜一些。以下是所涉及的步驟:
獲取輸入并將其轉(zhuǎn)換為 pandas 數(shù)據(jù)幀 : jsonable_encoder 返回的 JSON 兼容版本 pydantic model.
記錄輸入數(shù)據(jù)以進行審計。
使用 ML 模型的make_prediction函數(shù)進行預(yù)測。
捕獲模型產(chǎn)生的任何錯誤。
如果模型沒有錯誤,則返回結(jié)果。
通過從終端窗口使用以下命令啟動服務(wù)器,檢查所有功能是否正常:
py -m tox -e run
如果服務(wù)器正在運行,這將顯示多個日志,如圖 5 所示。

圖 5.顯示服務(wù)器正在運行的日志
現(xiàn)在,您可以導(dǎo)航到 http://localhost:8001 查看 API 的交互端點。
測試微服務(wù) API
導(dǎo)航到本地服務(wù)器將從main.py腳本轉(zhuǎn)到root_rooter中定義的索引端點。您可以通過在本地主機服務(wù)器 URL 的末尾添加/docs來獲得有關(guān) API 的更多信息。
例如,圖 6 顯示您已經(jīng)將predict端點創(chuàng)建為 POST 請求,health端點是 GET 請求。

圖 6.API 端點
首先,展開predict標題以接收有關(guān)端點的信息。在本標題中,您將看到請求主體中的一個示例。我在其中一個模式中定義了這個示例,以便您可以測試 API 。這超出了本文的范圍,但您可以瀏覽 模式代碼 。
要在請求體示例中嘗試該模型,請選擇試試看。

圖 7.使用微服務(wù)的示例預(yù)測
圖 7 顯示了模型返回的預(yù)測輸出類為 1 。在內(nèi)部,您知道 1 表示acc類值,但您可能希望在用戶界面中顯示時向用戶顯示該值。
下一步是什么?
恭喜您,您現(xiàn)在已經(jīng)為微服務(wù)構(gòu)建了自己的 ML 模型。接下來的步驟涉及部署它,以便它可以在生產(chǎn)中運行。
總而言之,微服務(wù)是一種架構(gòu)和組織設(shè)計方法,用于安排松散耦合的服務(wù)。在 ML 應(yīng)用程序中使用微服務(wù)方法的主要好處之一是獨立于主要軟件產(chǎn)品。擁有與主軟件產(chǎn)品分離的功能服務(wù)( ML 應(yīng)用程序)有兩個關(guān)鍵好處:
它使跨職能團隊能夠參與分布式開發(fā),從而加快部署速度。
軟件的可擴展性得到了顯著提高。
關(guān)于作者
Kurtis Pykes 是一位自學(xué)成才的機器學(xué)習(xí)實踐者,目前是一名自由職業(yè)者。
審核編輯:郭婷
-
python
+關(guān)注
關(guān)注
58文章
4881瀏覽量
90266
發(fā)布評論請先 登錄
使用阿里云ACM簡化你的Spring Cloud微服務(wù)環(huán)境配置管理
微服務(wù)架構(gòu)和CQRS架構(gòu)基本概念介紹
微服務(wù)網(wǎng)關(guān)gateway的相關(guān)資料推薦
java微服務(wù)生態(tài)系統(tǒng)模型解讀
微服務(wù)優(yōu)勢_微服務(wù)架構(gòu)的好處與不足
什么是微服務(wù)和容器?微服務(wù)和容器的作用是什么
什么是微服務(wù)架構(gòu)?
springcloud微服務(wù)架構(gòu)
docker微服務(wù)架構(gòu)實戰(zhàn)
設(shè)計微服務(wù)架構(gòu)的原則
如何構(gòu)建彈性、高可用的微服務(wù)?
使用FastAPI構(gòu)建機器學(xué)習(xí)微服務(wù)
評論