iT邦幫忙

2024 iThome 鐵人賽

DAY 14
0
Kubernetes

K8s 資料庫管理系統系列 第 14

day 14 K8s銀行提款資料庫管理系統

  • 分享至 

  • xImage
  •  

今天是第十四天我們可以寫一個K8s銀行提款資料庫管理系統,以下是程式碼

  1. 後端 API 服務:處理提款的業務邏輯。
  2. 資料庫服務:用於存儲用戶的帳戶、交易等數據。
  3. 前端服務:用於用戶和銀行管理員進行互動。
  4. Kubernetes 資源配置:如 DeploymentServicePersistentVolume 等。

1. API 服務 (Node.js 示例)

這裡是一個簡單的 API 服務,用於處理提款邏輯:

const express = require('express');
const mysql = require('mysql2');

// 建立 Express 應用
const app = express();
app.use(express.json());

// 設定 MySQL 連線
const db = mysql.createConnection({
  host: 'db', // K8s 中的資料庫服務名稱
  user: 'root',
  password: 'password',
  database: 'bank'
});

// 提款 API
app.post('/withdraw', (req, res) => {
  const { accountNumber, amount } = req.body;

  // 查詢帳戶餘額
  db.query('SELECT balance FROM accounts WHERE accountNumber = ?', [accountNumber], (err, results) => {
    if (err) return res.status(500).json({ message: '資料庫錯誤' });
    if (results.length === 0) return res.status(404).json({ message: '帳戶未找到' });

    const currentBalance = results[0].balance;

    // 檢查餘額是否足夠
    if (currentBalance < amount) {
      return res.status(400).json({ message: '餘額不足' });
    }

    // 更新帳戶餘額
    const newBalance = currentBalance - amount;
    db.query('UPDATE accounts SET balance = ? WHERE accountNumber = ?', [newBalance, accountNumber], (updateErr) => {
      if (updateErr) return res.status(500).json({ message: '無法更新餘額' });

      // 成功返回
      res.json({ message: '提款成功', balance: newBalance });
    });
  });
});

// 啟動服務
app.listen(3000, () => {
  console.log('銀行提款系統已啟動,端口 3000');
});

2. MySQL 資料庫配置

在 Kubernetes 中,您可以使用一個 MySQL 部署來保存銀行的帳戶數據。

MySQL Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.7
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        - name: MYSQL_DATABASE
          value: bank
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim

MySQL Service:

apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  ports:
  - port: 3306
  selector:
    app: mysql

Persistent Volume 和 Persistent Volume Claim:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data" # 本地存儲路徑

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

3. API 服務的 Kubernetes 部署

將 Node.js API 部署到 Kubernetes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bank-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: bank-api
  template:
    metadata:
      labels:
        app: bank-api
    spec:
      containers:
      - name: bank-api
        image: node:14
        ports:
        - containerPort: 3000
        volumeMounts:
        - name: api-code
          mountPath: /usr/src/app
        workingDir: /usr/src/app
        command: ["npm", "start"]
      volumes:
      - name: api-code
        hostPath:
          path: "/path/to/your/api/code" # 本地存儲的 API 代碼路徑

API Service:

apiVersion: v1
kind: Service
metadata:
  name: bank-api
spec:
  ports:
  - port: 80
    targetPort: 3000
  selector:
    app: bank-api
  type: LoadBalancer

4. 前端 (可選)

您可以選擇任何前端框架來構建用戶界面,並將其部署在 K8s 中。

5. 部署流程

  1. 編寫並構建 API 和資料庫映像。
  2. 在 K8s 上創建 DeploymentService 資源。
  3. 使用 PersistentVolume 保證資料的持久性。
  4. 使用 kubectl apply -f 部署這些 YAML 文件到您的 K8s 集群。

1. API 服務 (Node.js)

程式碼:

const express = require('express');
const mysql = require('mysql2');

// 建立 Express 應用
const app = express();
app.use(express.json());
  • express:這是一個輕量級的 Node.js 網頁應用框架,用來處理 HTTP 請求與回應。
  • mysql2:這個模組用來連接 MySQL 資料庫並執行查詢操作。
  • app.use(express.json()):這一行代碼允許應用程式解析 JSON 請求體,因為提款請求的資料會以 JSON 格式發送。

設定 MySQL 連線:

const db = mysql.createConnection({
  host: 'db', // K8s 中的資料庫服務名稱
  user: 'root',
  password: 'password',
  database: 'bank'
});
  • mysql.createConnection():這是用來連接 MySQL 資料庫的設定。連線資訊包括:
    • host: 'db':這裡的 'db' 是指 Kubernetes 中資料庫的服務名稱,它會解析成對應的 MySQL 服務 IP 地址。
    • user: 'root'password: 'password':分別是資料庫的使用者帳號和密碼。
    • database: 'bank':這裡指定了要使用的資料庫名稱 "bank"。

提款 API 路由:

app.post('/withdraw', (req, res) => {
  const { accountNumber, amount } = req.body;

  // 查詢帳戶餘額
  db.query('SELECT balance FROM accounts WHERE accountNumber = ?', [accountNumber], (err, results) => {
    if (err) return res.status(500).json({ message: '資料庫錯誤' });
    if (results.length === 0) return res.status(404).json({ message: '帳戶未找到' });

    const currentBalance = results[0].balance;

    // 檢查餘額是否足夠
    if (currentBalance < amount) {
      return res.status(400).json({ message: '餘額不足' });
    }

    // 更新帳戶餘額
    const newBalance = currentBalance - amount;
    db.query('UPDATE accounts SET balance = ? WHERE accountNumber = ?', [newBalance, accountNumber], (updateErr) => {
      if (updateErr) return res.status(500).json({ message: '無法更新餘額' });

      // 成功返回
      res.json({ message: '提款成功', balance: newBalance });
    });
  });
});
  • app.post('/withdraw'):定義了一個 POST 請求的路由,這個路由處理提款請求。當客戶端向這個路由發送提款請求時,請求資料會包含帳戶號碼 (accountNumber) 和提款金額 (amount)。
  • db.query():這是執行 SQL 查詢的函數。第一次查詢是檢查該帳戶號碼的餘額。結果儲存在 results 變數中。
    • 如果有錯誤,返回一個 HTTP 500 錯誤(伺服器錯誤)。
    • 如果帳戶不存在,返回 404 錯誤(找不到帳戶)。
    • 如果餘額不足,返回 400 錯誤(請求無效)。
  • UPDATE accounts:如果餘額足夠,則更新資料庫中的餘額,並返回一個成功的 JSON 響應。

啟動服務:

app.listen(3000, () => {
  console.log('銀行提款系統已啟動,端口 3000');
});
  • app.listen(3000):啟動 Node.js 應用,並將其監聽在 3000 端口上。當服務啟動後,伺服器會顯示 "銀行提款系統已啟動,端口 3000" 的訊息。

2. MySQL 部署 (Kubernetes YAML)

MySQL Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.7
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        - name: MYSQL_DATABASE
          value: bank
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
  • apiVersion: 指定了這個資源使用的 Kubernetes API 版本。
  • kind: Deployment: 說明這是一個 Deployment,Kubernetes 用來管理應用程式的副本和更新。
  • spec.template.spec.containers: 指定容器的映像以及環境變量:
    • image: mysql:5.7:使用了 MySQL 5.7 的容器映像。
    • MYSQL_ROOT_PASSWORDMYSQL_DATABASE:這些環境變數用於配置資料庫的 root 密碼和資料庫名稱。
  • volumeMounts: 將持久性存儲卷掛載到 /var/lib/mysql,這裡存放 MySQL 資料。

MySQL Service:

apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  • kind: Service:Service 用來將 MySQL 容器暴露給其他服務(如 API 服務)使用。port: 3306 是 MySQL 的默認端口。

3. API 服務的 Kubernetes 部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bank-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: bank-api
  template:
    metadata:
      labels:
        app: bank-api
    spec:
      containers:
      - name: bank-api
        image: node:14
        ports:
        - containerPort: 3000
        volumeMounts:
        - name: api-code
          mountPath: /usr/src/app
        workingDir: /usr/src/app
        command: ["npm", "start"]
      volumes:
      - name: api-code
        hostPath:
          path: "/path/to/your/api/code"
  • replicas: 2:設定兩個 API 服務的副本,這樣可以提供高可用性。
  • image: node:14:Node.js 14 的容器映像。
  • volumeMountshostPath:將本地代碼掛載到容器內的 /usr/src/app,讓容器能夠執行應用程式。

API Service:

apiVersion: v1
kind: Service
metadata:
  name: bank-api
spec:
  ports:
  - port: 80
    targetPort: 3000
  selector:
    app: bank-api
  type: LoadBalancer
  • kind: Service:這個服務暴露了 API 應用,port: 80 是暴露給外部的端口,targetPort: 3000 是容器內的端口。type: LoadBalancer 說明這個服務將被外部負載均衡器使用,這樣外部用戶可以通過公共 IP 訪問 API。

總結

  • Node.js API:處理提款的邏輯,從資料庫中檢查餘額並執行更新操作。
  • MySQL 資料庫:保存帳戶和交易資料,通過 K8s 的 PersistentVolume 保證資料不會丟失。
  • Kubernetes 資源 (Deployment 和 Service):K8s 用於管理和暴露 MySQL 和 API 服務,確保系統的高可用性和擴展性。

上一篇
day 12 K8s 科學園區廠區氣體資料庫管理系統
下一篇
day 12 K8s租車公司資料庫管理系統
系列文
K8s 資料庫管理系統30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言