网站建设营销的公司,佛山外包网站建设,新建的网站需要维护吗,广州花都网站开发微服务间通信常见的两种方式由于微服务架构慢慢被更多人使用后#xff0c;迎面而来的问题是如何做好微服务间通信的方案。我们先分析下目前最常用的两种服务间通信方案。gRPC#xff08;rpc远程调用#xff09;场景#xff1a;A服务主动发起请求到B服务#xff0c;同步方式… 微服务间通信常见的两种方式由于微服务架构慢慢被更多人使用后迎面而来的问题是如何做好微服务间通信的方案。我们先分析下目前最常用的两种服务间通信方案。gRPCrpc远程调用场景A服务主动发起请求到B服务同步方式范围只在微服务间通信应用EventBus基于消息队列的集成事件技术NotNetCore.Cap Rabbitmq Database场景A服务要在B服务做某件事情后响应异步方式实现B服务在完成某件事情后发布消息A服务订阅此消息范围只在微服务间通信应用通过对比两种方式完全不一样。rpc是类似于http请求的及时响应机制但是比http更轻量、快捷它更像以前的微软的WCF可以自动生成客户端代码充分体现了面向实体对象的远程调用的思想Eventbus是异步的消息机制基于cap的思想不关心下游订阅方服务是否消费成功保障了主服务业务的流畅性同时也是一款分布式事务的实现方案可以保障分布式架构中的数据的最终一致性。我们今天主要介绍gRPC在微服务中的实践案例。gRPC-Server服务端框架介绍.Net Core sdk 3.1Grpc.AspNetCore 2.30.0Grpc.Core 2.30.0搭建步骤以.net core webapi 项目为例详细说明如何集成gRPC。创建项目创建web api项目此步骤说明省略引入nuget包引入gRPC 服务端需要的 nuget包Grpc.AspNetCore 2.30.0和Grpc.Core 2.30.0外部访问考虑到项目发布后有webapi本身的http的接口和gRPC的接口都要给外部访问就需要暴露http1和http2两个端口。方式1本地调试时可以直接暴露http和https如果你的服务器支持https也可以在生产环境使用https来访问gRPC服务。public static IWebHostBuilder CreateWebHostBuilder(string[] args) WebHost.CreateDefaultBuilder(args).UseStartupStartup().UseNLog().UseUrls(http://*:5000;https://*:5001);
方式2如果在容器化部署场景下一般会在dockerfile中指定ASPNETCORE_PORT环境变量然后程序监听http1和http2两个端口。 public static IHostBuilder CreateHostBuilder(string[] args) Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder {var aspnetcorePort Environment.GetEnvironmentVariable(ASPNETCORE_PORT) ?? 5000;int.TryParse(aspnetcorePort, out int port);webBuilder.ConfigureKestrel(options {options.ListenAnyIP(port, options options.Protocols HttpProtocols.Http1);options.ListenAnyIP(port 1, options options.Protocols HttpProtocols.Http2);}).UseStartupStartup();webBuilder.UseNLog();});
异常处理由于gRPC服务端只能throw 基于 Grpc.Core.RpcException 的异常类型所以我们可以自定义中间件来统一处理下异常using Grpc.Core;
using Grpc.Core.Interceptors;
using System;
using System.Threading.Tasks;public class ExceptionInterceptor : Interceptor{public override async TaskTResponse UnaryServerHandlerTRequest, TResponse(TRequest request,ServerCallContext context,UnaryServerMethodTRequest, TResponse continuation){try{return await continuation(request, context);}catch (RpcException ex){throw ex;}catch (Exception ex){throw new RpcException(new Status(StatusCode.Internal, ex.Message \r\n ex.StackTrace));}}}
代码中被继承的 Interceptor 是 Grpc.Core.Interceptors.Interceptor。主要处理的目的是把在gRPC接口中抛出的非 RpcException 的异常转换为 RpcException。此中间件也是根据具体的业务需求来做的主要是告诉大家可以重写 Grpc.Core.Interceptors.Interceptor 的拦截器来统一处理一些事情。定义协议缓冲区protocol3新建项搜索rpc可以出现协议缓冲区文件定义示例接口创建订单方法以及创建订单入参和出参。关于proto3协议具体说明请参考往期文章。syntax proto3;option csharp_namespace GrpcTest.Protos;service Order {rpc CreateOrder (CreateOrderRequest) returns (CreateOrderReply);
}message CreateOrderRequest {string ItemCode 1;string ItemName 2;string Spec 3;double Price 4;double Quantity 5;string Unit 6;double Cost 7;
}message CreateOrderReply {bool success 1;
}
在项目的csproj文件中需要有proto包含进去GrpcServicesServer表示当前是服务端。改好后重新生成下项目。ItemGroupProtobuf IncludeProtos/GrpcTest.Protos GrpcServicesServer //ItemGroup
创建OrderService手动创建OrderService继承自Order.OrderBaseproto自动生成的代码 public class OrderService : Order.OrderBase{public async override TaskCreateOrderReply CreateOrder(CreateOrderRequest request, ServerCallContext context){//todo something//throw RpcException异常throw new RpcException(new Status(StatusCode.NotFound, 资源不存在));//返回return new CreateOrderReply{Success true};}}
重写CreateOrder方法此处就可以写你的实际的业务代码相当于Controller接口入口。如果业务中需要主动抛出异常可以使用RpcException有定义好的一套状态码和异常封装。修改Startup在ConfigureServices方法中加入AddGrpc以及上面提到的异常处理中间件代码如下services.AddGrpc(option option.Interceptors.AddExceptionInterceptor());
在Configure方法中将OrderService启用代码如下app.UseEndpoints(endpoints {endpoints.MapGrpcServiceOrderService();endpoints.MapGet(/, async context {await context.Response.WriteAsync(this is a gRPC server);});});
至此 gRPC服务端搭建完成。gRPC-Client客户端框架介绍.Net Core sdk 3.1Google.Protobuf 3.12.4Grpc.Tools 2.30.0Grpc.Net.ClientFactory 2.30.0搭建步骤以.net core webapi 项目为例详细说明如何集成gRPC客户端创建项目创建web api项目此步骤说明省略引入nuget包引入gRPC 客户端需要的 nuget包Google.Protobuf 3.12.4、Grpc.Tools 2.30.0和Grpc.Net.ClientFactory 2.30.0引入proto文件将服务端的 order.proto 拷贝到客户端的web api项目中并在csproj文件中添加ItemGroup节点。GrpcServicesClient表示当前是客户端。改好后重新生成下项目。ItemGroupProtobuf IncludeProtos/OutpAggregation.proto GrpcServicesClient //ItemGroup
修改Startup在ConfigureServices方法中加入AddGrpcClient代码如下 services.AddHttpContextAccessor();AppContext.SetSwitch(System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport, true);var baseUrl http://localhost:5001/;services.AddGrpcClientOrder.OrderClient(options {options.Address new Uri(baseUrl);});
注意要使用.NET Core客户端调用不安全的gRPC服务需要进行其他配置。gRPC客户端必须将System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport开关设置为true并在服务器地址中使用http。可以在以下链接查看具体说明。[Troubleshoot gRPC on .NET Core]另外说明下services.AddGrpcClient方法来自于nuget包Grpc.Net.ClientFactory 2.30.0将gRPC客户端的注入封装具体代码实现可以查看以下链接。Grpc.Net.ClientFactory客户端调用以在Controller中调用为例示例代码如下 [ApiController][Route([controller])]public class WeatherForecastController : ControllerBase{private readonly Order.OrderClient _orderClient;public WeatherForecastController(Order.OrderClient orderClient){_orderClient orderClient;}[HttpGet]public async TaskIEnumerableWeatherForecast Get(){var result await _orderClient.CreateOrderAsync(new CreateOrderRequest{ItemCode 123,ItemName 名称1});}}
通过构造函数注入gRPC客户端然后就可以使用里面的同步或者异步方法啦