当前位置: 首页 > news >正文

【微服务】03-HttpClientFactory与gRpc

文章目录

    • 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>());//自定义Handlerservices.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文件生成客户端代码

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

相关文章:

【微服务】03-HttpClientFactory与gRpc

文章目录 1.HttpClientFactory &#xff1a;管理外向请求的最佳实践1.1 核心能力1.2 核心对象1.3 HttpClient创建模式 2.gRPC&#xff1a;内部服务间通讯利器2.1 什么是gRPC2.2 特点gRPC特点2.3.NET生态对gRPC的支持情况2.4 服务端核心包2.5 客户端核心包2.5 .proto文件2.6 gRP…...

iOS开发之查看静态库(.a/.framework)中包含的.o文件和函数符号(ar,nm命令)

.a/.framework其实是把编译生成的.o文件&#xff0c;打包成一个.a/.framework文件。a的意思是archive/归档的意思。 查看静态库.a文件包含的内容用下面的命令解压&#xff1a; ar x xxx.a 用ar命令打包静态库&#xff1a; 参数r是将后面的*.o或者*.a文件添加到目标文件中 参数…...

Idea常用快捷键--让你代码效率提升一倍(一)

一、代码编辑相关快捷键 1.单行复制(实现快速创建多个对象)CtrlD 2.空出下一行 ShiftEnter 3.单行注释快捷键 ctrl / 4.快速构建构造函数&#xff0c;setter&#xff0c;getter、toString方法 AltInsert 4.显示快速修复和操作的菜单 altenter 5.格式化代码&#xff1a;C…...

【Open3D】第二篇:GUI编程

文章目录 基本控件创建创建文本框创建button创建布局 绘制形状绘制线段绘制点云 设置属性设置线宽设置点大小 可用Shader汇总GUI框架 基本控件创建 创建文本框 push_edit gui.TextEdit()创建button push_button gui.Button(...) push_button.horizontal_padding_em 0.5 p…...

【Python】P0 本系列博文简介与大纲

Python 前言本系列博文适合谁本系列博文不适合谁本系列博文大纲 前言 本系列博文基于《Python Cookbook》一书&#xff0c;Python 3 版本&#xff1b;本系列博文的目标不是为了构建一个 Python 知识大全&#xff0c;而是为了那些需要快速将 Python 学以致用的相关人员&#xf…...

FL Studio 21.1.0 Build 3713中文破解免费下载安装激活

FL Studio 21是一个功能齐全、开放式的PC音乐创作和制作环境。它具有基于音乐序列器的图形用户界面。 这个数字音频工作站将您所需的一切整合在一个包中&#xff0c;用于创作、编排、录制、编辑、混音和掌握专业质量的音乐。 FL Studio 21是从你的大脑到扬声器的最快方式。制作…...

从0开始配置eslint

没有在.eslintrc文件中配置parserOptions指定语言版本和模块类型 {"parserOptions": {"ecmaVersion": 7, //指定es版本为es2016"sourceType": "module", //使用import导入模块} }eslint还不能识别jsx语法 {"parserOptions"…...

Activity 的启动流程(Android 13)

Activity 的启动过程分为两种&#xff1a;一种是普通 Activity 的启动过程&#xff0c;另一种是根 Activity 的启动过程。普通 Activity 指的是除应用程序启动的第一个 Activity 之外的其他 Activity。根 Activity 指的是应用程序启动的第一个 Activity&#xff0c;因此&#x…...

deepspeed学习资料

记录一些deepspeed学习过程中的好文章 【进行中】1、DeepSpeed使用指南(简略版)_Reza.的博客-CSDN博客 - 含deepspeed的安装方法 - 含 zero config的不同配置&#xff0c;stage1、stage2、stage3的配置和解释...

数据分享|R语言PCA主成分、lasso、岭回归降维分析近年来各国土地面积变化影响...

全文链接&#xff1a;http://tecdat.cn/?p31445 机器学习在环境监测领域的应用&#xff0c;着眼于探索全球范围内的环境演化规律&#xff0c;人类与自然生态之间的关系以及环境变化对人类生存的影响&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 课题着眼于…...

Docker-Consul

Docker-Consul 一、介绍1.什么是服务注册与发现2.什么是consul3.consul提供的一些关键特性&#xff1a; 二、consul 部署1.环境准备2.consul服务器3.查看集群信息4.通过 http api 获取集群信息 三、registrator服务器1.安装 Gliderlabs/Registrator2.测试服务发现功能是否正常3…...

Pygame编程(2)display模块

pygame编程2-display设备显示 pygame.display.init() 初始化 display 模块init() -> None pygame.display.get_init() 获取display初始化 状态&#xff0c;如果已经初始化&#xff0c;返回 True&#xff0c;否则返回Falseget_init() -> bool pygame.display.quit() 退出…...

第十五天|104.二叉树的最大深度、111.二叉树的最小深度、 222.完全二叉树的节点个数

104.二叉树的最大深度 题目链接&#xff1a;104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullp…...

图像识别技术在医疗领域的革命:探索医学影像诊断的未来

导言&#xff1a; 随着人工智能和计算机视觉的快速发展&#xff0c;图像识别技术在医疗领域正掀起一场革命。医学影像诊断是医疗工作中的重要环节&#xff0c;而图像识别技术的引入为医生提供了更准确、高效的辅助手段。本文将深入探讨图像识别技术在医疗领域的应用&#xff0c…...

计网第四章(网络层)(二)

目录 IPV4地址编址 第一历史阶段&#xff08;分类编址&#xff09;&#xff1a; A类地址&#xff1a; B类地址&#xff1a; C类地址&#xff1a; D类地址&#xff08;多播地址&#xff09;&#xff1a; E类地址&#xff08;保留地址&#xff09;&#xff1a; 第二历史阶…...

原生微信小程序使用 wxs;微信小程序使用 vant-weapp组件

1.原生微信小程序使用 wxs 1.内嵌 WXS 脚本 2. 定义外链 wxs 3. 使用外连wxs 在这里插入图片描述 2. 微信小程序使用 vant weapp 1.安装步骤 2. 安装包管理(package.json)文件的方法 操作顺序 &#xff1a;文档地址 如果使用 typescript 需要操作步骤3&#xff0c;否则不…...

qml相关知识1

qml相关知识1 QtQuick.Controls 哪个版本支持TreeModel 和 TreeItemqt5.12开始&#xff0c;TreeItem 类被删除&#xff0c;无法使用delegate 什么时候可以用Qt5.15中没有 import QtQuick.Controls 1吗&#xff0c;哪个版本有control1qml如何两种版本的controls混用&#xff08;…...

linux+c+qt杂记

虚拟机网络选择&#xff1b; 桥接模式&#xff1a;设置window宿主机的IP/dns,把虚拟机设置为桥接即可。 切换到终端&#xff1a;我的是 ctrlaltFnF1&#xff1f; 问题解决&#xff1a; Ubuntu系统下载&#xff08;清华大学开源软件镜像站&#xff09;&#xff08;ubuntu-20.…...

shouldComponentUpdate有什么作用?

触发时机 当props或state发生变化时&#xff0c;shouldComponentUpdate() 会在渲染执行之前被调用。 作用 根据shouldComponentUpdate()的返回值&#xff0c;判断react组件的输出是否受当前state或props更改影响。默认行为是state每次发生变化组件都会重新渲染。 shouldCompo…...

华为OD-滑动窗口最大值

题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例一 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], k 3 输出…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...