在現代軟體開發中,非同步任務處理對於提升應用程式效能至關重要。本文示範如何利用 Python RQ 函式庫建立非同步任務佇列,並結合 Docker Compose 協調 PostgreSQL、Redis 和 Jupyter Notebook 等服務,實作一個完整的目標編碼非同步處理流程。程式碼範例中,我們首先使用 Python 連線 PostgreSQL 資料函式庫,擷取待處理資料的 ID。接著,利用 RQ 將目標編碼任務送入 Redis 佇列,並由 Worker 程式非同步執行。同時,我們使用 Docker Compose 管理多個容器,確保開發環境的一致性,並透過 Jupyter Notebook 進行互動式開發與除錯。最後,我們使用 Git 進行版本控制,方便團隊協作和程式碼管理。
第10章 ■ 互動式軟體開發
更新Python模組
在圖10-15中,您使用Jupyter Notebook伺服器導航到lib/目錄,然後在lib/內選擇您的postgres.py檔案以更新模組。接下來,您將清單10-74中的程式碼新增到檔案中,如圖10-16所示。請注意,當所有目前的變更都已儲存時,文字檔案名稱旁邊將出現勾選標記,如圖10-17所示。
圖10-15:開啟postgres.py進行編輯
圖10-16:最新版本的postgres.py
圖10-17:postgres.py的所有變更已儲存
接下來,您將建立一個新的筆記本,以使用encode_target函式透過延遲作業系統統對adult表格中的所有列進行編碼。您建立了一個名為20170619-Encode_target.ipynb的新筆記本。在清單10-77中,您從專案根目錄設計模式開始。在清單10-78中,您從lib.postgres匯入所需的函式。
清單10-77:專案根目錄設計模式
from os import chdir
chdir('/home/jovyan')
清單10-78:從lib.postgres匯入函式
from lib.postgres import connect_to_postgres, encode_target
在清單10-79中,您看到一個新的設計模式,即從rq函式庫例項化一個佇列(Queue)。佇列使用與特定Redis伺服器的連線進行例項化。和之前一樣,您使用由Docker Compose建立的網路上的Redis服務名稱this_redis。
清單10-79:建立與Redis的連線和新的佇列
from redis import Redis
from rq import Queue
REDIS = Redis(host='this_redis')
Q = Queue(connection=REDIS)
在清單10-80中,您將所有部分組合在一起。您建立了一個新的與PostgreSQL的連線。使用for迴圈從adult表格中提取100個尚未編碼目標值的列的_id。對於每個列,您使用.enqueue()函式將encode_target函式與相關的_id新增到作業佇列中。請注意,要傳遞給encode_target的引數(即_id)作為第二個引數傳遞給.enqueue()。
清單10-80:將100個目標編碼請求新增到佇列
con, cur = connect_to_postgres()
for _ in range(100):
cur.execute("""SELECT _id FROM adult WHERE target IS NULL;""")
this_id, = cur.fetchone()
Q.enqueue(encode_target, this_id)
con.close()
在至少一次執行此儲存格期間(您需要多次執行此儲存格以編碼整個表格,除非進行修改),建議使用根據瀏覽器的監控器,以及“追蹤”Docker Compose日誌,以觀察Worker如何處理這些函式。根據瀏覽器的監控器將在與您的Jupyter Notebook伺服器相同的IP地址上可用,但將在5000埠上可用(圖10-18)。清單10-81顯示了使用--follow旗標“追蹤”Docker Compose日誌。每個作業程式將在執行時透過此日誌傳遞。
清單10-81:追蹤Docker Compose日誌
$ docker-compose logs --follow this_worker
...
this_worker_1 | 01:43:04 *** Listening on default...
this_worker_1 | 01:43:04 default: lib.postgres.encode_target(24) (914a8229-a876-438f-98d4-d6cd39a469b2)
this_worker_1 | 01:43:04 default: Job OK (914a8229-a876-438f-98d4-d6cd39a469b2)
this_worker_1 | 01:43:04 Result is kept for 500 seconds
...
最後,您使用git跟蹤工作。在清單10-82中,您檢查專案的狀態。在清單10-83中,您新增並提交所有最近的工作。
清單10-82:檢查專案狀態
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/postgres.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
ipynb/20170619-Develop_encoding_target_function.ipynb
ipynb/20170619-Encode_target.ipynb
no changes added to commit (use "git add" and/or "git commit -a")
清單10-83:新增所有檔案並提交
$ git add -A
$ git commit -m 'function and queueing for target encoding'
[master 93f3033] function and queueing for target encoding
3 files changed, 319 insertions(+)
create mode 100644 ipynb/20170619-Develop_encoding_target_function.ipynb
create mode 100644 ipynb/20170619-Encode_target.ipynb
在清單10-84中,您顯示目前專案的狀態。
清單10-84:目前專案狀態
$ tree
.
├── data
│ └── adult.data
├── docker
│ ├── jupyter
│ │ └── Dockerfile
│ └── postgres
│ ├── Dockerfile
│ ├── get_data.sh
│ └── initdb.sql
├── docker-compose.yml
├── ipynb
│ ├── 20170611-Examine_Database_Requirements.ipynb
│ ├── 20170613-Initial_Database_Connection.ipynb
│ ├── 20170613-Verify_Database_Connection.ipynb
│ ├── 20170619-Develop_encoding_target_function.ipynb
│ └── 20170619-Encode_target.ipynb
└── lib
├── __init__.py
├── postgres.py
└── __pycache__
├── __init__.cpython-35.pyc
└── postgres.cpython-35.pyc
索引
(索引內容略)
程式碼解析:
-
資料函式庫連線與操作
- 使用
connect_to_postgres()函式建立與 PostgreSQL 資料函式庫的連線。 cur.execute()用於執行 SQL 查詢,例如選擇、更新資料表中的資料。
- 使用
-
佇列處理
- 從
rq函式庫匯入Queue,並使用 Redis 作為後端來處理任務佇列。 - 將任務
encode_target新增到佇列中,並傳遞_id作為引數。
- 從
-
Git 版本控制
- 使用
git status檢視當前專案狀態。 git add -A將所有變更的檔案新增到暫存區。git commit -m 'message'提交變更並新增提交訊息。
- 使用
-
專案結構
- 使用
tree命令顯示專案目錄結構,清晰展示各檔案和目錄的分佈。
- 使用
此程式碼實作了一個完整的互動式軟體開發流程:
- 模組更新:修改
postgres.py檔案以新增目標編碼功能。 - 任務佇列:利用 Redis 和 RQ 建立任務佇列,將目標編碼任務非同步處理。
- 版本控制:使用 Git 跟蹤所有變更,確保程式碼的可維護性和可追溯性。
- 專案結構管理:清晰展示專案的目錄結構,方便管理和擴充套件。
Docker 技術深度解析與實務應用
前言
Docker 是一種革命性的容器化技術,能夠大幅簡化應用程式的佈署和管理流程。本篇文章將探討 Docker 的核心概念、技術原理及其在實際開發中的應用。
Docker 基礎架構與元件
Docker 引擎
Docker 引擎是整個 Docker 生態系統的核心,負責容器的建立、執行和管理。它具備以下關鍵功能:
- 容器生命週期管理:建立、啟動、停止和刪除容器
- 映像檔管理:提取、推播和管理 Docker 映像檔
- 網路管理:提供容器間的網路通訊功能
Docker 映像檔與容器
Docker 映像檔是一個唯讀的範本,用於建立容器。容器則是映像檔的執行例項,具有以下特點:
- 輕量級虛擬化:與傳統虛擬機器相比,容器共用主機作業系統核心,因此更為輕量和高效。
- 快速佈署:容器可以在幾秒鐘內啟動,大幅提高了佈署效率。
- 環境一致性:確保開發、測試和生產環境的一致性,減少了「在我的機器上可以執行」的問題。
Docker Compose:多容器應用程式管理
Docker Compose 簡介
Docker Compose 是一個用於定義和執行多容器 Docker 應用程式的工具。它使用 YAML 檔案來組態應用程式的服務、網路和資料卷,從而簡化了複雜應用程式的佈署和管理。
Docker Compose 的主要功能
- 服務定義:在
docker-compose.yml檔案中定義應用程式的各個服務及其組態。 - 一鍵佈署:使用
docker-compose up命令即可啟動所有服務。 - 網路管理:自動為服務建立網路,實作服務間的通訊。
- 資料持久化:支援資料卷的掛載,確保資料持久化儲存。
Docker 在資料儲存技術中的應用
MongoDB 與 Docker
MongoDB 是一種流行的 NoSQL 資料函式庫,能夠與 Docker 無縫整合。以下是使用 Docker 佈署 MongoDB 的步驟:
- 提取 MongoDB 映像檔:使用
docker pull mongo命令下載官方 MongoDB 映像檔。 - 建立並執行 MongoDB 容器:使用
docker run -d --name mongodb mongo命令建立並在背景執行 MongoDB 容器。 - 資料持久化:使用資料卷將 MongoDB 資料持久化儲存,例如:
docker run -d --name mongodb -v /path/to/data:/data/db mongo。
PostgreSQL 與 Docker
PostgreSQL 是一種強大的開源關聯式資料函式庫,同樣能夠與 Docker 整合使用。以下是使用 Docker 佈署 PostgreSQL 的步驟:
- 提取 PostgreSQL 映像檔:使用
docker pull postgres命令下載官方 PostgreSQL 映像檔。 - 建立並執行 PostgreSQL 容器:使用
docker run -d --name postgresql -e POSTGRES_PASSWORD=mysecretpassword postgres命令建立並在背景執行 PostgreSQL 容器。 - 連線 PostgreSQL 資料函式庫:使用
psql或其他資料函式庫客戶端工具連線到正在執行的 PostgreSQL 容器。
Jupyter Notebook 與 Docker
Jupyter Notebook 是一種流行的互動式計算環境,能夠與 Docker 結合使用,提供一致且可重現的資料科學工作流程。
使用 Docker 佈署 Jupyter Notebook
- 提取 Jupyter Notebook 映像檔:使用
docker pull jupyter/scipy-notebook命令下載官方 Jupyter Notebook 映像檔。 - 建立並執行 Jupyter Notebook 容器:使用
docker run -p 8888:8888 jupyter/scipy-notebook命令建立並執行 Jupyter Notebook 容器,並將容器的 8888 連線埠對映到主機的 8888 連線埠。 - 存取 Jupyter Notebook:在瀏覽器中存取
http://localhost:8888以使用 Jupyter Notebook。
Dockerfile 最佳實踐
編寫高效的 Dockerfile
- 最小化層數:合併多個
RUN命令以減少映像檔層數,提高構建效率。 - 利用快取:將不常變化的指令放在前面,以充分利用 Docker 的快取機制。
- 使用官方基礎映像檔:選擇官方維護的基礎映像檔,以確保安全性和穩定性。
範例:建立自訂的 Python 環境
# 使用官方 Python 映像檔作為基礎
FROM python:3.9-slim
# 設定工作目錄
WORKDIR /app
# 複製 requirements.txt
COPY requirements.txt .
# 安裝依賴套件
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼
COPY . .
# 設定環境變數
ENV PYTHONUNBUFFERED=1
# 暴露應用程式連線埠
EXPOSE 8000
# 設定啟動命令
CMD ["python", "app.py"]
程式碼範例說明:
上述 Dockerfile 程式碼展示瞭如何建立一個自訂的 Python 環境,包括設定工作目錄、安裝依賴套件、複製應用程式碼以及設定環境變數和啟動命令。這種方法確保了應用程式在不同環境中的一致性和可重現性。
隨著雲原生技術的發展,Docker 將繼續演進,提供更多創新功能和最佳實踐,以滿足不斷變化的軟體開發需求。開發人員應持續關注最新的 Docker 功能和技術趨勢,以充分利用其強大的容器化能力。