日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Redola.Rpc 集成 Consul 服务发现

發布時間:2023/12/4 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redola.Rpc 集成 Consul 服务发现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Redola.Rpc 解決了什么問題?

Redola.Rpc 是一個使用 C# 開發的 RPC 框架,代碼開源在?GitHub?上。目前版本僅支持?.NET Framework 4.6?以上版本,未來待系統穩健后再考慮移植?.NET Standard?和?.NET Core。

Redola.Rpc?在 0.3.2 版本中,嘗試解決幾個 RPC 設計問題:

  • 我是誰?(Local Actor)

  • 如何告訴別人我是誰?(Actor Directory)

  • 我提供什么服務?(Service Catalog Provider)

  • 如何告訴別人我提供什么服務?(Service Directory)

  • 我需要的服務在哪里?(Service Discovery)

  • 如何調用該服務?(Service Dynamic Proxy)

  • 如何找到該服務?(Actor Directory)

  • 如何發消息給該服務?(Remote Actor)

Actor 是什么?

Redola 定義的 Actor 模型代表著一個通信節點,使用 ActorIdentity 描述,包括節點類型 Type、節點名稱 Name、節點地址 Address、節點端口 Port。

Actor 與 Actor 之間是基于 TCP Socket 通信的,Actor 并不區分 TCP 的 Server/Client 端,它將 Server 和 Client 封裝在底層,為上層應用提供更便捷的傳輸定義和調用接口。Actor 模型提供了面向通道 Channel 的雙工通道,可以接收來自對端的消息,也可以發送消息給對端。

Actor 收發的消息是面向二進制數組的,它不關心具體發送的是什么消息,也不關心序列化格式。Actor 使用 ActorFrameHeader 定義傳輸消息頭,Header 攜帶消息體長度。

Actor 一旦建立連接,生成的?Channel 通道會自動進行 KeepAlive 雙向?;顧C制。通過 Actor 服務發現,可以與任意的 Actor 進行通信,無需再配置對端節點地址和端口。并且,針對相同 Type 的 Actor,還可以實現消息分發的負載均衡功能。

RPC 契約定義

Redola.Rpc?是基于契約模型通信的,使用?Protobuf 2?格式定義 IDL,并通過自動生成工具生成 Contract 契約定義。

例如,下面是定義 ICalcService 服務的 IDL 定義。

package Redola.Rpc.TestContracts;message AddRequest {required int32 X = 10;required int32 Y = 20; }message AddResponse {required int32 Result = 10; }service CalcService {rpc Add (AddRequest) returns (AddResponse); }

上述 IDL 生成的 ICalcService 接口定義為:

public interface ICalcService {AddResponse Add(AddRequest request); }

RPC 消息序列化

Redola.Rpc 選擇使用 Protobuf 2 進行消息序列化,默認集成?protobuf-net?類庫,穩定使用 protobuf-net?v2.0.0.668?版本。

RPC 消息信封

使用 ActorMessageEnvelope 封裝消息信封,攜帶如下信息:

? 屬性名稱

?屬性類型?

?屬性描述?

?MessageID

string

?消息 ID,唯一 ID,通常使用 GUID。

?MessageTime

DateTime

?消息產生時間

?CorrelationID

string

?如果是 Response 則回填 Request 的 MessageID。?

?CorrelationTime?

DateTime?

?如果是 Response 則回填 Request 的 MessageTime。

?SourceEndpoint?

?ActorEndpoint??發送端節點描述,消息路由使用,默認不需要填寫。

?TargetEndpoint

ActorEndpoint?目的端節點描述,消息路由使用,默認不需要填寫。?

?MessageType

string?消息類型,使用字符串描述。

?MessageData

byte[]?消息體,消息序列化后的二進制數組。

RPC 消息定義

RPC 消息分為 2 類:

  • InvokeMethodRequest / InvokeMethodResponse?用于定義請求回復模型的方法調用;

  • InvokeMethodMessage?用于定義請求無回復模型的方法調用;

  • 通常 RPC 消息會包含如下屬性信息:

    ? 屬性名稱

    ?屬性類型?

    ?屬性描述?

    ?MethodLocator

    string

    ?RPC 方法描述,使用字符串描述。

    ?MethodArguments?

    object[]

    ?RPC 方法的入參,object 對象數組。

    例如,對于 ICalcService 中的 Add 方法:

    • MethodLocator = "Rodola.Rpc.TestContracts.ICalcService/Add_AddRequest";

    • MethodArguments = new object[] { new AddRequest(1, 2)};

    鑒于 protobuf 本身是面向契約設計的,而 object[] 中的 object 是有不確定性的,并不能具體描述一個契約,則要求每一個 Argument 都需要支持 protobuf 的序列化,傳輸時系統會攜帶該 Argument 類型的?AssemblyQualifiedName,在對端通過反射進行反序列化。

    Actor Directory 節點目錄

    Actor Directory 負責注冊本地 Local Actor 到注冊中心,Local Actor 也可以在 Shutdown 時將自己從注冊中心移除掉。

    通過 Actor Directory,Local Actor 可以使用?Type 和 Name 進行 Remote Actor 的檢索,進而進行 Channel 的建立和通信。

    Actor Directory 通過 IActorDirectory 的抽象定義,可以與不同的目錄方案進行集成。例如,自實現基于 Actor 的 CenterActorDirectory,使用 XML 配置文件的 LocalXmlFileActorDirectory,使用 Consul 進行中心注冊的 ConsulActorDirectory。

    使用 Consul 時,實際上是調用了?Consul HTTP API?中的 Agent Register Service 接口 '/v1/agent/service/register',通過指定 ServiceID 和 ServiceName 進行注冊。

    通過如下 cmd 啟動 Consul Server 和 Consul Agent。

    consul.exe agent -config-dir "C:\Consul\config\server-01" -bootstrap -ui consul.exe agent -config-dir "C:\Consul\config\client-01" -join 192.168.1.133:7774 -ui

    下面為啟動本地 Consul 進行測試的配置文件。

    server-01.json

    {
    ?
    "datacenter": "dc1",
    ?
    "data_dir": "C:\\Consul\\data\\server-01",
    ?
    "log_level": "INFO",
    ?
    "node_name": "server-01",
    ?
    "server": true,
    ?
    "ports": { ?
    ?
    "http": 7771, ?
    ?
    "rpc": 7772, ?
    ?
    "dns": 7773, ?
    ?
    "serf_lan": 7774, ?
    ?
    "serf_wan": 7775, ?
    ?
    "server": 7776} }


    client-01.json

    { ?
    "datacenter": "dc1",
    ?
    "data_dir": "C:\\Consul\\data\\client-01",
    ?
    "log_level": "INFO",
    ?
    "node_name": "client-01",
    ?
    "ports": { ?
    ?
    "http": 8881, ?
    ?
    "rpc": 8882, ?
    ?
    "dns": 8883, ?
    ?
    "serf_lan": 8884, ?
    ?
    "serf_wan": 8885, ?
    ?
    "server": 8886} }


    Service Catalog Provider 服務提供者

    作為 RPC Service 的 Provider 提供方,需要顯式定義指定 Contract 的服務實例。例如,下面將不同的服務契約與服務實例進行了注冊。

    var serviceCatalog = new ServiceCatalogProvider(); serviceCatalog.RegisterService<IHelloService>(new HelloService()); serviceCatalog.RegisterService<ICalcService>(new CalcService()); serviceCatalog.RegisterService<IOrderService>(new OrderService());

    實際上,可以通過對于 IServiceCatalogProvider 接口的不同實現,進行不同方式的本地服務發現和注冊。例如,可以使用?Attribute 標記服務,通過對 Assembly 進行反射進行服務的實例化。

    Service Directory 服務目錄

    本地服務聚集到 Catalog 中后,系統會將服務逐個注冊到 Service Directory 服務目錄中,使得其他節點可以檢索服務進行使用。

    通過 IServiceDirectory 的抽象定義,可以與不同的目錄方案進行集成。例如,使用 XML 配置文件的 LocalXmlFileServiceDirectory,使用 Consul 進行中心注冊的 ConsulServiceDirectory。

    使用 Consul 時,注冊服務的 log 如下所示。

    當 Redola 將服務注冊至 Consul 中后,可通過 Consul 內置的 UI 進行查看。

    http://localhost:8881/ui/#/dc1/services

    Service Discovery 服務發現

    通過 ConsulServiceDiscovery 實現 IServiceDiscovery 服務發現接口,從?Consul?檢索指定服務類型的服務。

    通過 Postman 測試 GET?/v1/catalog/services,得到如下 JSON 數據。

    http://localhost:8881/v1/catalog/services


    { ?
    ?
    "Redola.Rpc.TestContracts.ICalcService": [], ? ?"Redola.Rpc.TestContracts.IHelloService": [], ? ?"Redola.Rpc.TestContracts.IOrderService": [], ? ?"consul": [], ? ?"server": [] }


    通過 Postman 測試 GET?/v1/catalog/service,得到如下 JSON 數據。

    http://localhost:8881/v1/catalog/service/Redola.Rpc.TestContracts.ICalcService


    [{ ? ? ?
    ?
    "ID": "359e8dfe-262d-6eb7-260c-e6e3ad208a14", ?
    ? ? ?
    "Node": "client-01", ?
    ? ? ?
    "Address": "192.168.1.133", ?
    ? ? ?
    "Datacenter": "dc1", ? ? ?
    ? ??
    "TaggedAddresses": { ? ? ?
    ? ? ?
    "lan": "192.168.1.133", ? ? ?
    ? ? ?
    "wan": "192.168.1.133"}, ? ? ? ?"NodeMeta": {}, ?
    ? ? ?
    "ServiceID": "redola/server/server-33333/Redola.Rpc.TestContracts.ICalcService", ? ? ? ?"ServiceName": "Redola.Rpc.TestContracts.ICalcService", ? ? ? ?"ServiceTags": [], ? ?
    ? ?
    "ServiceAddress": "localhost", ?
    ? ? ?
    "ServicePort": 33333, ? ? ? ?"ServiceEnableTagOverride": true, ? ?
    ? ?
    "CreateIndex": 2147, ? ? ?
    ?
    "ModifyIndex": 2151} ]

    服務檢索方,可通過指定?IServiceLoadBalancingStrategy 的具體實現實施不同的負載均衡策略,默認指定的是?IServiceLoadBalancingStrategy 隨機選擇。

    Service Dynamic Proxy 動態代理

    為簡化?RPC 調用發起方的封裝,通常會使用 Dynamic Proxy 動態代理技術來動態生成給定契約的服務實例,將整體 RPC 的過程透明化。

    例如,通過下面的代碼來動態生成 ICalcService 的動態代理。

    var calcClient = rpcNode.Resolve<ICalcService>();

    目前 Redola.Rpc 默認集成了?Castle.Core?中的?Dynamic Proxy?模塊,通過對實例方法的 Intercept 攔截進行 RPC 消息的收發處理。

    當然,如需集成其他 Dynamic Proxy 類庫,可通過 ISeviceProxyGenerator 接口進行方案實現。

    Redola.Rpc 類庫依賴

    Redola.Rpc 當前實現依賴了如下開源類庫。

    <?xml version="1.0" encoding="utf-8"?><packages><package id="Consul" version="0.7.2.3" targetFramework="net46" /><package id="Cowboy.Sockets" version="1.3.14.0" targetFramework="net46" /><package id="protobuf-net" version="2.0.0.668" targetFramework="net46" /><package id="Castle.Core" version="4.1.0" targetFramework="net46" /><package id="Logrila.Logging" version="1.0.3.0" targetFramework="net46" /><package id="Logrila.Logging.NLogIntegration" version="1.0.3.0" targetFramework="net46" /><package id="NLog" version="4.2.3" targetFramework="net46" /></packages>


    總結

    以上是生活随笔為你收集整理的Redola.Rpc 集成 Consul 服务发现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。