- 后端
- 微服务
【免费下载链接】loopback-next
LoopBack makes it easy to build modern API applications that require complex integrations.
导读
本文基于 LoopBack 4 官方仓库中的@loopback/example-metrics-prometheus示例项目,系统讲解如何为 LoopBack 4 应用接入 Prometheus 指标监控:从启动应用、生成流量,到通过/metrics端点查看 Node.js 进程级指标与 LoopBack 方法调用指标,再到在 Prometheus Web UI 中进行查询与可视化。读完本文,你将掌握@loopback/metrics扩展组件的安装、注册、配置与底层实现原理,并能在自己的 LoopBack 4 应用中复现整套"Pull 模式"监控方案。
示例项目概述
examples/metrics-prometheus是一个用于演示@loopback/metrics扩展与 Prometheus 集成的官方示例。它构建了一个简单的"问候服务":通过 REST 接口批量生成并发调用流量,再由@loopback/metrics组件采集两类指标——Node.js 运行时指标(由 prom-client 提供)与 LoopBack 方法调用指标(由组件内置的拦截器提供),最终暴露为标准 Prometheus 文本格式,供 Prometheus 服务抓取(Pull 模式)。
项目的核心依赖关系可从 examples/metrics-prometheus/package.json 中看到:
@loopback/boot、@loopback/core、@loopback/rest:LoopBack 4 应用的基础框架;@loopback/metrics:本示例的核心演示对象,负责指标采集与暴露;@loopback/testlab:开发依赖,用于集成测试。
快速上手:启动应用并生成监控流量
直接启动
在示例目录下执行:
npm startstart脚本会先执行rebuild(即clean+build),再以node .启动应用。应用启动后,终端会输出两类地址信息(见 examples/metrics-prometheus/src/index.ts):
Greeting service is running at http://127.0.0.1:3000/greet/world?count=5. Metrics is running at http://127.0.0.1:3000/metrics默认监听地址与端口来自index.ts中的配置:
const config = { rest: { port: +(process.env.PORT ?? 3000), host: process.env.HOST ?? '127.0.0.1', openApiSpec: { setServersFromRequest: true, }, }, };即默认绑定127.0.0.1:3000,可通过环境变量PORT、HOST覆盖。
运行完整演示
npm run demodemo脚本(package.json 中定义为./bin/demo.sh)会拉起完整的演示环境——包括应用本身与配套的 Prometheus 服务。
生成监控流量
启动后,在浏览器中访问以下地址产生一批并发调用:
http://127.0.0.1:3000/greet/world?count=50这条请求由GreetingController处理(见 examples/metrics-prometheus/src/controllers/greeting.controller.ts):
@get('/greet/{name}') async greet( @param.path.string('name') name: string, @param.query.number('count') count = 1, ) { const tasks: Promise<string>[] = []; for (let i = 0; i < count; i++) { tasks.push(this.greetingService.greet(name)); } return Promise.all(tasks); }- 路径参数
name为问候对象; - 查询参数
count(默认 1)控制并发调用次数,count=50意味着同时发起 50 次服务调用; - 所有调用通过
Promise.all并行执行,能制造出可观的方法调用流量,便于观察指标变化。
底层GreetingService(见 examples/metrics-prometheus/src/services/greeting.service.ts)为每次调用注入 0~100ms 的随机延迟:
@injectable({tags: {[ContextTags.NAMESPACE]: 'services'}}) export class GreetingService { async greet(name: string) { const ts = new Date().toISOString(); // Delay for a random duration between 0 and 100ms const delayInMs = Math.floor(Math.random() * 100); await sleep(delayInMs); return `[${ts}: ${delayInMs}] Hello, ${name}`; } }随机延迟使得调用耗时呈现分布特征,让直方图(histogram)与摘要(summary)类指标展示出更有意义的形态。
查看指标端点
生成流量后,访问:
http://127.0.0.1:3000/metrics即可看到 Prometheus 文本格式的指标输出,内容包括:
- Node.js 进程指标:CPU 时间(
process_cpu_user_seconds_total等)、内存占用(process_resident_memory_bytes)、事件循环延迟(nodejs_eventloop_lag_seconds)、活动句柄/请求数、V8 堆大小等; - LoopBack 方法调用指标:以
loopback_invocation_为前缀的四类指标(详见下文"拦截器采集的四类指标")。
指标端点的底层实现
/metrics端点由@loopback/metrics组件动态注册的MetricsController提供。见 extensions/metrics/src/controllers/metrics.controller.ts:
@injectable({scope: BindingScope.SINGLETON}) class MetricsController { @get(basePath, spec) async report(@inject(RestBindings.Http.RESPONSE) res: Response) { // Set the content type from the register res.contentType(register.contentType); const data = await register.metrics(); res.send(data); return res; } }关键点:
- 端点路径
basePath默认/metrics,可通过配置修改; - 响应内容类型与数据均取自 prom-client 的全局注册表
register; - 端点默认在 OpenAPI 规格中隐藏(
x-visibility: undocumented),因此不会出现在 API Explorer 中,除非显式开启openApiSpec: true。
端点安全性说明
由于指标可能泄露内部信息,默认将端点从 OpenAPI 规格中隐藏。实际部署时建议通过防火墙、反向代理鉴权等方式进一步保护该端点,或将其迁移到独立的内网端口。
在 Prometheus Web UI 中查看指标
打开:
http://localhost:9090即可访问示例项目配套启动的 Prometheus Web UI。在其中可以:
- 使用 PromQL 查询指标,例如
loopback_invocation_total、nodejs_eventloop_lag_seconds; - 按标签(如
method、path、statusCode)过滤指标; - 将查询结果渲染为图表,观察调用量与延迟随时间的变化。
下面的截图来自本示例项目,展示了 Prometheus Web UI 中查询 LoopBack 方法调用指标并绘制出随时间变化的曲线(图片位于 examples/metrics-prometheus/prometheus-demo.png):
@loopback/metrics 组件:安装与注册
安装
npm install --save @loopback/metrics该包依赖prom-client(见 extensions/metrics/package.json),并声明@loopback/core、@loopback/rest为 peerDependencies。当前版本以0.x.y发布,属于**实验性(Experimental)**扩展,API 在未来版本中可能有破坏性变更,生产环境接入需关注版本演进。
在应用中注册
示例应用的注册方式极为简洁(见 examples/metrics-prometheus/src/application.ts):
import {BootMixin} from '@loopback/boot'; import {ApplicationConfig} from '@loopback/core'; import {MetricsComponent} from '@loopback/metrics'; import {RestApplication} from '@loopback/rest'; export class GreetingApplication extends BootMixin(RestApplication) { constructor(config: ApplicationConfig = {}) { super(config); this.projectRoot = __dirname; this.component(MetricsComponent); } }只需要在自定义Application的构造函数中调用this.component(MetricsComponent)一行代码,即可获得完整的指标能力。
组件内部装配了什么
从 extensions/metrics/src/metrics.component.ts 的源码可以看到,注册组件后会按配置条件化地装配以下构件:
if (options.defaultMetrics && !options.defaultMetrics.disabled) { this.application.lifeCycleObserver(MetricsObserver); } if (options.pushGateway && !options.pushGateway.disabled) { this.application.lifeCycleObserver(MetricsPushObserver); } this.application.add(createBindingFromClass(MetricsInterceptor)); if (options.endpoint && !options.endpoint.disabled) { this.application.controller(metricsControllerFactory(options)); } if (options.defaultLabels) { register.setDefaultLabels(options.defaultLabels); }即:
| 构件 | 作用 | 启用条件 |
|---|---|---|
MetricsObserver | 生命周期观察者,启动时调用 prom-client 的collectDefaultMetrics采集 Node.js 默认指标 | defaultMetrics未禁用(默认启用) |
MetricsPushObserver | 按固定周期把指标推送到 Pushgateway(Push 模式) | 配置了pushGateway且未禁用 |
MetricsInterceptor | 全局拦截器,为 LoopBack 方法调用采集指标 | 始终注册 |
MetricsController | 暴露/metrics拉取端点 | endpoint未禁用(默认启用) |
| 默认标签 | 通过register.setDefaultLabels为所有指标附加静态标签 | 配置了defaultLabels |
默认配置项
DEFAULT_METRICS_OPTIONS定义于 extensions/metrics/src/types.ts:
export const DEFAULT_METRICS_OPTIONS: MetricsOptions = { endpoint: { basePath: '/metrics', }, defaultMetrics: {}, openApiSpec: false, };组件构造时会将用户配置与默认配置合并:{...DEFAULT_METRICS_OPTIONS, ...metricsConfig},因此未配置的选项自动取默认值。
深入配置 MetricsOptions
MetricsOptions的完整结构(见 extensions/metrics/src/types.ts):
export interface MetricsOptions { endpoint?: { disabled?: boolean; basePath?: string; }; defaultMetrics?: { disabled?: boolean; } & DefaultMetricsCollectorConfiguration; // prom-client 的默认指标采集配置 defaultLabels?: { [labelName: string]: string; }; pushGateway?: { disabled?: boolean; url: string; interval?: number; // 推送周期,默认 5000ms jobName?: string; // 任务名,默认 'loopback' groupingKey?: {[key: string]: string}; replaceAll?: boolean; // true 使用 push(覆盖),false 使用 pushAdd(追加) }; openApiSpec?: boolean; }配置示例
在注册组件之前调用this.configure(MetricsBindings.COMPONENT).to({...})即可自定义配置:
import {MetricsBindings} from '@loopback/metrics'; this.configure(MetricsBindings.COMPONENT).to({ endpoint: { basePath: '/metrics', }, defaultMetrics: { timeout: 5000, }, defaultLabels: { service: 'api', version: '1.0.0', }, });重要:this.configure()必须在this.component()之前调用才能生效。
常用配置项说明
| 配置项 | 默认值 | 说明 |
|---|---|---|
endpoint.basePath | /metrics | 指标暴露路径,可改为如/internal/metrics |
endpoint.disabled | false | 设为true时不注册指标控制器,/metrics返回 404 |
defaultMetrics.disabled | false | 设为true时停止 Node.js 默认指标采集 |
defaultMetrics.prefix | 无 | 为默认指标统一添加前缀(如myapp_) |
defaultLabels | 无 | 为所有指标附加静态标签(如服务名、版本号) |
openApiSpec | false | 设为true后指标端点出现在 OpenAPI 规格中,可在 API Explorer 中看到 |
pushGateway | 未启用 | 配置url后启用 Push 模式 |
以上配置行为均有对应的验收测试佐证(见 extensions/metrics/src/tests/acceptance/metrics.acceptance.ts):例如basePath改为/internal/metrics后原/metrics返回 404;endpoint.disabled时控制器不注册;defaultMetrics.disabled时不再输出process_cpu_user_seconds_total;defaultLabels会同时出现在默认指标与方法调用指标中。
拦截器采集的四类 LoopBack 方法调用指标
MetricsInterceptor(见 extensions/metrics/src/interceptors/metrics.interceptor.ts)是@loopback/metrics的核心,以全局拦截器(asGlobalInterceptor('metrics'))注册,作用于所有方法调用,输出四类指标:
| 指标名 | 类型 | 含义 |
|---|---|---|
loopback_invocation_duration_seconds | Gauge | 当前方法调用的实时耗时(秒) |
loopback_invocation_duration_histogram | Histogram | 调用耗时的直方图分布(分桶统计) |
loopback_invocation_total | Counter | 方法调用累计次数 |
loopback_invocation_duration_summary | Summary | 调用耗时的分位数摘要(quantile) |
四类指标共用一组标签:
type LabelNames = 'targetName' | 'method' | 'path' | 'statusCode';targetName:被调用方法的全名,例如GreetingController.prototype.greet;method:HTTP 方法(大写),如GET、POST;path:路径模板(pattern)而非实际路径——这是刻意设计:若使用含动态参数的原始路径,每个不同的 ID 值都会产生新的时间序列,导致指标基数爆炸。见源码注释:// make sure to use path pattern instead of raw path // this is important since paths can contain unbounded sets of values // such as IDs which would create a new time series for each unique value return source.value.path;statusCode:响应状态码,拦截器在响应写回前执行,因此需要特殊推导:200 且无返回体的计为 204;异常时从错误对象读取statusCode(ENTITY_NOT_FOUND记为 404,其余无状态码时记 500)。
需要注意:该拦截器只覆盖方法调用本身,不包括在此之前执行的 Sequence 动作与中间件耗时。若需要更完整的链路指标,应在其他位置自行埋点。
理解 Pull 与 Push 两种采集模式
Prometheus 支持两种指标采集模式,@loopback/metrics同时支持:
- Pull(拉取)模式:Prometheus 定期向被监控系统暴露的 HTTP 指标端点发起抓取。这是常规模式,本示例默认采用,对应
/metrics端点; - Push(推送)模式:被监控系统主动把指标推送到 Prometheus Pushgateway,通常用于短暂存活的一次性任务(如批处理、CI 作业)。
@loopback/metrics通过MetricsPushObserver支持该模式。
Push 模式配置示例
this.configure(MetricsBindings.COMPONENT).to({ pushGateway: { url: 'http://127.0.0.1:9091', // Pushgateway 地址 interval: 5000, // 每 5 秒推送一次 jobName: 'my_job', groupingKey: {env: 'test'}, replaceAll: false, // false 使用 pushAdd 追加;true 使用 push 覆盖 }, });其实现见 extensions/metrics/src/observers/metrics.push.observer.ts:start()时创建Pushgateway实例,用setInterval按interval(默认 5000ms)周期推送;replaceAll为true时调用gateway.push()(整体覆盖),否则调用gateway.pushAdd()(追加合并);jobName默认'loopback'。
推送行为在 extensions/metrics/src/tests/acceptance/metrics-push.acceptance.ts 中有完整测试覆盖,包括自定义jobName、groupingKey与replaceAll三种组合。
测试与验证
运行示例测试
npm test示例项目包含一条集成测试(见 examples/metrics-prometheus/src/tests/integration/greeting-service.integration.ts),验证两个核心行为:
- 访问
/greet/Raymond返回 200 且响应体为数组,元素匹配Hello, Raymond; - 访问
/metrics返回 200 且文本中包含loopback_invocation_duration_seconds的 TYPE 声明。
@loopback/metrics 的验收测试
@loopback/metrics扩展自身的验收测试(extensions/metrics/src/tests/acceptance/metrics.acceptance.ts)则覆盖了更细粒度的行为,可作为理解组件能力的参考:
- 默认配置下
/metrics返回含# TYPE、# HELP的文本; - 指标端点默认不出现在 OpenAPI 规格中,开启
openApiSpec后出现在规格中; - 不同 HTTP 方法(GET/POST/PUT/PATCH/DELETE)都会产出带
method标签的指标; - 不同状态码(200/204/302/400/404/500)正确映射到
statusCode标签; - 动态路径使用路径模板:请求
/path/1产出path="/path/{param}"; - 纯拦截代理调用(非 REST 路由)只有
targetName标签,没有method/path/statusCode。
总结:把监控接入自己的 LoopBack 4 应用
把本示例的能力迁移到自己的项目,只需四步:
- 安装:
npm install --save @loopback/metrics; - 注册:在应用构造函数中调用
this.component(MetricsComponent)(先configure再component可定制行为); - 配置:按需设置
endpoint、defaultMetrics、defaultLabels、pushGateway等选项; - 抓取:在 Prometheus 的
scrape_configs中配置 target 指向应用的/metrics地址,即可开始采集。
在此基础上,还可以参考MetricsOptions的类型定义,使用 prom-client 的 API 在业务代码中自定义 Counter、Gauge、Histogram 等业务指标,形成"Node.js 运行时 + LoopBack 框架 + 业务自定义"三层完整的可观测性体系。
- 后端
- 微服务
【免费下载链接】loopback-next
LoopBack makes it easy to build modern API applications that require complex integrations.
相关推荐
LoopBack 4 集成 Prometheus 指标采集:@loopback/metrics 组件实战指南
LoopBack 4 集成 Prometheus 指标采集:@loopback/metrics 组件实战指南 @loopback/metrics 是 LoopB
后端微服务网盘直链下载:九大网盘一步拿到直链,全程零客户端
网盘直链下载:九大网盘一步拿到直链,全程零客户端 借同事电脑从 123 云盘取一套课程资料,网页上的下载按钮只通向安装客户端——在别人的机器上装软件不合适,逐个
后端微服务LoopBack 4 迁移实战:用 Casbin 重构 LoopBack 3 访问控制示例(access-control-migration)
LoopBack 4 迁移实战:用 Casbin 重构 LoopBack 3 访问控制示例(access control migration) LoopBack
后端微服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考