在現今軟體開發流程中,延遲任務處理已成為不可或缺的一環。本文將逐步示範如何利用 Docker Compose 建構一個包含 Jupyter 開發環境、PostgreSQL 資料函式庫以及 Redis 任務佇列的延遲任務處理系統。首先,我們會建立一個 Python 模組來連線 PostgreSQL 資料函式庫,並將其封裝成可重複使用的函式。接著,我們會使用 Docker Compose 定義和管理多個服務,包含 Jupyter、PostgreSQL、Redis、Worker 和 Monitor。Worker 服務負責處理 Redis 佇列中的任務,而 Monitor 服務則提供一個視覺化介面來監控任務佇列的狀態。最後,我們會示範如何更新 Jupyter Docker 映像檔以安裝必要的套件,例如 psycopg2、Redis 和 RQ,以及如何使用 Git 進行版本控制,確保程式碼的變更得到妥善管理。透過本文的實作步驟,讀者將能快速建立一個功能完善的延遲任務處理系統,並學習如何有效地管理和維護這個系統。
互動式軟體開發
建立 PostgreSQL 連線模組
在互動式軟體開發過程中,將常用的程式碼抽象化成函式是非常重要的步驟。以下展示如何建立一個用於連線 PostgreSQL 資料函式庫的 Python 模組。
程式碼實作
首先,在 Jupyter Notebook 中定義一個函式來連線 PostgreSQL 資料函式庫。
import psycopg2 as pg2
def connect_to_postgres():
"""連線到 PostgreSQL 資料函式庫並傳回連線物件與遊標"""
con = pg2.connect(host='this_postgres', user='postgres', database='postgres')
return con, con.cursor()
驗證函式功能
接下來,驗證 connect_to_postgres 函式是否能夠正確連線資料函式庫並執行查詢。
con, cur = connect_to_postgres()
cur.execute("SELECT COUNT(*) FROM adult;")
print(cur.fetchall())
con.close()
輸出結果應為資料函式庫中 adult 表的記錄數。
將函式加入外部 Python 模組
將 connect_to_postgres 函式加入到一個名為 lib.postgres 的 Python 模組中,以便在其他指令碼中重複使用。
# lib/postgres.py
import psycopg2 as pg2
def connect_to_postgres():
"""連線到 PostgreSQL 資料函式庫並傳回連線物件與遊標"""
con = pg2.connect(host='this_postgres', user='postgres', database='postgres')
return con, con.cursor()
在新 Notebook 中測試模組功能
建立一個新的 Jupyter Notebook,並匯入 lib.postgres 模組來測試其功能。
import lib.postgres as psql
con, cur = psql.connect_to_postgres()
cur.execute("SELECT COUNT(*) FROM bc_data;")
print(cur.fetchall())
con.close()
使用 Git 跟蹤專案變更
最後,使用 Git 記錄專案的變更。
git status
git add -A
git commit -m 'initial database connection'
擴充套件應用程式以支援延遲任務處理
為了增強應用程式的功能,將新增 Redis 服務以及兩個根據 Jupyter 映像的額外服務:Worker 服務和 Monitor 服務。Redis 將作為延遲任務處理系統的基礎設施。
更新 docker-compose.yml 檔案
在 docker-compose.yml 檔案中新增 Redis、Worker 和 Monitor 服務的定義。
version: '3'
services:
this_jupyter:
build: docker/jupyter
ports:
- "8888:8888"
volumes:
- .:/home/jovyan
this_postgres:
build: docker/postgres
volumes:
- postgres_data:/var/lib/postgresql/data
this_redis:
image: redis
volumes:
- redis_data:/data
this_worker:
build: docker/jupyter
volumes:
- .:/home/jovyan
entrypoint: ["tini", "--", "rqworker", "-u", "redis://this_redis:6379"]
this_monitor:
build: docker/jupyter
volumes:
- .:/home/jovyan
ports:
- "5000:5000"
entrypoint: ["tini", "--", "rq-dashboard", "-H", "this_redis", "-p", "5000"]
volumes:
postgres_data:
redis_data:
更新 Jupyter Dockerfile
更新 Jupyter Dockerfile 以包含支援 Worker 和 Monitor 服務所需的函式庫。
# docker/jupyter/Dockerfile
# ... 其他指令 ...
# 安裝必要的函式庫
RUN pip install rq rq-dashboard
啟動服務並驗證功能
啟動所有服務,並驗證 Worker 和 Monitor 服務是否正常運作。
docker-compose up --build
透過上述步驟,成功地將延遲任務處理功能整合到應用程式中,並使用 Redis、Worker 和 Monitor 服務來管理和監控任務佇列。### 詳細解說:使用 Docker Compose 建立多服務應用程式
在前面的章節中,我們已經成功建立了一個用於連線 PostgreSQL 資料函式庫的 Python 模組,並將其整合到我們的專案中。現在,我們將進一步擴充套件我們的應用程式,以支援延遲任務處理功能。這需要新增 Redis 服務以及兩個額外的服務:Worker 和 Monitor。
使用 Docker Compose 定義多服務架構
Docker Compose 提供了一種簡便的方式來定義和執行多個 Docker 容器的應用程式。在我們的專案中,我們將使用 Docker Compose 來定義四個主要服務:Jupyter、PostgreSQL、Redis、Worker 和 Monitor。
docker-compose.yml 組態詳解
version: '3'
services:
this_jupyter:
build: docker/jupyter
ports:
- "8888:8888"
volumes:
- .:/home/jovyan
this_postgres:
build: docker/postgres
volumes:
- postgres_data:/var/lib/postgresql/data
this_redis:
image: redis
volumes:
- redis_data:/data
this_worker:
build: docker/jupyter
volumes:
- .:/home/jovyan
entrypoint: ["tini", "--", "rqworker", "-u", "redis://this_redis:6379"]
this_monitor:
build: docker/jupyter
volumes:
- .:/home/jovyan
ports:
- "5000:5000"
entrypoint: ["tini", "--", "rq-dashboard", "-H", "this_redis", "-p", "5000"]
volumes:
postgres_data:
redis_data:
詳細解說:docker-compose.yml 中的關鍵組態
this_jupyter服務:- 使用
docker/jupyter目錄中的 Dockerfile 建立映像。 - 將主機的8888埠對映到容器的8888埠,以便存取 Jupyter Notebook。
- 將當前目錄掛載到容器的
/home/jovyan目錄,實作程式碼與資料的持久化。
- 使用
this_postgres服務:- 使用
docker/postgres目錄中的 Dockerfile 建立 PostgreSQL 資料函式庫映像。 - 將
postgres_data卷掛載到容器的/var/lib/postgresql/data目錄,確保資料函式庫資料的持久化。
- 使用
this_redis服務:- 直接使用官方的 Redis 映像。
- 將
redis_data卷掛載到容器的/data目錄,用於儲存 Redis 資料。
this_worker和this_monitor服務:- 這兩個服務都根據與
this_jupyter相同的 Dockerfile 建立映像。 this_worker使用rqworker命令來處理 Redis 中的任務佇列。this_monitor使用rq-dashboard命令來提供一個 Web 介面,用於監控 Redis 中的任務佇列狀態。- 這兩個服務都使用了
tini作為入口點,以確保容器內部程式的管理更加穩健。
- 這兩個服務都根據與
使用 Docker Compose 建立和管理多容器應用程式
詳細步驟和最佳實踐
建立 Docker Compose 組態檔案
- 在專案根目錄下建立
docker-compose.yml檔案。 - 定義所需的服務,包括 Jupyter Notebook、PostgreSQL、Redis、Worker 和 Monitor。
- 在專案根目錄下建立
組態各個服務
- 為每個服務指定適當的映像或建置上下文。
- 組態埠對映和資料卷,以實作資料持久化和方便除錯。
構建和啟動應用程式
docker-compose up --build使用上述命令構建映像並啟動所有服務。如果只需要啟動服務而不重新構建映像,可以省略
--build選項。管理應用程式生命週期
- 使用
docker-compose stop命令停止所有正在執行的服務。 - 使用
docker-compose rm命令刪除已停止的容器。 - 使用
docker-compose logs檢視各個服務的日誌輸出,便於除錯和監控。
- 使用
擴充套件和更新應用程式
- 修改
docker-compose.yml檔案以新增或修改服務組態。 - 使用
docker-compose up --build命令重新構建和啟動更新後的應用程式。
- 修改
詳細解說:使用 Docker Compose 的最佳實踐
版本控制
- 將
docker-compose.yml檔案納入版本控制系統(如 Git),以跟蹤變更歷史和協同開發。
- 將
環境變數管理
- 利用 Docker Compose 的環境變數替換功能,將敏感資訊(如資料函式庫密碼)儲存在
.env檔案中,避免直接寫入組態檔案。
- 利用 Docker Compose 的環境變數替換功能,將敏感資訊(如資料函式庫密碼)儲存在
日誌管理和監控
- 組態適當的日誌驅動程式,以便收集和分析各個容器的日誌資料。
- 利用監控工具(如 Prometheus 和 Grafana)對應用程式效能進行監控和分析。
安全性考慮
- 確保容器內的程式以非 root 使用者身份執行,以降低安全風險。
- 利用 Docker 的網路功能,限制不同服務之間的通訊,以增強安全性。
持續整合/持續佈署(CI/CD)
- 將 Docker Compose 與 CI/CD 管道整合,實作自動化的測試、構建和佈署流程,提高開發效率和品質。
透過遵循上述最佳實踐,可以充分發揮 Docker Compose 在多容器應用程式管理方面的優勢,提高開發效率、確保應用程式穩定性和安全性,並簡化佈署流程。
互動式軟體開發的最佳實踐與實作
在現代軟體開發過程中,互動式開發已成為一種重要的開發模式。本章節將探討如何利用互動式開發來提升軟體開發的效率和品質,並以實際案例來說明其應用。
Docker 環境組態與管理
在進行互動式軟體開發時,Docker 提供了一個強大的容器化環境,能夠有效地隔離和管理不同服務之間的依賴關係。
更新 Jupyter Docker 映像檔
首先,我們需要更新 docker/jupyter/Dockerfile 以安裝必要的套件。
# 使用官方的 Jupyter SciPy 映像檔作為基礎映像檔
FROM jupyter/scipy-notebook
# 切換到 root 使用者以安裝套件
USER root
# 安裝 psycopg2 和 Redis 相關套件
RUN conda install --yes --name root psycopg2
RUN conda install --yes --name root redis rq
# 安裝 rq-dashboard
RUN ["bash", "-c", "source activate root && pip install rq-dashboard"]
# 切換回預設的 jovyan 使用者
USER jovyan
內容解密:
- 基礎映像檔選擇:使用
jupyter/scipy-notebook作為基礎映像檔,能夠直接獲得 Jupyter Notebook 環境和 SciPy 相關的科學計算套件。 - 切換使用者:使用
USER root切換到 root 使用者,以取得安裝套件的許可權。 - 安裝必要套件:使用
conda安裝psycopg2(用於連線 PostgreSQL 資料函式庫)和redis、rq(用於處理非同步任務)。 - 安裝 rq-dashboard:使用
pip安裝rq-dashboard,以提供一個視覺化的介面來監控 RQ 任務佇列。 - 切換回 jovyan 使用者:完成安裝後,切換回預設的
jovyan使用者,以保持安全性。
專案結構與 Docker Compose 管理
本專案採用 Docker Compose 來管理和協調多個服務,包括 Jupyter Notebook、PostgreSQL 資料函式庫和 Redis 伺服器。
檢視專案結構
使用 tree 命令可以檢視目前的專案結構。
$ 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
└── lib
├── __init__.py
├── postgres.py
└── __pycache__
├── __init__.cpython-35.pyc
└── postgres.cpython-35.pyc
內容解密:
- 專案結構:專案被組織成多個目錄,分別用於存放資料、Docker 相關設定、Jupyter Notebook 和 Python 函式庫。
docker-compose.yml:定義了多個服務之間的關係和組態,是啟動整個專案的關鍵檔案。
啟動與管理服務
使用 Docker Compose 可以輕鬆地啟動和管理多個服務。
啟動服務
$ docker-compose up -d --build
檢視執行中的容器
$ docker-compose ps
內容解密:
docker-compose up -d --build:使用--build引數強制重新建構映像檔,並在背景啟動所有服務。docker-compose ps:檢視目前執行中的容器及其狀態。
除錯與日誌管理
在開發過程中,除錯是不可或缺的一環。Docker Compose 提供了方便的日誌管理功能。
檢視特定服務的日誌
$ docker-compose logs this_monitor
$ docker-compose logs this_worker
內容解密:
docker-compose logs:用於檢視指定服務的日誌輸出,有助於除錯和監控服務狀態。
版本控制與變更管理
在開發過程中,使用 Git 來管理程式碼變更是非常重要的。
提交變更
$ git add -A
$ git commit -m 'add delayed job system'
內容解密:
git add -A:將所有變更新增到 Git 索引中。git commit -m 'add delayed job system':提交變更並新增描述訊息。
擴充套件 PostgreSQL 模組
在互動式開發過程中,我們可能會需要擴充套件現有的模組或功能。例如,編寫一個函式來編碼目標變數。
編碼目標變數
首先,在 Jupyter Notebook 中開發和測試函式。
def encode_target(_id):
"""為單一行編碼目標變數為布林值。接受一個行 _id。"""
con, cur = connect_to_postgres()
# ... 省略實作細節 ...
con.close()
將函式移到模組中
將測試透過的函式移到 lib/postgres.py 模組中,以便重複使用。
將函式傳遞給工作執行緒
透過任務佇列將函式傳遞給工作執行緒執行。
內容解密:
- 互動式開發:在 Jupyter Notebook 中進行互動式開發,可以快速測試和驗證想法。
- 模組化:將可重複使用的程式碼抽象成函式,並放入適當的模組中。
- 非同步處理:透過任務佇列,將耗時的任務交由工作執行緒處理,提高系統的回應性和吞吐量。