成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何快速創(chuàng)建一個擁有異步任務(wù)隊(duì)列集群的 Rest Api

開發(fā) 前端
本文分享如何使用 docker-compose、FastAPI、rq 來快速創(chuàng)建一個包含異步任務(wù)隊(duì)列集群的 REST API,后端執(zhí)行任務(wù)的節(jié)點(diǎn)可以隨意擴(kuò)展。

異步任務(wù)是 Web 后端開發(fā)中最常見的需求,非常適合多任務(wù)、高并發(fā)的場景。本文分享如何使用 docker-compose、FastAPI、rq 來快速創(chuàng)建一個包含異步任務(wù)隊(duì)列集群的 REST API,后端執(zhí)行任務(wù)的節(jié)點(diǎn)可以隨意擴(kuò)展。

系統(tǒng)的架構(gòu)圖:

上圖中的每一個方框都可以理解為一個服務(wù)器。

用戶請求 api, api 將任務(wù)放入 redis 隊(duì)列,worker 自動去 redis 隊(duì)列取出任務(wù)并執(zhí)行,worker 節(jié)點(diǎn)可以任意水平擴(kuò)展。

接下來,我們來實(shí)現(xiàn)這一架構(gòu)的 demo,你可以看到 docker 的強(qiáng)大和方便之處。

1、先創(chuàng)建一個虛擬環(huán)境,安裝依賴

依賴 fastapi,redis,rq 庫,安裝后生成一個 requirements.txt 文件

  1. mkdir myproject 
  2. python3 -m venv env 
  3. source env/bin/activate 
  4. pip install rq 
  5. pip install fastapi 
  6. pip install redis 
  7. pip freeze > requirements.txt 

2、編碼實(shí)現(xiàn) REST API、Worker

REST 是一種風(fēng)格,這里不是重點(diǎn),我們使用 FastAPI 來快速創(chuàng)建一個接口,新建一個 api.py 的文件,內(nèi)容如下:

  1. from fastapi import FastAPI 
  2. from redis import Redis 
  3. from rq import Queue 
  4. from worker import send_captcha 
  5. app = FastAPI() 
  6.  
  7. # 需要注意,這里的 host 是主機(jī)名,在 docker 中就是服務(wù)名,后面的 docker-compose.ymal 中的服務(wù)名稱也要是這個 
  8. redis_conn = Redis(host='myproj_redis', port=6379, db=0) 
  9.  
  10. # 定義一個隊(duì)列,名稱是 my_queue 
  11. q = Queue('my_queue'connection=redis_conn) 
  12.  
  13. @app.get('/hello'
  14. def hello(): 
  15.     """Test endpoint""" 
  16.     return {'hello''world'
  17.  
  18. # Rest API 示例 
  19. @app.post('/send_captcha/{phone_number}', status_code=201) 
  20. def addTask(phone_number: str): 
  21.     ""
  22.     Adds tasks to worker queue. 
  23.     Expects body as dictionary matching the Group class. 
  24.  
  25.     ""
  26.     job = q.enqueue(send_captcha, phone_number) 
  27.  
  28.     return {'job'"tasks add done."

這里的 send_captcha 函數(shù)就是一個異步任務(wù),從 worker.py 中導(dǎo)入,worker.py 的內(nèi)容如下:

  1. import time 
  2.  
  3. def send_captcha(phone_number): 
  4.     ""
  5.     模擬一個耗時的異步任務(wù) 
  6.     ""
  7.     print(f'{time.strftime("%T")} 準(zhǔn)備發(fā)送手機(jī)驗(yàn)證碼') # in place of actual logging 
  8.     print(f'{time.strftime("%T")} 生成隨機(jī)驗(yàn)證碼并存入 redis,設(shè)置 5 分鐘過期時間'
  9.     time.sleep(5) # simulate long running task 
  10.     print(f'{time.strftime("%T")} {phone_number}發(fā)送完成'
  11.     return { phone_number: 'task complete'

return { phone_number: 'task complete'}

3、構(gòu)建 Dokcer 鏡像

現(xiàn)在的目標(biāo)是實(shí)現(xiàn)一個擁有兩個執(zhí)行節(jié)點(diǎn)的集群。我們需要啟動 4 個容器來完成一個集群部署:

  • 容器1:運(yùn)行 FastAPI app
  • 容器2:運(yùn)行 Redis 服務(wù)
  • 容器3:運(yùn)行 worker 1 服務(wù)
  • 容器4:運(yùn)行 worker 2 服務(wù)

其中容器 1、3、4 都是 Python 應(yīng)用,可以共用一個 Python 鏡像。

為了方便調(diào)試,我們可以讓 1、3、4 容器共享我們的本地路徑,這樣改了代碼就不需要重新構(gòu)建鏡像,比較方便。

創(chuàng)建一個包含依賴的 Python 鏡像

現(xiàn)在我們來創(chuàng)建一個包含前文 requirements.txt 依賴的 Python 鏡像,編寫 Dockerfile,內(nèi)容如下:

  1. FROM python:3.8-alpine 
  2. RUN adduser -D myproj 
  3. WORKDIR /home/myproj 
  4. COPY requirements.txt requirements.txt 
  5. RUN pip install -r requirements.txt 
  6. RUN chown -R myproj:myproj ./ 
  7. USER myproj 
  8. CMD uvicorn api:app --host 0.0.0.0 --port 5057 

內(nèi)容說明:

FROM python:3.8-alpine

指定使用 python:3.8-alpine,這個容器已經(jīng)預(yù)裝了 Python3.8,可以在命令行執(zhí)行 docker search python 看看有哪些 Python 鏡像。

RUN adduser -D myproj

添加一個用戶 myproj,這一步的主要目的是為了生成目錄 /home/myproj

WORKDIR /home/myproj

設(shè)置程序的執(zhí)行路徑為 /home/myproj

COPY requirements.txt requirements.txt

復(fù)制當(dāng)前路徑下的 requirements.txt 到容器的 /home/myproj,這里沒有復(fù)制 .py 文件是因?yàn)楹竺嫖覀儐尤萜鞯臅r候會共享本地路徑,不需要再復(fù)制了,生產(chǎn)部署時最好復(fù)制到窗口內(nèi)部,這樣容器就不會依賴本機(jī)。

RUN pip install -r requirements.txt

在容器中安裝依賴

RUN chown -R myproj:myproj ./

將 /home/myproj 路徑下的文件的擁有者和所屬組改為 myproj,這一步為了使用 myproj 用戶來啟動 fastapi 服務(wù),生產(chǎn)環(huán)境通常用 root 用戶啟動,也就不需要這個指令了。

USER myproj

切換到 myproj 用戶

CMD uvicorn api:app --host 0.0.0.0 --port 5057

容器啟動后執(zhí)行的命令,服務(wù)端口為 5057

更多的 Dockerfile 語法請參考官方文檔,這里僅是簡要說明。

現(xiàn)在 Dockerfile 所在的目錄執(zhí)行下面的命令構(gòu)建一個鏡像:

  1. docker build -t myproject:latest . 

創(chuàng)建完成后,可以使用 docker images 來查看:

  1. ❯ docker images | grep myproj 
  2. myproject               

4、啟動集群

這里使用 Docker Compose 來啟動 4 個容器,為什么用 Docker Compose 呢?因?yàn)榉奖悖绻挥玫脑挘枰謩右粋€容器一個容器啟動。

Docker Compose 會讀取一個 yaml 格式的配置文件,依據(jù)配置文件來啟動容器,各容器共享同一網(wǎng)絡(luò)。還記得 api.py 中使用的 Redis 主機(jī)名嗎,這里就需要將 redis 服務(wù)名設(shè)置為那個主機(jī)名。

編寫一個 docker-compose.yml 內(nèi)容如下:

  1. version: '3' 
  2.  
  3. services: 
  4.   myproj_redis: 
  5.     image: redis:4.0-alpine 
  6.     ports: 
  7.       - "6379:6379" 
  8.     volumes: 
  9.       - ./redis:/data 
  10.  
  11.   myproj_api: 
  12.     image: myproject:latest 
  13.     command: uvicorn api:app --host 0.0.0.0 --port 5057 
  14.     ports: 
  15.       - "5057:5057" 
  16.     volumes: 
  17.       - ./:/home/myproj 
  18.  
  19.   myproj_worker1: 
  20.     image: myproject:latest 
  21.     command: rq worker --url redis://myproj_redis:6379 my_queue 
  22.     volumes: 
  23.       - ./:/home/myproj 
  24.  
  25.   myproj_worker2: 
  26.     image: myproject:latest 
  27.     command: rq worker --url redis://myproj_redis:6379 my_queue 
  28.     volumes: 
  29.       - ./:/home/myproj 

第一個容器是 myproj_redis,運(yùn)行著 redis 服務(wù), redis 的數(shù)據(jù)通過 volumes 方式保存在本地,因此需要在本地創(chuàng)建一個 redis 目錄,來映射容器內(nèi)部的 /data 目錄。

第二個容器就是 fastapi 服務(wù),端口 5057,使用本地路徑映射為 /home/myproj

第三個容器和第四個容器是 worker 節(jié)點(diǎn),雖然也映射了本地路徑,但它僅使用 worker.py 文件。當(dāng)任務(wù)太多時,worker 節(jié)點(diǎn)可以擴(kuò)展,解決負(fù)載壓力,

最終的目錄是這樣:

執(zhí)行 docker compose 命令啟動 4 個容器:

  1. docker compose -f docker-compose.yml up 

可以看到 4 個服務(wù)均啟動并正常打印了日志輸出。

4、測試

現(xiàn)在來測試一下,左邊的窗口,我使用 Python 快速發(fā)送了 3 個 post 請求:

  1. import subprocess 
  2. for i in range(3): 
  3.     subprocess.run("curl -v -X POST 'http://localhost:5057/send_captcha/18012345678'",shell = True

從右邊窗口的日志輸出可以看出 worker1 和 worker2 都執(zhí)行了任務(wù),其中 worker1 執(zhí)行了 2 個,worker2 執(zhí)行了 1 個。

查看完整代碼請點(diǎn)擊「閱讀原文」

最后的話

本文分享了如何使用 Dockerfile 構(gòu)建一個鏡像,使用 Docker Compose 管理一個容器集群,以此為基礎(chǔ)實(shí)現(xiàn)了一個具有異步任務(wù)隊(duì)列集群的 REST API,拋磚引玉,關(guān)于 Dockerfile、docker-compose 的詳細(xì)用法,還請參考 Docker 官方文檔

 

責(zé)任編輯:武曉燕 來源: Python七號
相關(guān)推薦

2023-08-01 07:25:38

Expresso框架API

2021-08-10 07:27:42

Elasticsear集群開源

2023-11-19 20:16:43

RESTAPIPOST

2023-04-10 14:20:47

ChatGPTRESTAPI

2020-10-28 17:15:45

Redis前端數(shù)據(jù)庫

2010-03-08 16:36:53

攻略備案域名注冊淘寶網(wǎng)

2020-09-29 07:24:14

Python字典數(shù)據(jù)

2024-05-23 11:26:02

2013-07-01 11:01:22

API設(shè)計(jì)API

2024-10-14 08:46:50

Controller開發(fā)代碼

2023-05-11 12:40:00

Spring控制器HTTP

2024-01-02 13:58:04

GoREST API語言

2020-08-25 07:48:17

Kubernetes集群系統(tǒng)

2023-08-14 09:00:00

APIgRPCREST

2020-09-22 07:50:23

API接口業(yè)務(wù)

2018-06-19 16:04:27

Dubbo應(yīng)用Java

2023-03-01 09:39:40

調(diào)度系統(tǒng)

2019-11-11 10:45:44

LinuxWindows 10Debian 10

2013-05-02 10:40:24

xcode

2021-05-27 09:50:03

連接池FTP服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 神马影院一区二区三区 | 天天艹逼网 | 国产精品成人一区二区三区 | 精品久久久久久久久久久 | 高清成人av | 成人毛片在线视频 | 亚洲欧美综合网 | 男女羞羞免费网站 | 成人国产精品一级毛片视频毛片 | 激情久久网 | 国产视频中文字幕 | 日韩色视频 | 范冰冰一级做a爰片久久毛片 | 中文字幕av在线 | 欧美久久视频 | 精品欧美一区二区三区久久久 | 午夜在线观看免费 | 亚洲精品乱码久久久久久按摩观 | 中文字幕视频在线观看 | 国产一区二区三区免费观看视频 | 亚洲欧美中文字幕在线观看 | 中文字幕免费在线观看 | 欧美性网 | av免费网站在线观看 | 一区二区三区久久久 | 欧美成人精品一区 | 色妞av| 欧美精品中文字幕久久二区 | 欧美日韩一卡二卡 | 午夜视频网站 | 久久大陆 | 精品欧美一区二区三区久久久 | 一区二区中文 | 在线一级片 | 97超碰中文网 | 国产免费看 | 在线成人一区 | 神马久久久久久久久久 | 黄色片网此 | 中文字幕av免费 | 欧美精品久久久 |