使用 Tye 輔助開發 k8s 應用竟如此簡單(三)

Newbe36524發表於2021-02-19

續上篇,這篇我們來進一步探索 Tye 更多的使用方法。本篇我們來了解一下如何在 Tye 中如何對資料庫進行連結。

Newbe.Claptrap 是一個用於輕鬆應對併發問題的分散式開發框架。如果您是首次閱讀本系列文章。建議可以先從本文末尾的入門文章開始瞭解。

中介軟體連結

絕大多數服務都需要用到外部中介軟體來支援應用程式的正常執行,通常來說,就包含有資料庫、快取中介軟體、訊息佇列和檔案系統等等。

因此,在開發過程中需要在應用程式中管理對這些中介軟體的連結字串。

Tye 提供了一種方式以便更加容易的管理這些連結字串。

使用 Tye 啟動 mongo

首先,我們使用 Tye 來啟動一個 mongo。

手動建立一個 tye.yml:

tye.yml

name: mongo-sample
services:
  - name: mongo
    image: mongo
    env:
      - name: ME_CONFIG_MONGODB_ADMINUSERNAME
        value: root
      - name: ME_CONFIG_MONGODB_ADMINPASSWORD
        value: example
  - name: mongo-express
    image: mongo-express
    bindings:
      - port: 8081
        containerPort: 8081
        protocol: http
    env:
      - name: ME_CONFIG_MONGODB_ADMINUSERNAME
        value: root
      - name: ME_CONFIG_MONGODB_ADMINPASSWORD
        value: example

使用 tye run 便可以在本地啟動一個 mongo 並且在 http://localhost:8081 通過 ui 檢視 mongo 中的資料情況:

mongo express

實際上就是使用 Tye 控制 docker desktop 啟動 mongo。因此需要提前在本地安裝好 docker desktop,以便啟動。

當然,這實際上和使用 docker-compose 沒有什麼實質性的區別。

建立應用程式連線 mongo

下面,我們建立一個應用,並且將應用與 mongo 進行連線。

建立測試應用,並安裝必要的包:

create-tye-mongo-test.sh

dotnet new sln -n TyeTest
dotnet new webapi -n TyeTest
dotnet sln ./TyeTest.sln add ./TyeTest/TyeTest.csproj
dotnet add ./TyeTest/TyeTest.csproj package Microsoft.Tye.Extensions.Configuration --version 0.6.0-alpha.21070.5
dotnet add ./TyeTest/TyeTest.csproj package MongoDB.Driver

進入 Startup,向容器中註冊 MongoClient :

Startup.cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo {Title = "TyeTest", Version = "v1"}); });
    services.AddScoped(p =>
    {
        var config = p.GetRequiredService<IConfiguration>();
        var connectionString = config.GetConnectionString("mongo");
        Console.WriteLine(connectionString);
        var client = new MongoClient(connectionString);
        return client;
    });
}

值得注意的是,這裡使用了一個擴充套件方法從 IConfiguration 中讀取 mongo 的連線字串:

  1. mongo 實際上就是定義在 tye 中的服務名稱。
  2. GetConnectionString 是來自於 Microsoft.Tye.Extensions.Configuration 的擴充套件方法
  3. MongoClient 應該全域性單例還是 Scope 其實筆者也沒查過資料。實際專案開發者注意按照需求調整。

開啟 WeatherForecastController,讓我們在每次接受請求時,都寫入一些資料到 mongo 中以驗證效果。

WeatherForecastController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;

namespace TyeTest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;
        private readonly MongoClient _mongoClient;

        public WeatherForecastController(ILogger<WeatherForecastController> logger,
            MongoClient mongoClient)
        {
            _logger = logger;
            _mongoClient = mongoClient;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            var result = Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();

            var mongoCollection = _mongoClient.GetDatabase(nameof(WeatherForecast))
                .GetCollection<WeatherForecast>(nameof(WeatherForecast));
            mongoCollection.InsertMany(result);
            return result;
        }
    }
}

至此,測試應用就建立完畢了。預期的效果是,當接受到請求時,就會向 mongo 中的 WeatherForecast collection 寫入一些資料。可以通過 mongo express UI 進行檢視。

修改 tye.yml 以配置連結串

由於前面,我們是手動建立過了 tye.yml。因此,我們現在直接在原來的基礎上進行修改,以便加入測試應用。

首先,將之前建立好的 tye.yml 放置到 TyeTest.sln 的根目錄。

然後修改為如下形式:

tye.yml

name: mongo-sample
services:
  - name: mongo
    image: mongo
    env:
      - name: ME_CONFIG_MONGODB_ADMINUSERNAME
        value: root
      - name: ME_CONFIG_MONGODB_ADMINPASSWORD
        value: example
    bindings:
      - containerPort: 27017
        connectionString: 'mongodb://${host}:${port}'
  - name: mongo-express
    image: mongo-express
    bindings:
      - port: 8081
        containerPort: 8081
        protocol: http
    env:
      - name: ME_CONFIG_MONGODB_ADMINUSERNAME
        value: root
      - name: ME_CONFIG_MONGODB_ADMINPASSWORD
        value: example
  - name: tyetest
    project: TyeTest/TyeTest.csproj

對比之前,一共有兩處修改:

  1. 增加了 tyetest 服務配置的節點,以便能夠啟動測試應用
  2. 在 mongo 服務上增加了 bindings。這是 tye 中組織服務之間相互連線的一種方式。其中的 connectionString 便是其他服務連線 mongo 所使用的連結串。

修改完畢之後。使用 tye run 啟動應用。

開啟 swagger 頁面,並訪問 API,便可以在 mongo express 中檢視到資料已經成功完成了寫入:

mongo express 2

檢視效果之後可以使用 Ctrl+C 停止 tye 以移除相關容器。

最後,發到 K8S 裡面試一下

這次的樣例,並不是直接使用 tye deploy 就可以完成了。

首先,通常來說,中介軟體在生產環境中不太可能是通過部署在容器中的方式而存在的。即便是使用容器部署,也不會每次 deploy 都希望重新部署。也就是說,通常是直接連線已有的中介軟體就可以了。

其次,中介軟體連線字串通常來說是以 secret 的形式存於 k8s 中。故而不太可能在 tye 指令碼中進行指定。

故而,tye 僅僅會幫助開發者檢查需要部署的目標叢集中是否已經存在符合要求的 secret。當且僅當,目標叢集中存在符合要求的 secret 才能部署。

以本示例為例,需要在目標叢集中存在 binding-production-mongo-secret 對應的 secret 才能都實現使用 tye 進行部署。

具體的名稱約定規則,可以參照如下內容:

https://github.com/dotnet/tye/blob/master/docs/reference/deployment.md#validate-secrets

小結

本篇,我們已經順利完成了使用 Tye 來完成應用與中介軟體之間的連結配置。

不過還遺留一些問題沒有細說:

  • 如果一箇中間存在多個繫結該如何處理
  • https 繫結該如何處理

詳細這些內容,請移步官方文件進行檢視:

https://github.com/dotnet/tye/blob/master/docs/reference/service_discovery.md

下一篇,我們將進一步在 Tye 中實現對紛繁複雜的日誌進行統一管理。

最後但是最重要!

如果讀者對該內容感興趣,歡迎轉發、評論、收藏文章以及專案。

最近作者正在構建以 Actor 模式 和 事件溯源 為理論基礎的一套服務端開發框架。希望為開發者提供能夠便於開發出 “分散式”、“可水平擴充套件”、“可測試性高” 的應用系統 ——Newbe.Claptrap

本篇文章是該框架的一篇技術選文,屬於技術構成的一部分。

專案文件庫:claptrap.newbe.pro

聯絡方式: QQ 群 610394020

您還可以查閱本系列的其他選文:

理論入門篇

  1. Newbe.Claptrap - 一套以 “事件溯源” 和 “Actor 模式” 作為基本理論的服務端開發框架

術語介紹篇

  1. Actor 模式
  2. 事件溯源(Event Sourcing)
  3. Claptrap
  4. Minion
  5. 事件 (Event)
  6. 狀態 (State)
  7. 狀態快照 (State Snapshot)
  8. Claptrap 設計圖 (Claptrap Design)
  9. Claptrap 工廠 (Claptrap Factory)
  10. Claptrap Identity
  11. Claptrap Box
  12. Claptrap 生命週期(Claptrap Lifetime Scope)
  13. 序列化(Serialization)
  14. 最小競爭資源 (Minimal Competing Resources)

樣例實踐篇

  1. 設計一個火車票銷售系統

開發工具篇

  1. 使用 Tye 輔助開發 k8s 應用竟如此簡單(一)
  2. 使用 Tye 輔助開發 k8s 應用竟如此簡單(二)
  3. 使用 Tye 輔助開發 k8s 應用竟如此簡單(三)
  4. 使用 Tye 輔助開發 k8s 應用竟如此簡單(四)
  5. 使用 Tye 輔助開發 k8s 應用竟如此簡單(五)
  6. 使用 Tye 輔助開發 k8s 應用竟如此簡單(六)

其他番外篇

  1. 談反應式程式設計在服務端中的應用,資料庫操作優化,從 20 秒到 0.5 秒
  2. 談反應式程式設計在服務端中的應用,資料庫操作優化,提速 Upsert
  3. 十萬同時線上使用者,需要多少記憶體?——Newbe.Claptrap 框架水平擴充套件實驗
  4. docker-mcr 助您全速下載 dotnet 映象
  5. 十多位全球技術專家,為你獻上近十個小時的.Net 微服務介紹
  6. 年輕的樵夫喲,你掉的是這個免費 8 核 4G 公網伺服器,還是這個隨時可用的 Docker 實驗平臺?
  7. 如何使用 dotTrace 來診斷 netcore 應用的效能問題
  8. 只要十步,你就可以應用表示式樹來優化動態呼叫

GitHub 專案地址:https://github.com/newbe36524/Newbe.Claptrap

Gitee 專案地址:https://gitee.com/yks/Newbe.Claptrap

您當前檢視的是先行釋出於 www.newbe.pro 上的部落格文章,實際開發文件隨版本而迭代。若要檢視最新的開發文件,需要移步 claptrap.newbe.pro

Newbe.Claptrap

------ 本文結束 ------

相關文章