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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core 使用 grpc 实现微服务

發布時間:2023/12/4 asp.net 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core 使用 grpc 实现微服务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

GRPC 是Google發布的一個開源、高性能、通用RPC(Remote Procedure Call)框架。提供跨語言、跨平臺支持。以下以一個.NET Core Console項目演示如何使用GRPC框架。

一、定義服務

通過proto定義一個數學計算服務,其中包括兩個服務方法(Add, Multipy)以及4個請求響應對象(AddRequest, AddReply, MultiplyRequest, MultiplyReply)。

// 文件名:mathservice.protosyntax = "proto3"; option java_multiple_files = false; option java_package = "MathServices"; option java_outer_classname = "MathServicesProto"; option objc_class_prefix = "MathServices";
package MathServices;// 數學運算服務service MathService { ?
? ? rpc Add (AddRequest) returns (AddReply) {} ?rpc Multiply (MultiplyRequest)
? ?returns (MultiplyReply)
{} } message AddRequest { ?double First = 1; ?double Second = 2; } message AddReply { ?double Sum = 1; } message MultiplyRequest { ?double First = 1; ?double Second = 2; } message MultiplyReply { ?double Result = 1; }

二、將服務編譯成存根(stub)

通過以下批處理命令generate_protos.bat將服務定義生成多種語言和平臺版本的客戶端和服務端存根。

@rem 生成客戶端和服務器端存根setlocal@rem 進入當前目錄 cd /d %~dp0set TOOLS_PATH=C:\Users\Freeman\.nuget\packages\Grpc.Tools\1.0.0\tools\windows_x86 %TOOLS_PATH%\protoc.exe ^--proto_path protos ^--cpp_out=Interfaces/cpp ^--csharp_out=Interfaces/csharp ^--java_out=Interfaces/java ^--js_out=Interfaces/javascript ^--grpc_out=Interfaces/csharp ^--plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe ^protos/mathservice.proto endlocaltimeout 5

針對CSHARP語言,protoc.exe編譯器生成了如下圖幾個類,其中左邊4個類用于構造請求和響應對象,MathService類用于下一步構造服務和消費服務。


CSHARP STUBS

三、實現并運行服務

通過上一步的編譯,自動生成了MathService類,下面通過該類構造并啟動grpc服務。

通過繼承基類實現服務接口

? ?/// <summary>/// 實現RPC服務端接口。/// </summary>public class MathServiceImpl : MathService.MathServiceBase{public override Task<AddReply> Add(AddRequest request, ServerCallContext context){ ? ? ? ?
? ? ? ? ? ? return Task.FromResult(new AddReply { Sum = request.First + request.Second });}public override Task<MultiplyReply> Multiply(MultiplyRequest request, ServerCallContext context){ ? ? ? ?
? ? ? ? ? ? ?return Task.FromResult(new MultiplyReply { Result = request.First * request.Second });}}

啟動服務

const string ip = "0.0.0.0";const int port = 50051; Server server = new Server(); server.Ports.Add(new ServerPort(ip, port, ServerCredentials.Insecure)); server.Services.Add(MathService.BindService(new MathServiceImpl())); server.Start(); server.Ports.ToList().ForEach(a => Console.WriteLine($"Server listening on port {a.Port}...")); Console.ReadLine();

四、客戶端調用服務

客戶端通過創建一個Channel和一個服務客戶端來使用服務。

var channel = new Channel($"{"127.0.0.1"}:{port}", SslCredentials.Insecure);
var client = new MathService.MathServiceClient(channel);
var random = new Random();while (true) { ? ?var first = random.NextDouble(); ? ?
? ? ? var second = random.NextDouble(); ?
? ? ?var reply = client.Add(new AddRequest { First = first, Second = second }); ?
? ? ?Console.WriteLine($"RPC call Add service: {first:F4} + {second:F4} = {reply.Sum:F4}"); ? ?Thread.Sleep(500); }


RPC調用

五、使用SSL實現加密通訊

grpc默認實現了基于證書的SSL加密通訊,使用中需要注意以下事項。

  • 在Windows上開發請安裝 OpenSSL對應版本并將openssl.exe所在路徑添加到環境變量中。

  • 通過以下樣例腳本生成通訊中所需要的服務端和客戶端證書,其中需要特別注意的是,Generate server signing request:中的CN=KEKYK字段如果是本機測試,請一定使用本機名稱,如果是真實環境請使用域名,因為客戶端必須通過機器名(本地測試)或域名訪問該服務。如果此處CN字段不使用機器名或域名,將導致以下錯誤:


    CN字段不使用主機名或域名時產生的錯誤

  • 生成服務端和客戶端證書腳本generate_ssl.bat

@echo offset OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.cfg ? echo Generate CA key: openssl genrsa -passout pass:1111 -des3 -out ca.key 4096echo Generate CA certificate: openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj ?"/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=MyRootCA"echo Generate server key: openssl genrsa -passout pass:1111 -des3 -out server.key 4096echo Generate server signing request: openssl req -passin pass:1111 -new -key server.key -out server.csr -subj ?"/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=kekyk"echo Self-sign server certificate: openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt echo Remove passphrase from server key: openssl rsa -passin pass:1111 -in server.key -out server.keyecho Generate client keyopenssl genrsa -passout pass:1111 -des3 -out client.key 4096echo Generate client signing request: openssl req -passin pass:1111 -new -key client.key -out client.csr -subj ?"/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=client"echo Self-sign client certificate: openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt echo Remove passphrase from client key: openssl rsa -passin pass:1111 -in client.key -out client.keypause
  • 基于SSL的服務端啟動如下,創建服務的時候請使用主機名(開發環境)或域名(生產環境),不要使用IP地址。

    public static void RpcServerSsl() { ?
    ? ?var cacert = File.ReadAllText(CombinePath("ca.crt"));
    ??var servercert = File.ReadAllText(CombinePath("server.crt")); ?
    ?? ? ?var serverkey = File.ReadAllText(CombinePath("server.key"));
    ?var keypair = new KeyCertificatePair(servercert, serverkey);
    ? ?var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair>()
    ? ? ? { keypair }, cacert, false); ?
    ? ? ? var server = new Server{Services = { MathService.BindService(new MathServiceImpl()) },Ports = { new ServerPort("KEKYK", sslPort, sslCredentials) }};server.Start();server.Ports.ToList().ForEach(a => Console.WriteLine($"Server (SSL) listening on port {a.Port}..."));Console.ReadLine(); }
  • 基于SSL的客戶端使用如下,注意測試環境中使用主機名,生產環境中使用域名來,不要使用任何形式的IP地址。

    public static void RpcClientSsl(){ ?
    ? var cacert = File.ReadAllText(CombinePath("ca.crt"));
    ? var clientcert = File.ReadAllText(CombinePath("client.crt"));
    ? ?var clientkey = File.ReadAllText(CombinePath("client.key")); ?
    ? ? var ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey));
    ? var channel = new Channel("KEKYK", sslPort, ssl); ?
    ? ? var client = new MathService.MathServiceClient(channel); ?
    ? var random = new Random(); ?while (true){ ? ? ?
    ? ? ? ? var first = random.NextDouble(); ?
    ? ?? ?var second = random.NextDouble(); ? ? ?
    ? ?? ? ? ? ? ? var reply = client.AddAsync(new AddRequest { First = first, Second = second },
    ? ? ? ? ? new CallOptions()).ResponseAsync.Result;Console.WriteLine($"RPC call Add service: {first:F4} + {second:F4} = {reply.Sum:F4}");Thread.Sleep(1000);} }

原文地址:http://www.jianshu.com/p/f5e1c002047a


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的.NET Core 使用 grpc 实现微服务的全部內容,希望文章能夠幫你解決所遇到的問題。

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