《ASP.NET Core 微服务实战》-- 读书笔记(第8章)
第 8 章 服务发现
面对大量服务,为了简化配置和管理工作,我们需要了解”服务发现“概念
回顾云原生特性
配置外置
将 URL 和登录凭证移到配置文件和 C# 代码之外,放到环境变量中
这样能让代码运行所需的配置参数更明确,而把提供这些配置的责任交给运行环境
后端服务
不管程序需要的是二进制存储、数据库、另一个服务、队列服务,还是其他类型的依赖,这些设施都应该松耦合,并能从环境变量中配置
把资源绑定为后端服务有两种方式:静态绑定和动态绑定
静态绑定指的是,无论是由自动化工具还是由 DevOps 工程师来分配,服务与资源之间的绑定过程发生在应用启动期间,而且一经绑定,即不再变化
动态绑定指资源的绑定过程发生在运行期间,具体来说,绑定关系并不固定,并能在应用收到的多个请求期间发生变化
另外,为避免给应用开发人员增加额外的复杂性,它也要支持松耦合
Netflix Eureka 简介
GitHub链接:https://github.com/Netflix/eureka
要实现运行时的服务发现,需要用到”服务注册表“设施--一种集中式的服务目录
Netflix 基础设施主要运行在 Amazon 云服务上
Netflix 自行开发了用于管理服务注册的产品 Eureka,它提供故障转移和负载均衡能力
从一名开发人员的角度看,微服务与 Eureka 服务器的交互方式就是在启动时注册
如果需要发现并消费其他后端服务,可从 Eureka 服务器查找服务目录
微服务还会向 Eureka 服务以一定的时间间隔发送心跳
如果服务在一定时间里没有发送心跳,就会从服务注册表中移除
在服务注册和发现领域, Eureka 也不是唯一的选择
从纯粹的服务注册工具到具有完整注册、发现和容错功能的产品,有很多其他公司和产品可供选用
- etcd:一个底层的分布式键值存储,提供 HTTP 访问
- Consul:一个功能完备的服务发现工具,也提供用于支持配置功能的键值存储
- Marathon:Mesos 和 DC/OS 上一个相当成熟的容器编排系统
- ZooKeeper:源自 Hadoop 项目,是这一体系中最悠久的产品
如果想体验 Eureka,但不想从源代码编译,也不想把它完整地安装到服务器上,你可以直接使用 docker hub 镜像来运行它,命令行如下:
$ docker run -p 8080:8080 --name eureka \
-d netflixoss/eureka:1.3.1
发现和广播 ASP.NET Core 服务
现在分析一些与 Eureka 服务交互的示例代码
在下面的虚构示例中,将开发一套用于支持电子商务的服务
最终的服务将公开一个产品目录,这个目录提供标准的 API 端点,用于访问产品列表和详细信息
此外,有一个库存服务,负责提供物理库存的实时状态
当需要展示产品详细信息时,产品服务将需要调用库存服务获取数据,用于组装最终的完整数据
服务注册
我们示例项目的第一部分是库存服务,它需要在运行期间动态地被其他服务发现,以提供实时库存状态
GitHub链接:https://github.com/microservices-aspnetcore/ecommerce-inventory
使用 .NET Core 配置系统向 Steeltoe 类库提供一些配置信息
appsettings.json
{
"spring": {
"application": {
"name": "inventory"
}
},
"eureka": {
"client": {
"serviceUrl": "http://localhost:8080/eureka/",
"shouldRegisterWithEureka": true,
"shouldFetchRegistry": false,
"validate_certificates": false
},
"instance": {
"port": 5000
}
},
}
我们用惯常的方式装配好配置,确保加载了保存着服务发现客户端配置信息的 appsettings.json 文件
var builder = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
在 Startup 类的 ConfigureService 方法里调用 Steeltoe 的 AddDiscoveryClient 扩展方法
services.AddDiscoveryClient(Configuration);
最后,只需要在 Configure 方法中添加对 UseDiscoveryClient 方法的调用
app.UseDiscoveryClient();
发现并消费服务
有一个可供发现的服务之后,我们把注意力转到要开发的下一个服务上:目录服务
这个服务提供产品的目录,并通过查询库存服务来补充产品的详细信息
这一服务与我们开发过的其他服务之间最重要的区别是,它会在运行期间动态地发现库存服务
GitHub链接:https://github.com/microservices-aspnetcore/ecommerce-catalog
用与配置库存服务时几乎一样的方式配置客户端
appsettings.json
{
"spring": {
"application": {
"name": "catalog"
}
},
"eureka":{
"client":{
"serviceUrl":"http://localhost:8080/eureka/",
"shouldRegisterWithEureka":false
}
}
}
区别在于目录服务不需要被注册(因为它不需要被其他服务发现),只有获取注册表才能发现库存服务
请看 HttpInventoryClient 类的代码,它负责消费库存服务
using StatlerWaldorfCorp.EcommerceCatalog.Models;
using Steeltoe.Discovery.Client;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
namespace StatlerWaldorfCorp.EcommerceCatalog.InventoryClient
{
public class HttpInventoryClient : IInventoryClient
{
private DiscoveryHttpClientHandler handler;
private const string STOCKSERVICE_URL_BASE = "http://inventory/api/skustatus/";
public HttpInventoryClient(IDiscoveryClient client)
{
this.handler = new DiscoveryHttpClientHandler(client);
}
private HttpClient CreateHttpClient()
{
return new HttpClient(this.handler, false);
}
public async Task<StockStatus> GetStockStatusAsync(int sku)
{
StockStatus stockStatus = null;
using (HttpClient client = this.CreateHttpClient())
{
var result = await client.GetStringAsync(STOCKSERVICE_URL_BASE + sku.ToString());
stockStatus = JsonConvert.DeserializeObject<StockStatus>(result);
}
return stockStatus;
}
}
}
.NET Core 的 HttpClient 类的构造函数有一个重载,允许传入一个自定义的 HttpHandler 实例
由 Steeltoe 提供的 DiscoveryHttpClientHandler 负责把 URL 中的服务名称替换成在运行期间发现的 URL
执行如下步骤,可在电脑上同时运行库存服务、目录服务和 Eureka
首先,启动 Eureka 服务
$ docker run -p 8080:8080 -d --name eureka \
-d netflixoss/eureka:1.3.1
然后在 5001 端口运行库存服务
$ cd <inventory service>
$ dotnet run --service.urls=http://0.0.0.0:5001
要在 Docker 中运行服务,请使用下面的 docker run 命令:
$ docker run -p 5001:5001 -e PORT=5001 \
-e EURKEA__CLIENT__SERVICEURL=http://192.168.0.33:8080/eureka/ \
dotnetcoreservices/ecommerce-inventory
如果要在这里覆盖配置的值,请确保使用本机的地址
在 Docker 镜像中运行时,指向 localhost 就会有问题
最后,在 5002 端口启动目录服务
$ cd <目录服务>
$ dotnet run --service.urls=http://0.0.0.0:5002
现在,可以向产品目录服务 API 发送一些请求,获取产品的列表和详情
GET http://localhost:5002/api/products
GET http://localhost:5002/api/products/{id}
获取产品详情信息,期间将调用库存服务,它的 URL 是通过 Eureka 动态发现的
DNS 以及由平台支持的服务发现
在我看来,服务发现、注册,以及失败检测都应该是非功能需求
也就是说,应用代码的任何部分都不应该紧耦合特定服务发现的实现
显然,还是要优先考虑现实状况,务实地做出决策,而且最终决定还要由你自己来做


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
《ASP.NET Core 微服务实战》-- 读书笔记(第8章)的更多相关文章
- JavaScript DOM编程艺术读书笔记(三)
第七章 动态创建标记 在web浏览器中往文档添加标记,先回顾下过去使用的技术: <body> <script type="text/javascript"> ...
- JavaScript DOM编程艺术读书笔记(二)
第五章 最佳实践 平稳退化(graceful degradation):如果正确使用了JavaScript脚本,可以让访问者在他们的浏览器不支持JavaScript的情况下仍能顺利地浏览你网站.虽然某 ...
- JavaScript DOM编程艺术读书笔记(一)
第一章,第二章 DOM:是一套对文档的内容进行抽象和概念化的方法. W3C中的定义:一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态的访问和修改文档的内容,结构和样式. DHTML( ...
- JavaScript DOM编程艺术 - 读书笔记1-3章
1.JavaScript语法 准备工作 一个普通的文本编辑器,一个Web浏览器. JavaScript代码必须通过Html文档才能执行,第一种方式是将JavaScript代码放到文档<head& ...
- JavaScript DOM编程艺术 读书笔记
2. JavaScript语法 2.1 注释 HTML允许使用"<!--"注释跨越多个行,但JavaScript要求这种注释的每行都必须在开头加上"< ...
- JavaScript DOM编程艺术读书笔记(四)
第十章 实现动画效果 var repeat = "moveElement('"+elementID+"',"+final_x+","+fin ...
- JavaScript DOM编程艺术-学习笔记(第二章)
1.好习惯从末尾加分号:开始 2.js区分大小写 3.程序界万能的命名法则:①不以,数字开头的数字.字母.下划线.美元符号 ②提倡以下划线命名法来命名变量,以驼峰命名法来命名函数.但是到了公司往往会身 ...
- 《javascript dom编程艺术》笔记(一)——优雅降级、向后兼容、多个函数绑定onload函数
刚刚开始自学前端,如果不对请指正:欢迎各位技术大牛指点. 开始学习<javascript dom编程艺术>,整理一下学习到的知识.今天刚刚看到第六章,记下get到的几个知识点. 优雅降级 ...
- JavaScript DOM编程艺术学习笔记(一)
嗯,经过了一周的时间,今天终于将<JavaScript DOM编程艺术(第2版)>这本书看完了,感觉受益匪浅,我和作者及出版社等等都不认识,无意为他们做广告,不过本书确实值得一看,也值得推 ...
- JavaScript DOM编程艺术-学习笔记
发现基础不是很好,补习一下.37买了2本书(dom编程和高级程序设计). 以前读书总是自己勾勾画画,有点没意思.现在写下来,说不定会成为传世经典.哈哈...........随便扯扯淡. 第一天(201 ...
随机推荐
- 《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab
这是CSAPP的第四个实验,这个实验比较有意思,也比较难.通过这个实验我们可以更加熟悉GDB的使用和机器代码的栈和参数传递机制. @ 目录 实验目的 准备工作 内容简介 代码注入攻击 Level 1 ...
- 使用 Sealos 一键部署 Kubernetes 集群
Sealos 是一款以 Kubernetes 为内核的云操作系统发行版,使用户能够像使用个人电脑一样简单地使用云. 与此同时,Sealos 还提供一套强大的工具,可以便利地管理整个 Kubernete ...
- 机器学习-无监督机器学习-kmeans-17
目录 1. 什么是聚类 2. 代码实现 1. 什么是聚类 无监督机器学习的一种 输入数据只有X 没有y 将已有的数据 根据相似度 将划分到不同的簇 (花团锦簇) 步骤: 随机选择k个簇的中心点 样本根 ...
- Scan Synthesis Practice
不同上升沿触发器如何进行scan chain DFT实例 Synopsys 工具文档 Mentor DFT脚本 add_clocks 0 clk - 0表示上升沿 Synopsys DFT脚本 更改n ...
- 【rt-thread】Kconfig文件添加子Kconfig文件时是以顶级Kconfig所在目录为当前路径的
示例如下 顶级Kconfig文件所在目录 子级Kconfig文件所在目录 子级Kconfig文件添加次子级Kconfig文件,以顶级目录为当前路径依次写出次子级Kconfig文件所在目录
- 2023第十四届极客大挑战 — WEB WP
说明:由于是从docx直接导入,因此鉴于docx的识别,文章有些图片里面有红色下划线,但不影响! 属实懒了!直接导入了...哈哈.凑合看吧!实在太多了.... EzHttp Post传参 查看源码 访 ...
- [转帖]CoreDNS loop 插件异常问题
https://zhuanlan.zhihu.com/p/476611162 背景 最近有遇到一个客户集群,发现集群中的 CoreDNS 老是异常 (loop 插件检测到有回路后进行 panic) ...
- [转帖]【SQL SERVER】锁机制
https://www.cnblogs.com/WilsonPan/p/12618849.html 锁定是 SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 基 ...
- 【转帖】什么是RLHF
什么是RLHF? **字面翻译:**RLHF (Reinforcement Learning from Human Feedback) ,即以强化学习方式依据人类反馈优化语言模型. 强化学习从人类反馈 ...
- Python学习之六_同时访问Oracle和Mysql的方法
Python学习之六_同时访问Oracle和Mysql的方法 背景 jaydebeapi 可以访问大部分数据库. 但是他有一个问题是仅能够访问一种类型的数据库. 如果同事连接两种数据库,那么就会出现问 ...