【微服务】03-HttpClientFactory与gRpc

这篇具有很好参考价值的文章主要介绍了【微服务】03-HttpClientFactory与gRpc。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.HttpClientFactory :管理外向请求的最佳实践

1.1 核心能力

  • 管理内部HttpMessageHandler的生命周期,灵活应用资源问题和DNS刷新问题
  • 支持命名化、类型化配置,集中管理配置,避免冲突
  • 灵活的出站请求管道配置,轻松管理请求声明周期
  • 内置管道最外层和最内层日志记录器,有Information和Trace输出

1.2 核心对象

  • HttpClient
  • HttpMessageHandler
  • SocketsHttpHandler
  • DelegatingHandler
  • IHttpClientFactory
  • IHttpClientBuilder

管道模型
【微服务】03-HttpClientFactory与gRpc,微服务,NetCore,微服务,开发语言,.netcore,后端
请求过程

HttpClient发起请求,然后最外层的日志记录器来记录日志,然后再进到自定义的Handler中处理自定义的逻辑;
然后最内层的SocketsHttpHandler,这是真正去发起远程调用的处理程序,它回向远程站点发起HTTP请求并接受响应,在接收到响应以后,Http最内层的日志记录器会记录响应信息;
随后将响应结果交还给自定义的Handler,在接受响应后处理接受响应的逻辑,处理完成后最外层的日志记录器会输出响应日志,最终HttpClient拿到响应结果,输出给应用程序

1.3 HttpClient创建模式

  • 工厂模式
  • 命名客户端模式
  • 类型化客户端模式
// 工厂模式
public class OrderServiceClient
{
	IHttpClientFactory _httpClientFactory;

	public OrderServiceClient(IHttpClientFactory httpClientFactory)
	{
		_httpClientFactory = httpClientFactory;
	}

	public async Task<string> Get()
	{
		var client = _httpClientFactory.CreateClient();
		return await client.GetStringAsync("这里是远程服务路径地址");// 相对路径访问
	}
}

// 命名客户端
public class NamedOrderServiceClient
{
	IHttpClientFactory _httpClientFactory;
	const string _clientName = "NamedOrderServiceClient";
	public NamedOrderServiceClient(IHttpClientFactory httpClientFactory)
	{
		_httpClientFactory = httpClientFactory;
	}

	public async Task<string> Get()
	{
		var client = _httpClientFactory.CreateClient(_clientName);
		return await client.GetStringAsync("这里是远程服务路径地址");// 相对路径访问
	}
}

// 类型客户端
public class TypeOrderServiceClient
{
	HttpClient _client;
	public TypeOrderServiceClient(HttpClient client)
	{
		_client = client;
	}

	public async Task<string> Get()
	{	
		return await _client.GetStringAsync("这里是远程服务路径地址");// 相对路径访问
	}
}


// HttpClientFactory注册,startup中ConfigurationService
public void ConfigureServices(IServiceCollection services)
{
	// 工厂模式
	services.AddHttpClient();
	services.AddScope<OrderServiceClient>();
	
	// 命名客户端模式
	services.AddHttpClient("NamedOrderServiceClient",client =>
	{
		client.DefaultRequestHeaders.Add("client-name","nameclient");
		client.BaseAddress = new Uri("远程站点根路径");
	})
	.AddHttpMessageHandler(provider => provider.GetService<RequestIdDelegatingHandler>());//自定义Handler
	services.AddScope<NamedOrderServiceClient>();

	//推荐使用
	// 类型客户端,
	services.AddHttpClient<TypeOrderServiceClient>(client =>
	{
		client.BaseAddress = new Uri("远程站点根路径");
	});
}


// Controller中使用
public class OrderController : ControllerBase
{
	OrderServiceClient _orderServiceClient;
	public OrderController(OrderServiceClient orderServiceClient)
	{
		_orderServiceClient = orderServiceClient;
	}

	[HttpGet("Get")]
	public Task<string> Get()
	{
		return await _orderServiceClient.Get();
	}

	[HttpGet("NameGet")]
	public Task<string> NamedGet([FromServices] NamedOrderServiceClient serviceClient)
	{
		return await serviceClient.Get();
	}

	[HttpGet("TypeGet")]
	public async Task<string> TypeGet([FromServices] TypeOrderServiceClient client)
	{
		return await client.Get();
	}
}

2.gRPC:内部服务间通讯利器

2.1 什么是gRPC

  • 定义

gRPC是一个远程过程调用框架,作用是让我们可以像在调用本地的类一样调用远程的服务。由Google公司发起并开源,g表示Google公司,RPC表示远程调用

2.2 特点gRPC特点

  • 提供几乎所有主流语言的实现,打破语言隔阂
  • 基于HTTP/2,开放协议,收到广泛的支持,易于实现和集成
  • 默认使用ProtocolBuffers序列化,性能相较于RESTfulJson好很多
  • 工具链成熟,代码生成便捷,开箱即用
  • 支持双向流式的请求和响应,对批量处理、低延时场景友好

2.3.NET生态对gRPC的支持情况

  • 提供基于HttpClient的原生框架实现
  • 提供原生的ASP.NETCore集成库
  • 提供完整的代码生成工具
  • Visual Studio和Visual Studio Code提供proto文件的只能提示

2.4 服务端核心包

  • Grpc.AspNetCore

2.5 客户端核心包

  • Google.Protobuf ⇒ 序列化协议包
  • Grpc.Net.Client ⇒ 客户端包
  • Grpc.Net.ClientFactory ⇒ 与HttpClientFactory集成的包
  • Grpc.Tools ⇒ 提供命令行工具使用的包

2.5 .proto文件

  • 定义包、库名
  • 定义服务“service”
  • 定义输出和输入模型“message”

2.6 gRPC异常处理

  • 使用Grpc.Core.RpcException
  • 使用Grpc.Core.Interceptors.Interceptor

RpcException支持拦截器,可以通过注入拦截器处理异常

2.7 gRPC与HTTPS证书

  • 使用自制证书
  • 使用非加密的HTTP2

服务端

// order.proto文件定义 *****核心*****
syntax = "proto3";// 定义proto协议类型为proto3
// 定义命名空间为GrpcServices
option csharp_namespace = "GrpcServices";
package GrpcServices;

// 定义服务OrderGrpc 
service OrderGrpc {
	rpc CreateOrder(CreateOrderCommand) returns (CreateOrderResult);
}

// 定义输入输出响应,需要为每个字段定义顺序,这也是序列化时候的顺序
// 序列化时是根据数据类型和顺序识别字段的值
message CreateOrderCommand {
	string buyerId = 1;
    int32 productId = 2;
    double unitPrice = 3;
    double discount = 4;
    int32 units = 5;
}

message CreateOrderResult {
    int32 orderId = 1;
}

// 定义OrderService
public class OrderService : OrderGrpc.OrderGrpcBase
{
     public override Task<CreateOrderResult> CreateOrder(CreateOrderCommand request, ServerCallContext context)
     {

         throw new System.Exception("order error");

         //添加创建订单的内部逻辑,录入将订单信息存储到数据库
         return Task.FromResult(new CreateOrderResult { OrderId = 24 });
     }
 }
// 注册gRPC服务
public void ConfigureServices(IServiceCollection services)
{
       services.AddGrpc(options =>
       {
           options.EnableDetailedErrors = true;// 内部错误信息输出设置,生产环境不对外输出
           options.Interceptors.Add<ExceptionInterceptor>();// 添加的异常拦截器
       });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
      if (env.IsDevelopment())
      {
          app.UseDeveloperExceptionPage();
      }

      app.UseRouting();

      app.UseEndpoints(endpoints =>
      {
          endpoints.MapGrpcService<OrderService>();
          endpoints.MapGet("/", async context =>
          {
              await context.Response.WriteAsync("Hello World!");
          });
      });
  }

定义好order.proto文件,那么会自动生成服务端代码,生成的代码在项目目录的obj文件夹下的Order.cs和OrderGrpc.cs

客户端
将服务端的order.proto文件引入客户端,可以基于proto文件生成客户端代码

// startup
 public void ConfigureServices(IServiceCollection services)
 {
 	 //允许使用不加密的HTTP/2协议
	 //AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
 
 	// 注册OrderGrpcClient
 	// OrderGrpcClient文件是由order.proto文件生成的
 	services.AddGrpcClient<OrderGrpc.OrderGrpcClient>(options =>
    {
          options.Address = new Uri("https://localhost:5001");
      })
      .ConfigurePrimaryHttpMessageHandler(provider =>
      {
           var handler = new SocketsHttpHandler();
           handler.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true; //允许无效、或自签名证书
           return handler;
       }).AddTransientHttpErrorPolicy(p => p.WaitAndRetryForeverAsync(i => TimeSpan.FromSeconds(i * 3)));
 }


2.8 gRPC命令行工具

2.8.1 工具核心包
  • Grpc.Tools ⇒ 工程需要引用的工具
  • dotnet-grpc ⇒ 命令行工具,是.net命令行的工具插件
2.8.2 核心命令
  • dotnet grpc add-file ⇒ 将指定目录下的proto文件添加到工程中
  • dotnet grpc add-url ⇒ 将一个HTTP的URL地址指定的proto文件添加到我们的工程中
  • dotnet grpc remove ⇒ 将添加的proto文件的引用移除,文件不会移除
  • dotnet grpc refresh ⇒ 更新proto文件
2.8.3 最佳实践
  • 使用单独的Git仓库管理proto文件
  • 使用submodule将proto文件集成到工程目录中
  • 使用dotnet-grpc命令行添加proto文件及相关依赖包引用

备注

由proto生成的代码文件会存放在obj目录中,不会被签入到Git仓库文章来源地址https://www.toymoban.com/news/detail-677783.html

到了这里,关于【微服务】03-HttpClientFactory与gRpc的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .netcore grpc截止时间和取消详解

    截止时间功能让 gRPC 客户端可以指定等待调用完成的时间。  超过截止时间时,将取消调用。  设定一个截止时间非常重要,因为它将提供调用可运行的最长时间。 它能阻止异常运行的服务持续运行并耗尽服务器资源。 截止时间对于构建可靠应用非常有效,应该进行配置。

    2024年02月11日
    浏览(84)
  • .netcore grpc的proto文件字段详解

    grpc的接口传输参数都是根据.proto文件约定的字段格式进行传输的 grpc提供了多种类型字段;主要包括标量值类型(基础类型)、日期时间、可为null类型、字节、列表、字典、Any类型(任意类型)、Oneof等 字段严格规范,是一种强类型文件协议 标量值类型 日期时间 可为null类

    2024年02月12日
    浏览(39)
  • .netcore grpc客户端工厂及依赖注入使用

    gRPC 与  HttpClientFactory  的集成提供了一种创建 gRPC 客户端的集中方式。 可以通过依赖包Grpc.Net.ClientFactory中的AddGrpcClient进行gRPC客户端依赖注入 AddGrpcClient函数提供了许多配置项用于处理一些其他事项;例如AOP、重试策略等 创建一个WPF客户端 在App.xaml.cs代码类里重写OnStartup方

    2024年02月12日
    浏览(36)
  • 【NetCore】03-依赖注入

    管理类之间的依赖,帮助我们在构建应用时遵循设计原则,确保代码的可维护性和可扩展性 依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的 组件包 Microsoft.Extensions.DependencyInjection.Abstractions Microsoft.Extensions.

    2024年02月15日
    浏览(40)
  • NetCore部署微服务(三)

    接上文,服务端部署完成之后,同样我们也需要修改一下客户端代码 1.1 服务发现 在客户端代码中使用Nuget安装consul包  修改配置文件,我们首先需要把consul的请求地址配置在配置文件中 修改control方法  OK,通过如下修改,我们发现,我们不需要再在代码中配置请求地址,请

    2024年02月02日
    浏览(37)
  • NetCore_signalR服务端

    本文不介绍关于SignalR的原理内容,比如如何实现的长连接,如何实现双工通信,如何实现向下兼容的通信等等 本文仅仅记录如何实现一个服务端 IDE :visual Studio2022 环境:.net6 webApi程序 语言:C#10 没有引入其他包,因为是WebApi项目,所以默认的asp.net的包都引入了。 完整代码

    2024年02月09日
    浏览(39)
  • NetCore下WebApi的后台服务BackgroundService

    引言:最近发现个好东西就是 BackgroundService ,以前一直没注意到。个人理解它就是在你的后台开了一个子线程运行你的其他业务逻辑。 先上代码: 还需要在startup里面注册一下: 应用场景:定时提醒。

    2024年02月10日
    浏览(40)
  • 基于vol.NetCore vue低代码开发使用文档

    1、前端字段的label中文说明短时,this.boxOptions.labelWidth = 300 在 OnInit 中增加 2、this.searchAfter(data, result); 注意查询后的方法有两个参数,返回所有后台的所有数据;动态多选格式 3、查询提交查询之前,客户端可以增加查询条件 4、生成主从表时,要先生成从表的model和编辑行,

    2024年02月08日
    浏览(104)
  • 基于.NetCore开发博客项目 StarBlog - (28) 开发友情链接相关接口

    之前介绍的友情链接功能,只实现了友情链接的展示和管理接口。 还缺失友情链接申请、审核管理、通知,现在把这块功能补全。 Model 什么的之前那篇文章都有,本文直接补全逻辑代码~ 详见: 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能 友情链接申请页面 实现一

    2024年02月06日
    浏览(50)
  • nacos实现Java和.NetCore的服务注册和调用

    用nacos作为服务注册中心,如何注册.NetCore服务,如何在Java中调用.NetCore服务呢?可以分为下面几个步骤:   0.运行nacos   1.开发.net core服务,然后调用nacos提供的.net core sdk注册服务。   2.开发Java服务,然后注册服务。   3.用RestTemplate调用.net core服务。   4.用OpenFeign调用服务

    2024年01月17日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包