【微服务】03-HttpClientFactory与gRpc

news2025/7/19 10:12:11

文章目录

    • 1.HttpClientFactory :管理外向请求的最佳实践
      • 1.1 核心能力
      • 1.2 核心对象
      • 1.3 HttpClient创建模式
    • 2.gRPC:内部服务间通讯利器
      • 2.1 什么是gRPC
      • 2.2 特点gRPC特点
      • 2.3.NET生态对gRPC的支持情况
      • 2.4 服务端核心包
      • 2.5 客户端核心包
      • 2.5 .proto文件
      • 2.6 gRPC异常处理
      • 2.7 gRPC与HTTPS证书
      • 2.8 gRPC命令行工具
        • 2.8.1 工具核心包
        • 2.8.2 核心命令
        • 2.8.3 最佳实践

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

1.1 核心能力

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

1.2 核心对象

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

管道模型
在这里插入图片描述
请求过程

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仓库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/924495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

opencv 水果识别+UI界面识别系统,可训练自定义的水果数据集

目录 一、实现和完整UI视频效果展示 主界面&#xff1a; 测试图片结果界面&#xff1a; 自定义图片结果界面&#xff1a; 二、原理介绍&#xff1a; 图像预处理 HOG特征提取算法 数据准备 SVM支持向量机算法 预测和评估 完整演示视频&#xff1a; 完整代码链接 一、…

redis--集群

redis集群 Redis 集群是一种用于分布式存储和管理数据的解决方案&#xff0c;它允许将多个 Redis 实例组合成一个单一的逻辑数据库&#xff0c;提供更高的性能、容量和可用性。 redis集群的优点 高可用性&#xff1a; Redis集群使用主从复制和分片技术&#xff0c;使得数据可…

提高nodejs中promise的性能

提高nodejs中promise的性能 我们先来看一个常见问题&#xff0c;假设我们有 N 条记录需要处理&#xff0c;或者例如&#xff0c;为每条记录发出 API 请求以获取数据。 通常情况下我们都是使用promise.all方法来实现这一需求&#xff1a; // 记录 const data [{}, {}, {}];/…

Linux网络编程:线程池并发服务器 _UDP客户端和服务器_本地和网络套接字

文章目录&#xff1a; 一&#xff1a;线程池模块分析 threadpool.c 二&#xff1a;UDP通信 1.TCP通信和UDP通信各自的优缺点 2.UDP实现的C/S模型 server.c client.c 三&#xff1a;套接字 1.本地套接字 2.本地套 和 网络套对比 server.c client.c 一&#xff1a;线…

如何使用CSS实现一个3D旋转效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 3D效果实现⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域…

有线耳机插入电脑没声音

有线耳机插入电脑没声音 首先确保耳机和电脑都没问题&#xff0c;那就有可能是声音输出设备设置错误 右击任务栏的声音图标-打开声音设置-选择输出设备。

长时间序列的25米全球sar卫星镶嵌数据

数据简介 1992年JAXA&#xff08;Japan Aerospace Exploration Agency&#xff0c;日本宇宙航空研究开发机构&#xff09;发射了一颗JERS-1卫星&#xff0c;该卫星携带有18*24m分辨率的SAR传感器。随后&#xff0c;JAXA又在2006年和2014年分别发射了带有SAR传感器的alos卫星和…

拓世科技集团 | “书剑人生”李步云学术思想研讨会暨李步云先生九十华诞志庆

2023年&#xff0c;中国改革开放迎来了45周年&#xff0c;改革春风浩荡&#xff0c;席卷神州大地&#xff0c;45年间&#xff0c;中国特色社会主义伟大事业大步迈入崭新境界&#xff0c;一路上结出了饶为丰硕的果实。中华民族在这45年间的砥砺前行&#xff0c;不仅使中国的经济…

Clion 找不到头文件,无法DEBUG,无法进入断点,断点灰了

文章目录 1. 找不到远程toolchain的头文件2.gdb未安装或版本不对无法debug3.远程debug断点灰了 1. 找不到远程toolchain的头文件 ①检查cmake头文件引入指令include_directories(SYSTEM "/usr/lib/jvm/jdk-17-oracle-x64/include") ②菜单栏Tools->Resyinc with r…

运放的分类、运放的参数

一、运放的分类 运放按功能分为通用运放与专用运放&#xff08;高速运放、精密运放、低IB运放等&#xff09;。 1.1通用运放 除廉价外&#xff0c;没有任何最优指标的运放。 例&#xff1a;uA741&#xff0c;LM324&#xff0c;TL06X&#xff0c;TL07X、TL08X等 国外知名运放…

科技赋能,教育革新——大步迈向体育强国梦

在 "全民健身"、"体育强国建设"战略的推进下&#xff0c;体育考试成绩被纳入重要升学考试且分值不断提高&#xff0c;体育科目的地位逐步上升到前所未有的高度&#xff0c;在此趋势下&#xff0c;体育教学正演变出更多元化、个性化的需求。然而现实中却面临…

ubuntu20.04 编译安装运行emqx

文章目录 安装依赖编译运行登录dashboard压力测试 安装依赖 Erlang/OTP OTP 24 或 25 版本 apt-get install libncurses5-dev sudo apt-get install erlang如果安装的erlang版本小于24的话&#xff0c;可以使用如下方法自行编译erlang 1.源码获取 wget https://github.com/erla…

ARM开发,stm32mp157a-A7核IIC实验(采集温湿度传感器值)

1.实验目标&#xff1a;采集温湿度传感器值&#xff1b; 2.分析框图&#xff08;模拟IIC控制器&#xff09;&#xff1b; 3.代码&#xff1b; ---iic.h封装时序协议头文件--- #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "st…

bash: conda: command not found

问题描述&#xff1a; 在Pycharm上用SSH远程连接到服务器&#xff0c;打开Terminal准备查看用 conda 创建的虚拟环境时&#xff0c;却发现调用 conda 指令时出现以下报错&#xff1a; -bash: conda: command not found如果使用Xshell 利用端口号直接连接该 docker 容器&#…

学无止境·运维高阶⑦Docker进阶一(构建个人网盘)

Docker进阶一 1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。1.1 拉取镜像1.2 创建容器1.3登录查看 1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 1.1 拉取镜像 [rootnode3 ~]# docker pull mysql:5.6 [rootnode3 ~]# docker pull own…

基于jeecg-boot的flowable流程跳转功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 今天我…

云计算在线实训系统建设方案

一、 人工智能与云计算系统概述 人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是一种模拟人类智能的科学和工程&#xff0c;通过使用计算机系统来模拟、扩展和增强人类的智能能力。人工智能涉及多个领域&#xff0c;包括机器学习、深度学习、自然…

零基础如何使用IDEA启动前后端分离中的前端项目(Vue)?

一、在IDEA中配置vue插件 点击File-->Settings-->Plugins-->搜索vue.js插件进行安装&#xff0c;下面的图中我已经安装好了 二、搭建node.js环境 安装node.js 可以去官网下载&#xff1a;安装过程就很简单&#xff0c;直接下一步就行 测试是否安装成功&#xff1a;要…

HCIP-OpenStack组件之neutron

neutron&#xff08;ovs、ovn&#xff09; OVS OVS(Open vSwitch)是虚拟交换机&#xff0c;遵循SDN(Software Defined Network&#xff0c;软件定义网络)架构来管理的。 OVS介绍参考&#xff1a;https://mp.weixin.qq.com/s?__bizMzAwMDQyOTcwOA&mid2247485088&idx1…

基于PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…