AWS App Runner 上的 .NET 工作負載

模組 3

模組 3:AWS App Runner 上的 .NET Web API

 實作實驗室

實驗室目標

在這個實作實驗室中,您將建立一個使用 DynamoDB 資料表的 .NET Web API,然後對其進行容器化並託管於 AWS App Runner 之中。您可以在 Windows 電腦、macOS 或 Linux 電腦上執行此實驗室,或是在雲端中的 Cloud9 環境上執行。

首先,您將建立 DynamoDB 資料表和存取該資料表的 .NET 6 Web API 專案。在本機測試之後,您將使用 Docker 和適用於 .NET CLI 的 AWS 部署工具對軟體進行容器化並將其部署到 Amazon Elastic Container Registry (ECR)。然後,您將建立 App Runner 服務,以及與 DynamoDB 通信所需的 AWS Artifact,其中包括一個 IAM 角色、一個 VPC 連接器和一個適用於 DynamoDB 的 VPC 端點。您將在雲端測試應用程式,並驗證該應用程式能否從 DynamoDB 擷取資料。您將在 App Runner 主控台中監視應用程式並檢閱日誌。最後,您將更新該專案並將更新推送到 ECR,然後看到 App Runner 自動對其進行部署。最後,您將刪除應用程式及其資源。

此實驗室有 12 個步驟:

  1. 設定 AWS
  2. 設定您的開發環境
  3. 建立 DynamoDB 資料表
  4. 建立 .NET Web API 專案
  5. 本機測試
  6. 將 Web API 專案發佈到 ECR
  7. 建立 IAM 角色
  8. 建立 App Runner 服務
  9. 為 DynamoDB 建立 VPC 端點
  10. 在雲端測試
  11. 部署更新
  12. 關閉專案

 完成時間

90 分鐘

實作

第 1 步:設定 AWS

在此步驟中,您將設定 AWS 環境。

如果您已完成開發並並部署到 Amazon,並且已安裝適用於 .NET CLI 的 AWS 部署工具,您可以跳到第 3 步。

 1.取得 AWS 帳戶

使用現有的 AWS 帳戶或建立 AWS 帳戶。請勿使用生產帳戶。

 2.選擇 AWS 區域

登 AWS Console ,然後選擇一個支援 AWS App Runner支援 DynamoDB 的 AWS 區域,以在其中執行。

3.建立開發環境

如果在此實驗室使用本機電腦,請繼續執行第 2 步。

如果使用 Cloud9,請繼續下列操作。

透過 AWS Console 設定 Cloud9 環境:

A. 在 AWS Console 中導覽至 Cloud9,然後按一下「建立環境」。

B. 將環境命名為 AppRunnerLab。

C. 保留預設值,然後按一下「建立」。

D. 等待環境完成建立,這需要幾分鐘時間。如果由於 t2.micro 執行個體類型在該區域不可用而導致環境創建失敗,請重複上述步驟並選擇另外一種小型執行個體類型。如果免費方案中不包含該執行個體類型,請注意您需按照特定費率為實驗期間對該執行個體類型的使用付費。

檢查您的工作

您現在應該:

✓ 有一個 AWS 帳戶

✓ 了解如何登入 AWS 管理主控台

✓ 已選取要在其中工作的區域

✓ 有可用的本機電腦或 Cloud9 環境

第 2 步:設定您的開發環境

在此步驟中,您將安裝軟體以設定開發環境。跳過您已安裝的項目。

1.安裝 AWS CLI

安裝 AWS Command Line Interface (CLI)。

2.設定 AWS CLI

設定 AWS CLI,使其連結至 AWS 帳戶中的使用者。

在命令/終端視窗中,使用此命令設定區域:aws configure

3.安裝 .NET SDK

安裝 .NET 6 SDK.為您的作業系統下載並安裝 SDK。

如果使用 Cloud9,您可以在「安裝必要工具」底下執行這些命令 (第 1 步和第 2 步)。然後,執行下列命令:./dotnet-install.sh -c LTS

4.安裝適用於 .NET CLI 的 AWS 開發工具

在命令/終端機視窗中,使用下列命令安裝適用於 .NET 的 AWS 部署工具:

dotnet tool install -g aws.deploy.tools

5.安裝 Docker

安裝 Docker Desktop。如果您已有 Docker,請注意您需要 17.05 或更新版本。

6.安裝 IDE

安裝 IDE,例如 Microsoft Visual Studio 2022 (Windows)、Visual Studio Code (Linux、macOS、Windows) 或 JetBrains Rider (Linux、macOS、Windows)。請確定您已安裝在 C# 中進行 .NET Web 開發的選項或延伸。

檢查您的工作

您現在應該:

✓ 已安裝所有必要軟體

✓ 已為您的 AWS 使用者和區域設定 AWS CLI

第 3 步:建立 DynamoDB 資料表

在此步驟中,您將建立名為 Weather 的 DynamoDB 資料表,並建立一些資料記錄。

 1.在 AWS Console 中建立 DynamoDB 資料表

在 AWS Console 中導覽至 Amazon DynamoDB,然後按一下建立資料表

    A. 資料表名稱:Weather
    B. 分區索引鍵:Location
    C. 排序索引鍵:Timestamp
    D. 按一下建立資料表

 2.在資料表中填入項目

按一下 Weather 資料表名稱前往其詳細資訊頁面,然後按一下探索資料表項目。新增這些項目:

A.按一下建立項目JSON 檢視。在下方輸入 JSON (Dallas, morning),然後按一下建立項目

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "33"
  },
  "TempF": {
    "N": "92"
  }
}

B.以相同方式,使用此 JSON 新增第二個項目 (Dallas, mid-day):

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Scorching"
  },
  "TempC": {
    "N": "43"
  },
  "TempF": {
    "N": "109"
  }
}

C.使用此 JSON 新增第三個項目 (Dallas, evening):

{
  "Location": {
    "S": "Dallas"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Hot"
  },
  "TempC": {
    "N": "36"
  },
  "TempF": {
    "N": "97"
  }
}

D.使用此 JSON 新增第四個項目 (Minneapolis, morning):

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T06:00:00"
  },
  "Summary": {
    "S": "Cool"
  },
  "TempC": {
    "N": "13"
  },
  "TempF": {
    "N": "56"
  }
}

E.使用此 JSON 新增第五個項目 (Minneapolis, mid-day)

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T12:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "22"
  },
  "TempF": {
    "N": "72"
  }
}

F.使用此 JSON 新增第六個項目 (Minneapolis, evening): 

{
  "Location": {
    "S": "Minneapolis"
  },
  "Timestamp": {
    "S": "2022-07-23T18:00:00"
  },
  "Summary": {
    "S": "Balmy"
  },
  "TempC": {
    "N": "19"
  },
  "TempF": {
    "N": "67"
  }
}

檢查您的工作

您現在應該:

✓ 有一個名為 Weather 的 DynamoDB 資料表,已填入 6 個項目。

第 4 步:建立 .NET Web API 專案

在此步驟中,您將使用 dotnet new 命令建立 Web API 專案,並更新其程式碼以從 DynamoDB 資料表中擷取資料。

1.將目錄切換至開發資料夾

開啟命令/終端視窗,並將目錄切換至開發資料夾。

2.建立 .NET WebAPI 專案

執行下列 dotnet new 命令,以建立名為 HelloAppRunnerVpc 的新 Web API 專案。

dotnet new webapi -n HelloAppRunnerVpc --framework net6.0

3.在您的 IDE 中開啟專案

在您的 IDE 中開啟此 HelloAppRunnerVpc 專案。

如果您為 IDE 安裝了 AWS Toolkit,請將 AWS Explorer 中的區域設定為您在步驟 1 中選取的區域。

4.檢閱產生的專案

產生的專案是一個 WeatherForecast API,在 .NET 範例中非常常用。

要試用,請按 F5 並用 Swagger 進行測試。您會看到該服務具有 /WeatherForecast 動作,會傳回模擬天氣資料 JSON。

將程式停止執行。

5.新增 AWS SDK NuGet 套件

在命令/終端視窗中,將目錄切換至專案資料夾。執行下列 dotnet add package 命令,將 AWS SDK NuGet 套件 AWSSDK.DynamoDBv2 新增至專案。

cd HelloAppRunnerVpc
 dotnet add package AWSSDK.DynamoDBv2

6.修改 Program.cs

在程式碼編輯器中開啟 Program.cs,並將此陳述式刪除或設為註解,App Runner 不需要使用此陳述式:

//app.UseHttpsRedirection();

 7.對 WeatherForecast 類別進行編碼

開啟 WeatherForecast.cs,並將其取代為下列程式碼。此類別包含從 Weather 資料表中擷取的項目:

namespace HelloAppRunnerVpc;

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public int TemperatureF { get; set; }
    public string? Summary { get; set; }
}

 8.對 WeatherForecastController 類別進行編碼

開啟 Controllers 資料夾中的 WeatherForecastController.cs,然後將其替換為以下程式碼。將 RegionEndpoint.USEast1 更新為您正在其中執行的區域。。此程式碼在服務的根目錄下執行運作狀態檢查方法,並在 /WeatherForecast 目錄下執行 WeatherForecast 方法,後者接受一個位置參數並從 DynamoDB Weather 資料表中擷取資料。它會執行資料表掃描,以尋找分區索引鍵與位置相符的記錄。結果會以 JSON 記錄的陣列形式輸出。
using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using Microsoft.AspNetCore.Mvc;

namespace HelloAppRunnerVpc.Controllers;

[ApiController]
[Route("")]
public class WeatherForecastController : ControllerBase
{
    static readonly RegionEndpoint region = RegionEndpoint.USEast1;

    private readonly ILogger _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet("")]
    public string GetHealthcheck()
    {
        return "Healthcheck: Healthy";
    }

    [HttpGet("WeatherForecast")]
    public async Task<IEnumerable<WeatherForecast>> GetWeatherForecast(string location = "Dallas")
    {
        List<WeatherForecast> forecasts = new List<WeatherForecast>();

        try
        {
            _logger.LogInformation($"00 enter GET, location = {location}");

            var client = new AmazonDynamoDBClient(region);
            Table table = Table.LoadTable(client, "Weather");

            var filter = new ScanFilter();
            filter.AddCondition("Location", ScanOperator.Equal, location);

            var scanConfig = new ScanOperationConfig()
            {
                Filter = filter,
                Select = SelectValues.SpecificAttributes,
                AttributesToGet = new List<string> { "Location", "Timestamp", "TempC", "TempF", "Summary" }
            };

            _logger.LogInformation($"10 table.Scan");

            Search search = table.Scan(scanConfig);

            List<Document> matches;
            do
            {
                _logger.LogInformation($"20 table.GetNextSetAsync");
                matches = await search.GetNextSetAsync();
                foreach (var match in matches)
                {
                    forecasts.Add(new WeatherForecast
                    {
                        Date = Convert.ToDateTime(match["Timestamp"]),
                        TemperatureC = Convert.ToInt32(match["TempC"]),
                        TemperatureF = Convert.ToInt32(match["TempF"]),
                        Summary = Convert.ToString(match["Summary"])
                    });
                }
            } while (!search.IsDone);

            _logger.LogInformation($"30 exited results loop");

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "90 Exception");
        }

        _logger.LogInformation($"99 returning {forecasts.Count} results");

        return forecasts.ToArray();
    }
}

9.儲存變更和組建

儲存您的變更並確保專案組建。

檢查您的工作

您現在應該:

✓ 有一個名為 HelloAppRunnerVpc 的 Web API 專案

✓ 已在 WeatherForecastController.cs 中設置區域

第 5 步:本機測試

在此步驟中,您將在本機測試 Web API,並確認從 DynamoDB 的資料擷取。

 1.偵錯專案

在 IDE 中按 F5,等待應用程式建置並在瀏覽器中啟動。

 2.測試運作狀態檢查動作

在瀏覽器中,移除 URL 的 Swagger 路徑以觸及服務根,您應該會看到運作狀態檢查訊息。App Runner 會定期對網站執行 ping 操作,來檢查運作狀態。

 3.測試達拉斯的天氣預報動作

將 /WeatherForecast?location=Dallas 添加到 URL 路徑的末尾。您應該會看到天氣預報資料 JSON,其中包含您第 1 步中在 DynamoDB 資料表中建立的值。

4.測試明尼亞波利斯的天氣預報動作

將 URL 路徑更改為以 /WeatherForecast?location=Minneapolis 結尾。現在您可以看到該城市的資料。

5.測試無效位置的天氣預報動作

嘗試使用其他位置名稱,您會看到空回應,因為資料表中沒有資料。

6.開啟程式

將程式停止執行。

雖然在本機測試時,我們的應用程式可以直接存取 DynamoDB,但在雲端卻無法直接存取,因為預設情況下,App Runner 僅可存取公共端點。我們必須採取額外步驟,為 App Runner 添加一個 VPC 連接器,並為 DynamoDB 添加一個匹配的 VPC 端點。

檢查您的工作

您現在應該:

✓ 已在本機測試 Web API 專案。

✓ 確認已擷取 DynamoDB 資料。

第 6 步:將 Web API 項目發佈至 ECR

在此步驟中,您將使用 AWS .NET 部署工具來對專案進行容器化,並將容器映像推送到 Amazon Elastic Container Registry (ECR)。

1.建立 Dockerfile

使用以下程式碼將名為 Dockerfile 的文字檔添加到專案檔案夾:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HelloAppRunnerVpc.csproj", "."]
RUN dotnet restore "./HelloAppRunnerVpc.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "HelloAppRunnerVpc.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "HelloAppRunnerVpc.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloAppRunnerVpc.dll"]

2.部署到 ECR

將您的專案作為容器映像部署到 ECR:

a.在命令/終端視窗中,運行以下命令啟動部署,並指定您偏好的區域。(圖 1)

dotnet aws deploy --region us-west-2

b.選擇相應選項,將容器映像推送到 Amazon Elastic Container Registry (ECR)

c.在「目前設定」提示下,輸入要變更影像標籤的編號,並將其設定為最新。(圖 2)

d.按 Enter 鍵確認部署。

3.等待部署

等待部署完成。

4.在 AWS Console 中確認部署

確認容器映像已部署到 ECR。在 AWS Console 中,導覽至 ECR。此時應列出一個名為 helloapprunnervpc 的存儲庫。

檢查您的工作

您現在應該:

✓ 已使用 Dockerfile 對項目進行容器化。

✓ 已將容器映像部署到 Amazon ECR。

第 7 步:建立 IAM 角色

在此步驟中,您將使用 AWS Console 建立名為 AppRunnerInstanceDynamoDB 的 IAM 角色。此角色將允許 App Runner EC2 執行個體存取 DynamoDB 資料表。

1.建立 DynamoDB 資料表存取政策

建立允許存取 Weather DynamoDB 資料表的政策:    

    a.導覽至 Identity and Access Management (IAM)。

    b.從左窗格中選取「政策」,然後按一下「建立政策」。

    c.建立政策並在下方輸入 JSON,將 [account] 取代為您的 12 位數 AWS 帳戶號碼,並將 [region] 取代為您的區域。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:[region]:[account]:table/Weather"
        }
    ]
}

    d.按一下「下一步:標籤」,然後按一下「下一步:檢閱」。將政策命名為 ddb-Weather,然後按一下「建立政策」。

2.建立 EC2 執行個體的角色

為 App Runner EC2 執行個體建立角色:

    a.從左側窗格中選取角色,然後按一下建立角色

    b.對於「信任的實體類型」,選取「AWS 服務」。(圖 1)

    c.對於「使用案例」,選取「EC2」,然後按「下一步」。(圖 1)

    d.搜尋並選取下列權限:ddb-Weather, AmazonDynamoDBFullAccessAWSAppRunnerFullAccess。然後按一下下一步。(圖 2)

    e.在「信任關係」標籤上,按一下「編輯信任政策」。將其替換為此 JSON,然後按一下「更新政策」。(圖 5)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "ec2.amazonaws.com",
                    "tasks.apprunner.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

    f.將角色命名為 AppRunnerInstanceDynamoDB ,然後按一下建立角色。(圖 3)

檢查您的工作

您現在應該:

✓ 有一個名為 AppRunnerInstanceDynamoDB 並具有 3 個政策的 IAM 角色。 

第 8 步:建立 App Runner 服務

在此步驟中,您將建立 App Runner 服務和一個 VPC 連接器。

 1.建立服務

在 AWS Console 中,導覽至 AWS App Runner,然後按一下建立服務

    a.儲存庫類型:容器登錄。 (圖 1)

    b.供應商:Amazon ECR.

    c.按一下「瀏覽」,然後選取您在第 6 步中部署到 ECR 的容器。(圖 2)

    d.對於部署設定觸發器,選取自動

    e.對於「ECR 存取角色」,選取建立新服務角色

    f.按一下下一步

 2.設定服務

在「設定服務」頁面上,

    a.服務名稱:HelloAppRunnerVpc

    b.連接埠:80

3.設定執行個體角色

展開「安全性」區段,並將執行個體角色設定為 AppRunnerInstanceDynamoDB

4.建立 VPC 連接器

展開「網路」區段並建立 VPC 連接器:

    a.在「網路」下,選取自訂 VPC

    b.在 VPC 連接器下,按一下新增

    c.VPC 連接器名稱:AppRunnerDynamoDB。(圖 1)

    d.VPC:選取預設 VPC。

    e.子網路:選取所有子網路。

    f.安全群組:選取預設安全群組。(圖 2)

    g.按一下新增。如果收到錯誤訊息,指出其中一個子網路不支援 App Runner 服務,請將其從「子網路」清單中移除,然後再按一下新增。(圖 2)

    h.按一下下一步,然後一步建立並部署

5.等待部署

等待部署,這將需要幾分鐘。這是休息的好時機。

6.記錄服務 URL

服務部署完成後,您會看到建立服務成功訊息。

記錄預設網域 URL。這是您的服務 URL。

重新整理事件日誌,您應該會看到服務正在執行的確認訊息。

7.瀏覽至服務 URL

瀏覽到 URL,您應該會看到運作狀態檢查。我們的服務託管在 App Runner 中,但它尚無法存取 DynamoDB。我們已建立 App Runner VPC 連接器,但仍然需要為 DynamoDB 建立相符的 VPC 端點。

檢查您的工作

您現在應該:

✓ 有一個名為 HelloAppRunnerVpc 的執行中 AWS App Runner 服務。

✓ 有服務端點 URL。

✓ 已確認運作狀態檢查 URL 能在瀏覽器中正常回應。

第 9 步:為動態 ODB 建立 VPC 端點

在此步驟中,您將為 DynamoDB 建立 VPC 端點。

1.在 AWS Console 中,導覽至 VPC

2.建立端點

從左側面板選取「端點」,然後按一下建立端點

    a.名稱:vpc-endpoint-dynamodb。(圖 1)

    b.服務類別:AWS 服務

    c.服務:在搜尋框中輸入 DynamoDB 並選取 com.amazonaws.region.dynamodb

    d.VPC:選取預設 VPC。

    e.路由表:選取「主路由表」。

    f.按一下建立端點。(圖 2)

檢查您的工作

您現在應該:

有一個 DynamoDB 的 VPC 端點,名為 vpc-endpoint-dynamodb。

第 10 步:在雲端測試

現在,我們已準備好將所有內容整合在一起,並在雲端測試 Web API。

 1.造訪服務 URL

在瀏覽器中,造訪您在第 6 步中記錄的服務 URL。您會看到運作狀態檢查回應。

 2.測試達拉斯的天氣預報動作

/WeatherForecast?location=Dallas 添加到 URL 路徑的末尾。現在,您可以看到您在第 1 步中輸入的達拉斯的記錄

 3.測試明尼亞波利斯的天氣預報動作

3.將路徑的末尾改為 /WeatherForecast?location=Minneapolis然後您會看到該市的記錄。

恭喜您! 您的 Web API 已託管於 AWS App Runner 之中,且該服務正在與 DynamoDB 通信。

檢查您的工作

您現在應該:

✓ 您的 Web API 已託管於 AWS App Runner 之中,且該服務正在與 DynamoDB 通信。

第 11 步:部署更新

在此步驟中,您將更新 Web API、推送經過更新的容器,並看到 App Runner 自動將更新後的容器部署到該服務。之所以如此,是因為我們在創建服務時在第 8 步中配置了自動部署。

1.修改服務

在您的 IDE 中,更改 GetWeatherForecast 方法,使回應略有不同。例如,您可以在「摘要」欄位中添加一個感嘆號。

2.在本機建置和測試

在本機建置和測試專案,以確保符合預期。 

3.重新部署容器

開啟程式。在命令/終端窗口中,再次執行 dotnet aws deploy,將更新後的容器部署到 ECR,就像在第 6 步中的操作一樣。確保標籤仍是 最新的

4.監控服務重新部署

在 AWS App Runner 主控台中,查看您的服務。部署新容器不久後,App Runner 將自動部署更新。

5.測試更新的服務

等待更新完成後,按照第 10 步中的操作導覽到該服務,對其進行測試。確認您現在可以看到該服務輸出的新版本。

檢查您的工作

您現在應該:

✓ 已透過更改更新了 Web API 專案。

✓ 已將更新的容器部署到 ECR。

✓ 確認 App Runner 已自動部署更新。 

第 12 步:關閉

您可以隨意對專案進行變更,以測試您的知識掌握情況。

完成專案的所有相關操作後,將其關閉。您一定不希望為自己沒有使用的內容付費。

1.刪除 App Runner 服務

在 AWS Console 中,導覽至 App Runner 並刪除 HelloAppRunnerVpc 服務

2.第 1 步:刪除 DynamoDB 資料表

導覽至 DynamoDB 並刪除 Weather 資料表

3.刪除容器映像

導覽至 ECR 並刪除 helloapprun nervpc 容器映像。

4.刪除 Cloud9 環境

如果使用 Cloud9,請導覽至 Cloud9 並刪除 AppRunnerLab 環境。

檢查您的工作

您現在應該:

✓ 已刪除 App Runner 服務。

✓ 已刪除了 DynamoDB 資料表。

✓ 已刪除 ECR 容器映像。 

總結

在此實驗中,您建立了一個 DynamoDB 資料並在其中填充了資料。您使用 dotnet new 命令產生了一個 .NET Web 應用程式專案。您對 Web API 進行編碼,使其能夠從 DynamoDB 資料表中擷取天氣資料。您將容器部署到了 ECR。您建立了一個 App Runner 服務來託管該 Web API。您建立了一個 App Runner VPC 連接器並為 DynamoDB 創建了一個 VPC 端點,以連接這兩個可以連接的服務。您對當前託管於 AWS 上的應用程式進行了測試,並看到它可以正常執行。您將更新後的容器部署到了 ECR 並看到它自動部署到了 App Runner 服務。最後,您從 AWS 中取消了應用程式的分配。

本頁對您是否有幫助?

技能評估