【微服务】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 :管理外向请求的最佳实践1.1 核心能力1.2 核心对象1.3 HttpClient创建模式 2.gRPC:内部服务间通讯利器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文件,打包成一个.a/.framework文件。a的意思是archive/归档的意思。 查看静态库.a文件包含的内容用下面的命令解压: ar x xxx.a 用ar命令打包静态库: 参数r是将后面的*.o或者*.a文件添加到目标文件中 参数…...

Idea常用快捷键--让你代码效率提升一倍(一)
一、代码编辑相关快捷键 1.单行复制(实现快速创建多个对象)CtrlD 2.空出下一行 ShiftEnter 3.单行注释快捷键 ctrl / 4.快速构建构造函数,setter,getter、toString方法 AltInsert 4.显示快速修复和操作的菜单 altenter 5.格式化代码: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》一书,Python 3 版本;本系列博文的目标不是为了构建一个 Python 知识大全,而是为了那些需要快速将 Python 学以致用的相关人员…...

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

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

Activity 的启动流程(Android 13)
Activity 的启动过程分为两种:一种是普通 Activity 的启动过程,另一种是根 Activity 的启动过程。普通 Activity 指的是除应用程序启动的第一个 Activity 之外的其他 Activity。根 Activity 指的是应用程序启动的第一个 Activity,因此&#x…...
deepspeed学习资料
记录一些deepspeed学习过程中的好文章 【进行中】1、DeepSpeed使用指南(简略版)_Reza.的博客-CSDN博客 - 含deepspeed的安装方法 - 含 zero config的不同配置,stage1、stage2、stage3的配置和解释...

数据分享|R语言PCA主成分、lasso、岭回归降维分析近年来各国土地面积变化影响...
全文链接:http://tecdat.cn/?p31445 机器学习在环境监测领域的应用,着眼于探索全球范围内的环境演化规律,人类与自然生态之间的关系以及环境变化对人类生存的影响(点击文末“阅读原文”获取完整代码数据)。 课题着眼于…...

Docker-Consul
Docker-Consul 一、介绍1.什么是服务注册与发现2.什么是consul3.consul提供的一些关键特性: 二、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初始化 状态,如果已经初始化,返回 True,否则返回Falseget_init() -> bool pygame.display.quit() 退出…...
第十五天|104.二叉树的最大深度、111.二叉树的最小深度、 222.完全二叉树的节点个数
104.二叉树的最大深度 题目链接:104. 二叉树的最大深度 - 力扣(LeetCode) /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullp…...
图像识别技术在医疗领域的革命:探索医学影像诊断的未来
导言: 随着人工智能和计算机视觉的快速发展,图像识别技术在医疗领域正掀起一场革命。医学影像诊断是医疗工作中的重要环节,而图像识别技术的引入为医生提供了更准确、高效的辅助手段。本文将深入探讨图像识别技术在医疗领域的应用,…...

计网第四章(网络层)(二)
目录 IPV4地址编址 第一历史阶段(分类编址): A类地址: B类地址: C类地址: D类地址(多播地址): E类地址(保留地址): 第二历史阶…...

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

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

linux+c+qt杂记
虚拟机网络选择; 桥接模式:设置window宿主机的IP/dns,把虚拟机设置为桥接即可。 切换到终端:我的是 ctrlaltFnF1? 问题解决: Ubuntu系统下载(清华大学开源软件镜像站)(ubuntu-20.…...
shouldComponentUpdate有什么作用?
触发时机 当props或state发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。 作用 根据shouldComponentUpdate()的返回值,判断react组件的输出是否受当前state或props更改影响。默认行为是state每次发生变化组件都会重新渲染。 shouldCompo…...
华为OD-滑动窗口最大值
题目描述 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例一 输入:nums [1,3,-1,-3,5,3,6,7], k 3 输出…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...