尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Midway 接入 Consul:服务注册、负载均衡与健康检查实战指南

Midway 接入 Consul:服务注册、负载均衡与健康检查实战指南 后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载导读本文基于 Midway 官方子包midwayjs/consul本仓库位于 packages/consul系统讲解如何在 Midway 应用中集成 Consul实现服务注册register、应用下线反注册deregister、基于健康检查实例的服务发现与负载均衡以及直接注入原生 Consul 客户端进行底层操作。读完本文你将掌握从安装依赖、编写配置、注册服务到通过consul:balancerService调用远端服务实例的完整链路并了解服务发现模块ConsulServiceDiscovery背后的源码实现与健康检查机制可直接在基于 Koa / Express / Egg 的 Midway 微服务项目中落地使用。一、Consul 组件能做什么midwayjs/consul是 Midway 生态中面向微服务注册与发现的标准组件能力清单如下与 packages/consul/usage.md 中 Support 列表一致register可选应用启动时向 Consul Server 注册当前服务实例deregister on the shutdown可选应用正常关闭时自动反注册避免留下“僵尸实例”service balancer默认 random组件内置负载均衡器在多个健康实例中挑选一个进行调用默认采用随机策略expose the origin consul object暴露原始consul客户端对象方便直接使用官方库的底层 API如 KV 存储、健康检查查询等。组件基于consulnpm 包dependencies中锁定consul2.0.1封装运行要求 Node.js 20详见 packages/consul/package.json。二、安装与引入组件2.1 安装依赖在 Midway 项目中安装运行时依赖与 TypeScript 类型声明npm i midwayjs/consul -S npm i types/consul -D-S安装到dependencies运行时需要-D安装types/consul到devDependencies仅 TypeScript 编译期使用。2.2 引入组件在入口configuration.ts中通过imports引入consul模块并通过importConfigs声明配置目录import * as consul from midwayjs/consul Configuration({ imports: [ consul ], importConfigs: [join(__dirname, config)] }) export class ContainerConfiguration {}组件内部在ConsulConfiguration见 packages/consul/src/configuration.ts中完成了生命周期管理onReady应用就绪时通过容器获取ConsulServiceFactory提前完成客户端初始化onStop应用停止时调用factory.stop()触发destroyClient销毁连接packages/consul/src/manager.ts 中会打印[midway:consul] destroy %s日志。因此你只需引入组件并写好配置连接的生命周期由框架自动托管。三、配置 Consul Server 与服务定义在配置目录即importConfigs指向的config文件夹下的config.default.ts或config.default.js中写入consul: { provider: { // 注册本服务 register: true, // 应用正常下线反注册 deregister: true, // consul server 主机 host: 192.168.0.10, // consul server 端口 port: 8500, // 调用服务的策略(默认选取 random 具有随机性) strategy: random, }, service: { address: 127.0.0.1, port: 7001, tags: [tag1, tag2], // others consul service definition } }各字段含义与取值说明配置段字段说明默认值/备注providerregister是否向 Consul 注册当前服务布尔值可选为true时启动即注册providerderegister应用正常关闭时是否反注册布尔值可选为true时onStop阶段调用agent.service.deregisterproviderhostConsul Server 地址例如192.168.0.10providerportConsul Server 端口默认8500Consul HTTP API 标准端口providerstrategy实例选取策略默认random具有随机性serviceaddress本服务对外暴露的 IP/主机例如127.0.0.1serviceport本服务对外暴露的端口例如7001servicetags注册时附加的标签数组例如[tag1, tag2]可用于按标签筛选实例service其余字段其他 Consul 服务注册定义直接透传给官方agent.service.register从源码看客户端工厂ConsulServiceFactory.createClientpackages/consul/src/manager.ts会把consul配置中的host、port等直接作为参数构造原生new Consul(config)客户端并在初始化时输出日志[midway:consul] init %s at %s:%s方便排查连接目标。3.1 关于服务发现serviceDiscovery的进阶配置除了上述provider/service两段组件默认配置中还预置了服务发现相关参数见 packages/consul/src/configuration.tsconsul: { serviceDiscovery: { loadBalancer: roundRobin, healthCheckType: self, }, }loadBalancer服务发现客户端的负载均衡器类型组件默认值为roundRobinhealthCheckType健康检查方式默认self自管理健康检查。ConsulServiceDiscoverypackages/consul/src/extension/serviceDiscovery.ts在初始化时通过MidwayConfigService.getConfiguration(consul.serviceDiscovery, {})读取该段配置并据此创建对应的服务发现客户端。四、查询服务实例并调用负载均衡当需要调用其他注册到 Consul 的服务时通过consul:balancerService获取负载均衡器。支持两种获取方式// 1. 注入的方式 Inject(consul:balancerService) balancerService: IConsulBalancer; // 2. 编码的方式 const balancerService await app.getApplicationContext().getAsyncIConsulBalancer(consul:balancerService);然后通过getBalancer().select(name)选取一个实例// 1. 查询通过健康检查的服务 const service await balancerService.getBalancer().select(the-service-name); // 2. 可能取到不健康的服务 const service await balancerService.getBalancer().select(the-service-name, false);两点必须注意返回的是 Consul 原生数据select返回的service是 Consul API 返回的原始健康检查条目结构含Node、Service、Checks等字段类型定义见 packages/consul/src/interface.ts 中的ConsulHealthItem组件并不知道应用层使用 Consul 的哪些元数据信息因此不做过多的结构转换无实例时会抛 Errorselect在“没有任何可用服务实例”的场景下会抛出异常业务代码需要自行捕获或降级处理。select的第二个参数控制是否只选取健康实例默认true/缺省仅返回通过健康检查的实例传入false时则可能取到不健康的实例。4.1 与 Service Discovery 的关系consul:balancerService的负载均衡能力建立在服务发现之上。ConsulServiceDiscovery对外提供以下核心方法见 packages/consul/src/extension/serviceDiscovery.tscreateClient()创建服务发现客户端内部实现register/deregister/online/offline/beforeStop等方法getInstances(options)获取某个服务当前的健康实例列表内部强制passing: true即只返回健康检查通过的实例getInstance(options)从实例列表中选取单个实例。其数据链路可以总结为ConsulDataListener首次调用client.health.service(options)拉取全量实例作为初始数据initData随后通过client.watch({ method: client.health.service, options })建立 Consul watch 长轮询监听实例列表变化时自动setData更新见onData多个查询请求按hashServiceOptions基于排序 key 的 DJB2 变体哈希见 packages/consul/src/utils.ts做缓存同一服务复用同一个ConsulDataListener避免重复建立 watch应用停止时beforeStop统一销毁所有 listener 的 watcher。从源码结构看ConsulServiceDiscoverClient.register的流程还包括注册成功后调用online()把实例状态置为UP内部走agent.check.pass(checkId)checkId 形如service:${instance.id}offline()则对应agent.check.fail。测试用例 packages/consul/test/serviceDiscovery.test.ts 中完整演示了注册携带check: { name, timeout, ttl }的 TTL 健康检查、getInstances查询、getInstance选取以及offline()后健康实例列表归零的完整流程。五、注入原生 Consul 对象除了组件封装的高层能力还可以直接注入官方consul客户端使用其完整 APIimport * as Consul from consul; // 使用 consul 官方包装的 API 接口 Inject(consul:consul) consul: Consul.Consul;注入后即可直接调用官方库方法例如// KV 读写 await this.consul.kv.set(my/key, my-value); const res await this.consul.kv.get(my/key); // 查询健康服务 const services await this.consul.health.service({ service: the-service-name });底层实现上ConsulServicepackages/consul/src/manager.ts是一个Singleton()初始化时从ConsulServiceFactory中取出默认客户端getDefaultClientName()未定义时取default并通过delegateTargetAllPrototypeMethod(ConsulService, Consul)把原生 Consul 类的原型方法全部委托到该实例上因此注入后具备与原生客户端完全一致的方法集。5.1 多客户端与自定义客户端ConsulServiceFactory继承自 Midway 的ServiceFactory支持按consul.client.xxx的形式配置多个客户端测试用例 packages/consul/test/index.test.ts 中展示了consul.client.host/port的配置写法。此外createClient支持customClientClass配置项——若传入自定义类则使用new customClientClass(otherConfig)构造客户端packages/consul/test/customClient.test.ts 有对应用例适合替换或包装客户端实现的场景。六、健康检查机制源码级解读当service定义中携带check字段且autoHealthCheck开启时ConsulServiceDiscoverClient.register会根据检查类型自动启动对应的健康检查器实现位于 packages/consul/src/extension/helper.ts检查类型触发条件实现类行为TTL 心跳check.ttl存在TTLHeartbeat按calculateTTL(check.ttl)计算间隔最小 1000ms支持30s、1m等 ms 库格式周期性调用agent.check.pass(checkId)上报心跳失败时输出错误日志HTTP 探活check.http存在HTTPHealthCheck解析 URL 的端口与路径若当前应用是 Egg/Koa/Express 应用则把该路径注册进框架路由返回success否则自起一个 HTTP 服务在对应端口路径返回okTCP 探活check.tcp存在TCPHealthCheck自起一个 TCP 服务监听对应端口/主机连接成功即关闭用于验证端口可达应用关闭时beforeStop会依次停止 TTL 心跳与 HTTP/TCP 健康检查服务并完成deregister()反注册确保资源释放干净。七、完整的最小可运行示例综合以上内容一个完整的最小接入方案如下1. 安装npm i midwayjs/consul -S npm i types/consul -D2. 入口 configuration.tsimport { Configuration } from midwayjs/core; import { join } from path; import * as consul from midwayjs/consul; Configuration({ imports: [consul], importConfigs: [join(__dirname, config)], }) export class ContainerConfiguration {}3. 配置 config/config.default.tsexport default { consul: { provider: { register: true, deregister: true, host: 192.168.0.10, port: 8500, strategy: random, }, service: { address: 127.0.0.1, port: 7001, tags: [tag1, tag2], check: { name: TTL Health Check, timeout: 30s, ttl: 10s, }, }, }, };4. 调用远端服务import { Inject, Provide } from midwayjs/core; import { IConsulBalancer } from midwayjs/consul; Provide() export class RemoteCallService { Inject(consul:balancerService) balancerService: IConsulBalancer; async call() { // 只选健康实例 const healthy await this.balancerService.getBalancer().select(user-service); // 或允许不健康实例 const any await this.balancerService.getBalancer().select(user-service, false); return { healthy, any }; } }八、常见问题与注意事项select 抛错没有可用的服务实例时select会抛出Error请务必 try/catch 或结合降级逻辑如直接返回默认地址使用注册与反注册的开关register/deregister均为可选开关生产环境建议都开启避免服务下线后实例仍在 Consul 中残留策略选择provider.strategy默认random若需均匀分发可关注serviceDiscovery.loadBalancer的roundRobin配置组件默认即roundRobin返回数据为原生结构select/getInstances返回的是 Consul 健康检查原始数据结构Node/Service/Checks字段名遵循 Consul API 的大写风格需按 ConsulHealthItem 类型定义取用多环境配置Midway 的importConfigs机制支持config.default/config.prod/config.test等按环境覆盖 Consul 地址与开关便于本地与线上隔离。九、更多源码入口组件生命周期与默认配置packages/consul/src/configuration.ts客户端工厂、原生客户端注入与委托packages/consul/src/manager.ts服务发现与数据监听watch、缓存、注册/反注册packages/consul/src/extension/serviceDiscovery.tsTTL 心跳 / HTTP / TCP 健康检查实现packages/consul/src/extension/helper.ts类型定义ConsulHealthItem、GetHealthServiceOptions、ConsulServiceDiscoveryOptionspackages/consul/src/interface.ts官方用法文档packages/consul/usage.md功能测试用例packages/consul/test/index.test.ts 与 packages/consul/test/serviceDiscovery.test.ts赞分享后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载相关推荐gh_mirrors/docume/documentation微前端架构大型项目的模块化拆分方案gh_mirrors/docume/documentation微前端架构大型项目的模块化拆分方案 gh_mirrors/docume/documentatio微服务架构中Consul健康检查的终极指南确保服务高可用的关键步骤微服务架构中Consul健康检查的终极指南确保服务高可用的关键步骤 在微服务架构中服务注册与发现是确保系统弹性和可靠性的核心组件。Consul作为一款功能全文档教程知识库技术博客后端抖音无水印批量下载3步搞定备份创作者全部作品抖音无水印批量下载3步搞定备份创作者全部作品 douyin downloader 是一个实用的抖音批量下载工具主打无水印下载。它直接解析作品的原始文件地址网页爬虫CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表