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 实现微服务相关推荐

  1. ASP.NET Core基于K8S的微服务电商案例实践--学习笔记

    摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...

  2. 简单事务:.NET Core应用程序的微服务示例体系结构

    目录 介绍 应用架构 微服务设计 安全性:基于JWT令牌的身份验证 开发环境 技术 使用的开源工具 云平台服务 数据库设计 WebApi终端 通过API网关配置和访问终端 在微服务级别实现终端 解决方 ...

  3. Spring Boot+gRPC构建微服务并部署到Istio(详细教程)

    点击关注公众号,实用技术文章及时了解 作为Service Mesh和云原生技术的忠实拥护者,我却一直没有开发过Service Mesh的应用.正好最近受够了Spring Cloud的"折磨& ...

  4. 用gRPC建设微服务,Proto 怎么管理更合适

    虽然我朋友他们已经从大单体切换为微服务化有一定的年头了,但一些细节方面的处理总会有不同的人有不同的看法. 而且时不时就会有人出来反复问,这其中的一个重要讨论点,就是 Proto 这个 IDL 的代码到 ...

  5. 微服务统计,分析,图表,监控, 分布式追踪一体化的 HttpReports 在 .Net Core 的应用...

    前言介绍 HttpReports 是针对.Net Core 开发的轻量级APM系统,基于MIT开源协议, 使用HttpReports可以快速搭建.Net Core环境下统计,分析,图表,监控,分布式追 ...

  6. 【.net core】电商平台升级之微服务架构应用实战

    一.前言 这篇文章本来是继续分享IdentityServer4 的相关文章,由于之前有博友问我关于微服务相关的问题,我就先跳过IdentityServer4的分享,进行微服务相关的技术学习和分享.微服 ...

  7. 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发...

    <ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...

  8. 构建简单的微服务架构

    前言 本篇仅作引导,内容较多,如果阅读不方便,可以使用电脑打开我们的文档官网进行阅读.如下图所示: 文档官网地址:docs.xin-lai.com 目录 总体介绍   微服务架构的好处    微服务架 ...

  9. 构建自己的简单微服务架构(开源)

    构建自己的简单微服务架构(开源) 原文:构建自己的简单微服务架构(开源) 前言 本篇仅作引导,内容较多,如果阅读不方便,可以使用电脑打开我们的文档官网进行阅读.如下图所示: 文档官网地址:https: ...

最新文章

  1. Java线程怎样映射到操作系统线程
  2. 《编码的奥秘》---学习编程一年半的体会
  3. leetcode1237. 找出给定方程的正整数解(二分法)
  4. 相对、绝对、固定定位,以及其层级关系和脱离文档流的影响
  5. Ubuntu18.04下安装配置ORB_SLAM2以及过程中遇到的问题解决方法
  6. 管理感悟:每次争吵后要有进步
  7. Windows XP 优化设置注册文件集合(共80项,请谨慎使用)
  8. CrossApp更新至0.3.3,推出JS体验版
  9. 多模态理论张德禄_专家观点||张德禄:系统功能理论视阈下的多模态话语分析综合框架...
  10. Python爬虫-国家企业信用信息公示系统App
  11. ps命令查看进程详解
  12. 英语,对程序员有多重要?
  13. halcon 二值图像处理 区域的细化 skeleton
  14. 【摘录】Ubuntu 10.10编译Android froyo可能需要注意的几个地方
  15. 8.1 Handling Relationships
  16. TCO-PNB ester,1438415-89-4, 反式环辛烯-对硝基苯
  17. LibreOffice SDK 开发环境配置(Windows)
  18. matlab 多相滤波,数字多相网络的滤波原理
  19. 兼职程序员一般可以从什么平台接私活?
  20. 三坐标测量机误差产生的主要原因及解决方法

热门文章

  1. Resin的安全性ip限制
  2. 51单片机实现4位数以内的加减法
  3. [reship]某类领导
  4. Task.Factory.StartNewTResult 和 Task.RunTResult 到底有什么区别?
  5. 一起来庆祝 .NET 20 周年!
  6. .Net Core with 微服务 - Seq 日志聚合
  7. 前端老弟第一次写后端,崩了!
  8. IComparer与IEqualityComparer的简单使用
  9. 谈到云原生, 绕不开容器化
  10. 推荐:.Net 5开源免费的内容管理系统