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 làm việc không máy chủ, giúp liên kết một loạt các tác vụ không máy chủ với nhau theo thứ tự do 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 ra các ứng dụng linh hoạt không máy chủ.

Quy trình công việc không yêu cầu bạn phải 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 định giá trả tiền cho mỗi lần sử dụng, bạn chỉ phải trả 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 bằng 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à 1 API HTTP công khai bên ngoài vào quy trình làm việc.

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

  • Kiến thức cơ bản về Quy trình công việc.
  • Cách kết nối Cloud Functions công khai với Workflows.
  • 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 API HTTP bên ngoài với Workflows.

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

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Cloud Console rồi tạo dự án mới hoặc sử dụng lại 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

Xin lưu ý rằng mã dự án là một tên riêng biệt trong tất cả dự án Google Cloud (tên ở trên đã được sử dụng nên sẽ không phù hợp với bạn!). Lớp này sẽ được đề cập sau trong lớp học lập trình này là PROJECT_ID.

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

Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Hãy nhớ làm theo mọi hướng dẫn trong phần "Dọn dẹp" sẽ tư vấn cho bạn cách tắt tài nguyên để bạn không phải chịu thanh toán ngoài 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í 300 USD.

Khởi động Cloud Shell

Mặc dù bạn 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 trong Đám mây.

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

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

Sẽ chỉ mất một chút thời gian để cấp phép và kết nối với môi trường. Sau khi hoàn tất, bạn sẽ thấy như sau:

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

Máy ảo này chứa tất cả các công cụ phát triển mà bạn cần. Phiên bản này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Bạn có thể thực hiện tất cả công việc trong phòng thí nghiệm này chỉ bằng một trình duyệt.

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

Thông tin cơ bản

Một quy trình công việc bao gồm một loạt 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 làm 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 một quy trình công việc được tạo, nó sẽ được triển khai, giúp quy trình công việc luôn sẵn sàng để thực thi. Quá trình thực thi là một lần chạy logic có trong định nghĩa của một quy trình công việc. Tất cả các quá trình thực thi quy trình công việc đều độc lập và sản phẩm hỗ trợ nhiều lần thực thi đồng thời.

Bật dịch vụ

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

Bật tất 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 hai Cloud Functions với nhau trong một quy trình làm việc.

4. Triển khai chức năng đám mây đầu tiên

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

Tạo và điều hướng đến một thư mục chứa mã hàm:

mkdir ~/randomgen
cd ~/randomgen

Tạo 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 yêu cầu HTTP, hàm này sẽ tạo một số ngẫu nhiên trong khoảng từ 1 đến 100 và trả về ở định dạng JSON cho phương thức gọi.

Hàm này dựa vào Flask để xử lý HTTP và chúng ta cần thêm dữ liệu đó làm phần phụ thuộc. Các phần phụ thuộc trong Python được quản lý bằng pip và được thể hiện trong 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 với những nội dung sau:

flask>=1.0.2

Triển khai hàm có điều kiện kích hoạt HTTP và với các yêu cầu chưa được xác thực được cho phép bằng lệnh sau:

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

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

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

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

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

5. Triển khai chức năng đám mây thứ hai

Hàm thứ hai là một số nhân. Hàm này nhân dữ liệu đầu vào nhận được với 2.

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

mkdir ~/multiply
cd ~/multiply

Tạo 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ề ở định dạng JSON cho phương thức gọi.

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

flask>=1.0.2

Triển khai hàm có điều kiện kích hoạt HTTP và với các yêu cầu chưa được xác thực được cho phép bằng lệnh sau:

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

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

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

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

6. Kết nối hai Hàm đám mây

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

Tạo tệp workflow.yaml có cá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 làm việc này, bạn nhận được một số ngẫu nhiên từ hàm đầu tiên rồi truyền số đó vào hàm thứ hai. Kết quả là số ngẫu nhiên được nhân lê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 thực thi quy trình công việc, bạn có thể xem kết quả bằng cách truyền mã thực thi đã cho ở 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 API HTTP bên ngoài

Tiếp theo, bạn sẽ kết nối math.js dưới dạng dịch vụ bên ngoài trong quy trình làm 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ẽ dùng Cloud Console để cập nhật quy trình làm việc của chúng tôi. Tìm Workflows trong Google Cloud Console:

7608a7991b33bbb0.pngS

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 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}

Quy trình hiện tại sẽ đưa kết quả 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 làm 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

Hãy lưu ý mã trạng thái 200body có kết quả là 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, hãy hoàn tất quy trình công việc bằng lệnh gọi đến 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ố đã truyền.

Tạo và điều hướng đến một thư mục cho mã dịch vụ:

mkdir ~/floor
cd ~/floor

Tạo 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 đó, bạn có 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ừ phần nội dung JSON, gọi payment.floor và trả về kết quả cho phương thức gọi.

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

# 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 xong vùng chứa, hãy triển khai Cloud Run. Hãy lưu ý cờ no-allow-unauthenticated. Việc này đảm bảo dịch vụ chỉ chấp nhận các cuộc 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 được triển khai, dịch vụ sẽ sẵn sàng cho quy trình công việc.

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

Trước khi có thể định cấu hình Workflows để 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ụ cho Workflows để sử dụng:

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

Cấp vai trò của 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 để bao gồm dịch vụ Cloud Run. Lưu ý cách bạn bao gồm cả trường auth để đảm bảo Quy trình làm việc 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. Lần này chuyển vào 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

Sau vài giây, bạn có thể xem xét quá trình thực thi quy trình để biết kết quả:

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

Kết quả sẽ bao gồm một 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ội dung đã đề cập

  • Kiến thức cơ bản về Quy trình công việc.
  • Cách kết nối Cloud Functions công khai với Workflows.
  • 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 API HTTP bên ngoài với Workflows.