DotBPE.RPC快速開始

來源:互聯網
上載者:User

0x00 php.cn/code/10224.html" target="_blank">簡介

DotBPE.RPC是一款基於dotnet core編寫的RPC架構,而它的爸爸DotBPE,目標是實現一個開箱即用的微服務架構,但是它還差點意思,還僅僅在構思和嘗試的階段。但不管怎麼說RPC是微服務的基礎,先來講講RPC的實現吧。DotBPE.RPC底層通訊預設實現基於DotNetty,這是由微軟Azure團隊開發的C#的Netty實現,非常酷。當然你也可以替換成其他Socket通訊組件。DotBPE.RPC使用的預設協議名稱叫Amp,編解碼使用Google的Protobuf3,不過這些預設實現都是可以替換的。

源碼地址:github.com/xuanye/dotbpe.git

0x01 關於Amp協議和Google Protobuf

Amp(A Message Protocol)

Amp(A Message Protocol) ,中文名叫 一個訊息協議 ,是DotBPE.RPC預設實現的訊息協議,在實際開發中,其實是不需要瞭解訊息是如何編解碼和傳輸的,但是瞭解協議有助於進一步瞭解架構。協議基本結構如所示:

      0        1 2 3 4   5 6 7 8     9     10 11     12 13   <length>-14+------------+----------+---------+------+-------+---------+------------+| <ver/argc> | <length> |  <seq>  |<type>|<serId>| <msgid> |   <data>   |+------------+----------+---------+------+-------+---------+------------+

Amp協議預設訊息頭長為14個位元組,不包含擴充包頭
第0位:ver/argc // 為版本號碼,暫時來說,預設為0
第1-4位: length //為包總長度(含包頭長度)
第5-8位: sequence // 為訊息序號,通過該序號對應 請求<--->響應
第9位: type // 訊息類型,現值有5種,如下:

Request = 1, Response = 2, Notify = 3,NotFound = 4, ERROR = 5
第10-11位: serviceId//訊息ID ushort類型
第12-13位: msgId//訊息ID ushort類型
在Amp協議中,serviceId標識一類請求,類似應用中的模組,而msgId標識模組中的具體方法

其後緊跟實際的資料

Google Protobuf

Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言資料標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,183 個 .proto 檔案。他們用於 RPC 系統和持續資料存放區系統。

Protocol Buffers 是一種輕便高效的結構化資料存放區格式,可以用於結構化資料序列化,或者說序列化。它很適合做資料存放區或 RPC 資料交換格式。可用於通訊協議、資料存放區等領域的語言無關、平台無關、可擴充的序列化結構資料格式。目前提供了 多種語言的API,包括C++、 C# 、GO、 JAVA、 PYTHON

我在之前的部落格使用CSharp編寫Google Protobuf外掛程式中有過介紹如果通過編寫外掛程式的方式,來通過定義proto檔案,並產生我們需要的代碼。

在DotBPE.RPC 中,我使用protobuf來作為服務的描述檔案,並通過自訂的外掛程式方式來產生服務端和用戶端代理類。

0x02 快速開始

0. 前提

因為DotBPE是基於dotnet core開發的,你本地必須已經有了dotnet core開發環境
使用githubManaged 程式碼,所以你必須已經安裝了git用戶端
需要通過protoc產生模板代碼,所以你必須已經安裝了google protobuf命令列工具

1. 下載樣本程式

為了能夠解釋我們的快速開始程式,你需要一份本地能夠啟動並執行範例程式碼。從github上下載我已經寫好的範例程式碼,可以讓你快速的搭建程式,免去一些繁瑣,但是又必須的步驟。

>$ # Clone the repository to get the example code:    >$ git clone https://github.com/xuanye/dotbpe-sample.git  >$ cd dotbpe-sample

使用VS2017,或者VSCode開啟下載好的代碼,目錄結構如下所示:

如果你使用VS2017 可以自動幫你還原,如果使用VSCode的話 ,需要運行dotnet restore 下載依賴,成功後使用dotnet build 編譯一下看看結果:看著很完美

2. 運行程式

運行Server

>$ cd HelloDotBPE.Server   >$ dotnet run

運行Client

>$ cd HelloDotBPE.Client   >$ dotnet run

恭喜!已經使用DotBPE.RPC運行一個Server/Client的應用程式。

3. 來一起看一下代碼吧

3.1 服務描述檔案proto

首先是DotBPE.RPC架構中對proto的擴充檔案,所有的項目都需要這個檔案,關於如何擴充proto,我的這篇部落格有比較詳細的介紹,這裡就不重複說了

//dotbpe_option.proto 檔案syntax = "proto3";package dotbpe;option csharp_namespace = "DotBPE.ProtoBuf";import "google/protobuf/descriptor.proto";//擴充服務extend google.protobuf.ServiceOptions {  int32 service_id = 51001;  bool disable_generic_service_client = 51003; //禁止產生用戶端代碼  bool disable_generic_service_server = 51004; //禁止產生服務端代碼}extend google.protobuf.MethodOptions {  int32 message_id = 51002;}extend google.protobuf.FileOptions {  bool disable_generic_services_client = 51003; //禁止產生用戶端代碼  bool disable_generic_services_server = 51004; //禁止產生服務端代碼  bool generic_markdown_doc = 51005; //是否產生文檔 本樣本中無用  bool generic_objectfactory = 51006; //是否產生objectfactory 本樣本中無用}

下面的服務描述檔案 greeter.proto 才是真正的樣本的服務描述檔案:比較簡單,定義一個Greeter Rpc服務,並定義一個Hello的方法

//greeter.protosyntax = "proto3";package dotbpe;option csharp_namespace = "HelloDotBPE.Common";// 引入擴充import public "dotbpe_option.proto";// 定義一個服務service Greeter {  option (service_id)= 100 ;//訊息ID,全域必須唯一  // Sends a greeting  rpc Hello (HelloRequest) returns (HelloResponse) {    option (message_id)= 1 ;//設定訊息ID,同一服務內唯一  }}// The request message containing the user's name.message HelloRequest {  string name = 1;}// The response message containing the greetingsmessage HelloResponse {  string message = 1;}

通過protoc工具產生模板代碼,樣本中的代碼產生到了 HelloDotBPE.Common_g 目錄下,本地可以運行shell命令的同學可以直接到
dotbpe-sample\script\generate 目錄運行sh generate_hello.sh (windows下一般安裝cgywin),不能啟動並執行同學也可以在HelloDotBPE目錄下,直接運行命令列

protoc -I=../protos --csharp_out=./HelloDotBPE.Common/_g/ --dotbpe_out=./HelloDotBPE.Common/_g/   ../protos/dotbpe_option.proto ../protos/greeter.proto  --plugin=protoc-gen-dotbpe=../../tool/protoc_plugin/Protobuf.Gen.exe

當然我還是建議大家安裝以下cgywin運行環境,可以運行unix上的一些常用命令。同時在部署到正式環境的時候可以公用開發環境的一些指令碼。

3.2 服務端代碼

服務實現:

// 服務實現代碼public class GreeterImpl : GreeterBase {    public override Task<HelloResponse> HelloAsync(HelloRequest request)   {        // 直接返回Hello Name       return Task.FromResult(new HelloResponse() { Message = "Hello " + request.Name });   }}

服務端啟動類

 public class Startup : IStartup    {               public void Configure(IAppBuilder app, IHostingEnvironment env)        {                   }        public IServiceProvider ConfigureServices(IServiceCollection services)        {            services.AddDotBPE(); // 添加DotBPE.RPC的核心依賴            services.AddServiceActors<AmpMessage>(actors => {                actors.Add<GreeterImpl>(); // 註冊服務實現            });            return services.BuildServiceProvider();        }    }

啟動服務端

   class Program    {        static void Main(string[] args)        {            Console.OutputEncoding = System.Text.Encoding.UTF8;            //在控制台輸出調試日誌            DotBPE.Rpc.Environment.SetLogger(new DotBPE.Rpc.Logging.ConsoleLogger());            var host = new RpcHostBuilder()                .UseServer("0.0.0.0:6201") //綁定本地連接埠6201                .UseStartup<Startup>()                .Build();            host.StartAsync().Wait();            Console.WriteLine("Press any key to quit!");            Console.ReadKey();            host.ShutdownAsync().Wait();        }    }

3.3 用戶端代碼

 class Program    {        static void Main(string[] args)        {            Console.OutputEncoding = Encoding.UTF8;            var client = AmpClient.Create("127.0.0.1:6201"); //建立連結通道            var greeter = new GreeterClient(client); //用戶端代理類                       while (true)            {                Console.WriteLine("input your name and press enter:");                string name = Console.ReadLine();                if ("bye".Equals(name))                {                    break;                }                try                {                    var request = new HelloRequest() { Name = name };                    var result = greeter.HelloAsync(request).Result;                                      Console.WriteLine($"---------------receive form server:{result.Message}-----------");                                                    }                catch (Exception ex)                {                    Console.WriteLine("發生錯誤:" + ex.Message);                }            }            Console.WriteLine($"---------------close connection-----------");            client.CloseAsync();        }    }

0x03 下一步

下一篇 我將詳細講述DotBPE.RPC中的主要類和調用關係,並介紹如何使用DotNetty實現RPC通訊。
事實上我正在編寫一個更加複雜的樣本https://github.com/xuanye/PiggyMetrics.git,
這原是spring cloud的一個樣本程式,我使用DotBPE進行改造,用樣本描述DotBPE在真實情境中的應用。包括服務註冊和發現,服務間調用,公開HttpApi,監控檢查等功能,並通過實踐進一步完善DotBPE。初步的功能已經實現,不過還沒來的及寫文檔。該系列的後面將詳細描述該系統的實現。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.