Giới thiệu về cách điều phối không máy chủ bằng Quy trình công việc

1. Giới thiệu

c9b0cc839df0bb8f.png

Bạn có thể sử dụng Quy trình công việc để tạo quy trình công việc không máy chủ, liên kết một loạt các tác vụ không máy chủ với nhau theo thứ tự mà bạn xác định. Bạn có thể kết hợp sức mạnh của các API của Google Cloud, các sản phẩm không máy chủ như Cloud Functions và Cloud Run, cũng như các lệnh gọi đến các API bên ngoài để tạo các ứng dụng không máy chủ linh hoạt.

Workflows không yêu cầu quản lý cơ sở hạ tầng và có thể mở rộng quy mô một cách liền mạch theo nhu cầu, kể cả khi giảm quy mô xuống 0. Với mô hình thanh toán theo mức sử dụng, bạn chỉ trả tiền cho thời gian thực thi.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách kết nối nhiều dịch vụ của Google Cloud và API HTTP bên ngoài với Workflows. Cụ thể hơn, bạn sẽ kết nối 2 dịch vụ Cloud Functions công khai, 1 dịch vụ Cloud Run riêng tư và một API HTTP công khai bên ngoài vào một quy trình.

Kiến thức bạn sẽ học được

  • Kiến thức cơ bản về Workflows.
  • Cách kết nối Cloud Functions công khai với quy trình công việc.
  • Cách kết nối các dịch vụ Cloud Run riêng tư với Workflows.
  • Cách kết nối các API HTTP bên ngoài với quy trình công việc.

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. (Nếu chưa có tài khoản Gmail hoặc G Suite, bạn phải tạo một tài khoản.)

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

Hãy nhớ mã dự án, một tên duy nhất trên tất cả các dự án trên Google Cloud (tên ở trên đã được sử dụng và sẽ không hoạt động đối với bạn, xin lỗi!). Sau này trong lớp học lập trình này, chúng ta sẽ gọi nó là PROJECT_ID.

  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên của Google Cloud.

Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Hãy nhớ làm theo mọi hướng dẫn trong phần "Dọn dẹp" để biết cách tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi hướng dẫn này. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí trị giá 300 USD.

Khởi động Cloud Shell

Mặc dù có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên Cloud.

Trên Bảng điều khiển GCP, hãy nhấp vào biểu tượng Cloud Shell trên thanh công cụ ở trên cùng bên phải:

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

Quá trình này chỉ mất vài phút để cung cấp và kết nối với môi trường. Khi quá trình này kết thúc, bạn sẽ thấy như sau:

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

Máy ảo này được trang bị tất cả các công cụ phát triển mà bạn cần. Nó cung cấp một thư mục chính có dung lượng 5 GB và chạy trên Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Bạn chỉ cần một trình duyệt là có thể thực hiện mọi thao tác trong phòng thí nghiệm này.

3. Tổng quan về quy trình công việc

Thông tin cơ bản

Quy trình công việc bao gồm một chuỗi các bước được mô tả bằng cú pháp dựa trên YAML của Workflows. Đây là định nghĩa của quy trình công việc. Để biết nội dung giải thích chi tiết về cú pháp YAML của quy trình công việc, hãy xem trang Tài liệu tham khảo về cú pháp.

Khi được tạo, quy trình công việc sẽ được triển khai, giúp quy trình công việc sẵn sàng thực thi. Quá trình thực thi là một lần chạy duy nhất của logic có trong định nghĩa của quy trình công việc. Tất cả các lần thực thi quy trình đều độc lập và sản phẩm hỗ trợ một số lượng lớn các lần thực thi đồng thời.

Bật các dịch vụ

Trong lớp học lập trình này, bạn sẽ kết nối Cloud Functions, các dịch vụ Cloud Run với Workflows. Bạn cũng sẽ sử dụng Cloud Build và Cloud Storage trong quá trình tạo dịch vụ.

Bật tất cả các dịch vụ cần thiết:

gcloud services enable \
  cloudfunctions.googleapis.com \
  run.googleapis.com \
  workflows.googleapis.com \
  cloudbuild.googleapis.com \
  storage.googleapis.com

Trong bước tiếp theo, bạn sẽ kết nối 2 Cloud Functions với nhau trong một quy trình.

4. Triển khai Cloud Function đầu tiên

Hàm đầu tiên là trình tạo số ngẫu nhiên trong Python.

Tạo và chuyển đến một thư mục cho mã hàm:

mkdir ~/randomgen
cd ~/randomgen

Tạo một tệp main.py trong thư mục có nội dung sau:

import random, json
from flask import jsonify

def randomgen(request):
    randomNum = random.randint(1,100)
    output = {"random":randomNum}
    return jsonify(output)

Khi nhận được một yêu cầu HTTP, Functions này sẽ tạo một số ngẫu nhiên từ 1 đến 100 và trả về cho phương thức gọi ở định dạng JSON.

Hàm này dựa vào Flask để xử lý HTTP và chúng ta cần thêm hàm đó làm phần phụ thuộc. Các phần phụ thuộc trong Python được quản lý bằng pip và thể hiện trong một tệp siêu dữ liệu có tên là requirements.txt.

Tạo một tệp requirements.txt trong cùng thư mục có nội dung sau:

flask>=1.0.2

Triển khai hàm bằng một trình kích hoạt HTTP và cho phép các yêu cầu chưa xác thực bằng lệnh này:

gcloud functions deploy randomgen \
    --runtime python312 \
    --trigger-http \
    --allow-unauthenticated

Sau khi triển khai hàm, bạn có thể thấy URL của hàm trong thuộc tính url xuất hiện trong bảng điều khiển hoặc xuất hiện khi dùng lệnh gcloud functions describe.

Bạn cũng có thể truy cập vào URL của hàm bằng lệnh curl sau:

curl $(gcloud functions describe randomgen --format='value(url)')

Hàm này đã sẵn sàng cho quy trình công việc.

5. Triển khai Cloud Functions thứ hai

Hàm thứ hai là hàm nhân. Thao tác này nhân giá trị đầu vào nhận được với 2.

Tạo và chuyển đến một thư mục cho mã hàm:

mkdir ~/multiply
cd ~/multiply

Tạo một tệp main.py trong thư mục có nội dung sau:

import random, json
from flask import jsonify

def multiply(request):
    request_json = request.get_json()
    output = {"multiplied":2*request_json['input']}
    return jsonify(output)

Khi nhận được một yêu cầu HTTP, hàm này sẽ trích xuất input từ nội dung JSON, nhân với 2 rồi trả về cho phương thức gọi ở định dạng JSON.

Tạo tệp requirements.txt tương tự trong cùng một thư mục với nội dung sau:

flask>=1.0.2

Triển khai hàm bằng một trình kích hoạt HTTP và cho phép các yêu cầu chưa xác thực bằng lệnh này:

gcloud functions deploy multiply \
    --runtime python312 \
    --trigger-http \
    --allow-unauthenticated

Sau khi triển khai hàm, bạn cũng có thể truy cập vào URL của hàm đó bằng lệnh curl sau:

curl $(gcloud functions describe multiply --format='value(url)') \
-X POST \
-H "content-type: application/json" \
-d '{"input": 5}'

Hàm này đã sẵn sàng cho quy trình công việc.

6. Kết nối hai Cloud Functions

Trong quy trình công việc đầu tiên, hãy kết nối 2 hàm với nhau.

Tạo tệp workflow.yaml có nội dung sau.

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- returnResult:
    return: ${multiplyResult}

Trong quy trình này, bạn sẽ nhận được một số ngẫu nhiên từ hàm đầu tiên và truyền số đó đến hàm thứ hai. Kết quả là số ngẫu nhiên đã nhân.

Triển khai quy trình công việc đầu tiên:

gcloud workflows deploy workflow --source=workflow.yaml

Thực thi quy trình công việc đầu tiên:

gcloud workflows execute workflow

Sau khi quy trình được thực thi, bạn có thể xem kết quả bằng cách truyền mã thực thi được cung cấp ở bước trước:

gcloud workflows executions describe <your-execution-id> --workflow workflow

Kết quả sẽ bao gồm resultstate:

result: '{"body":{"multiplied":108},"code":200 ... } 

...
state: SUCCEEDED

7. Kết nối một API HTTP bên ngoài

Tiếp theo, bạn sẽ kết nối math.js làm dịch vụ bên ngoài trong quy trình công việc.

Trong math.js, bạn có thể đánh giá các biểu thức toán học như sau:

curl https://api.mathjs.org/v4/?'expr=log(56)'

Lần này, bạn sẽ sử dụng Cloud Console để cập nhật quy trình làm việc của chúng ta. Tìm Workflows trong Google Cloud Console:

7608a7991b33bbb0.png

Tìm quy trình làm việc của bạn rồi nhấp vào thẻ Definition:

f3c8c4d3ffa49b1b.png

Chỉnh sửa định nghĩa quy trình công việc và thêm một lệnh gọi đến math.js.

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- returnResult:
    return: ${logResult}

Giờ đây, quy trình công việc sẽ truyền đầu ra của hàm nhân vào một lệnh gọi hàm nhật ký trong math.js.

Giao diện người dùng sẽ hướng dẫn bạn chỉnh sửa và triển khai quy trình công việc. Sau khi triển khai, hãy nhấp vào Execute để thực thi quy trình công việc. Bạn sẽ thấy thông tin chi tiết về quá trình thực thi:

b40c76ee43a1ce65.png

Lưu ý mã trạng thái 200body có đầu ra của hàm nhật ký.

Bạn vừa tích hợp một dịch vụ bên ngoài vào quy trình làm việc của chúng tôi, thật tuyệt!

8. Triển khai dịch vụ Cloud Run

Trong phần cuối cùng, hãy hoàn tất quy trình bằng cách gọi một dịch vụ Cloud Run riêng tư. Điều này có nghĩa là quy trình công việc cần được xác thực để gọi dịch vụ Cloud Run.

Dịch vụ Cloud Run trả về math.floor của số được truyền vào.

Tạo và chuyển đến một thư mục cho mã dịch vụ:

mkdir ~/floor
cd ~/floor

Tạo một tệp app.py trong thư mục có nội dung sau:

import json
import logging
import os
import math

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['POST'])
def handle_post():
    content = json.loads(request.data)
    input = float(content['input'])
    return f"{math.floor(input)}", 200

if __name__ != '__main__':
    # Redirect Flask logs to Gunicorn logs
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)
    app.logger.info('Service started...')
else:
    app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

Cloud Run triển khai các vùng chứa, vì vậy bạn cần có Dockerfile và vùng chứa của bạn cần liên kết với biến môi trường 0.0.0.0PORT, do đó có đoạn mã ở trên.

Khi nhận được một yêu cầu HTTP, hàm này sẽ trích xuất input từ nội dung JSON, gọi math.floor và trả kết quả về cho phương thức gọi.

Trong cùng một thư mục, hãy tạo Dockerfile sau đây:

# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.7-slim

# Install production dependencies.
RUN pip install Flask gunicorn

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

Tạo vùng chứa:

export SERVICE_NAME=floor
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

Sau khi tạo vùng chứa, hãy triển khai lên Cloud Run. Hãy lưu ý cờ no-allow-unauthenticated. Điều này đảm bảo rằng dịch vụ chỉ chấp nhận các lệnh gọi đã xác thực:

gcloud run deploy ${SERVICE_NAME} \
  --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
  --platform managed \
  --no-allow-unauthenticated

Sau khi triển khai, dịch vụ này đã sẵn sàng cho quy trình làm việc.

9. Kết nối dịch vụ Cloud Run

Trước khi có thể định cấu hình quy trình công việc để gọi dịch vụ Cloud Run riêng tư, bạn cần tạo một tài khoản dịch vụ để quy trình công việc sử dụng:

export SERVICE_ACCOUNT=workflows-sa
gcloud iam service-accounts create ${SERVICE_ACCOUNT}

Cấp vai trò run.invoker cho tài khoản dịch vụ. Thao tác này sẽ cho phép tài khoản dịch vụ gọi các dịch vụ Cloud Run đã xác thực:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
    --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
    --role "roles/run.invoker"

Cập nhật định nghĩa quy trình công việc trong workflow.yaml để thêm dịch vụ Cloud Run. Lưu ý rằng bạn cũng đang thêm trường auth để đảm bảo Workflows truyền mã thông báo xác thực trong các lệnh gọi đến dịch vụ Cloud Run:

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- floorFunction:
    call: http.post
    args:
        url: https://floor-<random-hash>.run.app
        auth:
            type: OIDC
        body:
            input: ${logResult.body}
    result: floorResult
- returnResult:
    return: ${floorResult}

Cập nhật quy trình làm việc. Thời gian này trôi qua trong tài khoản dịch vụ:

gcloud workflows deploy workflow \
    --source=workflow.yaml \
    --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Thực thi quy trình công việc:

gcloud workflows execute workflow

Trong vài giây, bạn có thể xem quá trình thực thi quy trình công việc để xem kết quả:

gcloud workflows executions describe <your-execution-id> --workflow workflow

Kết quả sẽ bao gồm số nguyên resultstate:

result: '{"body":"5","code":200 ... } 

...
state: SUCCEEDED

10. Xin chúc mừng!

Chúc mừng bạn đã hoàn thành lớp học lập trình này.

Nội dung đã đề cập

  • Kiến thức cơ bản về Workflows.
  • Cách kết nối Cloud Functions công khai với quy trình công việc.
  • Cách kết nối các dịch vụ Cloud Run riêng tư với Workflows.
  • Cách kết nối các API HTTP bên ngoài với quy trình công việc.