npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tecace/nest-consul

v0.0.3

Published

nest-consul

Readme

@tecace/nest-consul

请注意:本工具的主要目的是为了帮助 NestJS 用户更轻松地进行 consul 服务注册和健康检查,而不是为了封装 Consul 的 API。使用该工具时,可以选择自动或手动注册服务,然后通过 api 获取 Consul 实例,可以像使用官方 API 一样使用它来管理服务或进行二次封装。

base on [email protected] https://www.npmjs.com/package/consul/v/1.2.0

基于 node-consul 的 1.2.0 版本封装的 nestjs 版本,封装了服务和健康检查注册/注销,kv 存储操作,获取其他服务的url等功能,绑定了自动注册服务/健康检查,可以手动注销服务和健康检查。

Documentation

install

npm install @tecace/nest-consul
# or
pnpm add @tecace/nest-consul

use

这里只是核心的代码,当中还涉及了微服务的创建,运行等,参考官方文档 https://docs.nestjs.com/microservices/grpc#grpc

注册module

单独注册ConsulModule

// app.modules.ts or any.modules.ts
import { ConsulModule, ConsulService } from '@tecace/nest-consul';

@Module({
  imports: [
    // 参数类型是InitOptions, 下文会提到InitOptions的类型
    ConsulModule.register({
      host: 'localhost',
      port: '8500',
      promisify: true,
      autoRegister: true, // 自动注册服务与健康检查
      registerOptions: {
        // 服务配置
        id: 'user-service',
        name: 'user-service',
        port: 5001,
        address: 'localhost',
      },
      check: {
        // 可选,健康检查配置,要注册健康检查,需要开发好对应接口,consul会根据提供的grpc/http等类型进行检查
        id: 'user_health_check',
        name: 'user_health_check',
        // http: 'localhost:5001/health/check'
        grpc: 'localhost:5001',
        interval: '15s',
        ttl: '10s',
      },
    }),
  ],
  controllers: [AppController],
  providers: [ConsulService], // 需要提供ConsulService,在AppController中才能使用consulService
})
export class AppModule {}

或在微服务ClientsModule中注册


import { ClientsModule, Transport } from '@nestjs/microservices';

// 省略部分代码
ClientsModule.registerAsync([
      {
        imports: [
          // 在微服务中注册ConsulModule
          ConsulModule.register({
            host: '10.211.55.14',
            port: '8500',
            promisify: true,
            autoRegister: true,
            registerOptions: {
              id: 'category-service',
              name: 'category-service',
              port: 5002,
              address: '192.168.31.117',
            },
            check: {
              id: 'category_health_check',
              name: 'category_health_check',
              grpc: '192.168.31.117:5002',
              interval: '15s',
              ttl: '10s',
            },
          }),
        ],
        name: 'UserGrpcClient',
        useFactory: async (consulSrv: ConsulService) => {
          const url = await consulSrv.getServiceUrl('user-service'); // 在另外一个微服务中获取user-service注册相关的url,以便进行通信
          return {
            name: 'UserGrpcClient',
            transport: Transport.GRPC,
            options: {
              url,
              package: protosLoader.getPackages(),
              protoPath: protosLoader.getProtos(),
            },
          };
        },
        inject: [ConsulService],
      },
    ]),
// 省略部分代码
// app.controller.ts or any.controller.ts
import { Controller, Inject } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
import { ConsulService } from '@tecace/nest-consul';
@Controller()
export class AppController {
  // 这里注入了consulService的实例,会基于在app.module.ts中导入模块的配置进行操作
  constructor(@Inject(ConsulService) private consulService: ConsulService) {}

  // 这里需要实现grpc健康检查
  @GrpcMethod('Health', 'Check')
  healthCheck() {
    return {
      status: 1,
    };
  }

  // 实现服务和健康检查的注销
  @GrpcMethod('Health', 'Deregister')
  async deregister() {
    const [err] = await this.consulService.srvDeregistration();
    if (err) {
      console.error(err);
    }
  }

  // 实现服务和检查检查的注册
  @GrpcMethod('Health', 'Register')
  async register() {
    const [err] = await this.consulService.srvRegistration();
    if (err) {
      console.error(err);
    }
  }
}

注意:如果使用 grpc 进行健康检查,这个包名不可以改动 注意:如果使用 grpc 进行健康检查,这个包名不可以改动 注意:如果使用 grpc 进行健康检查,这个包名不可以改动

PS: I don't know why, 每次改了健康检查它就是不行。

protofile 官方原代码:https://github.com/grpc/grpc/blob/master/doc/health-checking.md

下面的 proto 文件是笔者增加了一些

syntax = "proto3";

package grpc.health.v1;

message HealthCheckRequest {
  string service = 1;
}

message HealthCheckResponse {
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
    SERVICE_UNKNOWN = 3;  // Used only by the Watch method.
  }
  ServingStatus status = 1;
}

message Empty {}

service Health {
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
  rpc Deregister(Empty) returns (Empty);
  rpc Register(Empty) returns (Empty);
  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}

api

getConsulInstance(): Consul.Consul; 核心 api

返回初始化后的 consul 实例,从而像使用官方 API 一样使用,初始化 Consul 阶段基于 InitOptions 中的 ConsulOptions 部分,InitOptions 请查看下一小节

const consul = consulService.getConsulInstance();
// 假如要使用catalog
consul.catalog.register(options)
// 要使用session
consul.session.create();

constructor(consulOptions: InitOptions);

ConsulModule.register(consulOptions: InitOptions)

// InitOptions是基于官方提供的类型进行合并或者扩展
export type InitOptions = ConsulOptions & {
  autoRegister?: boolean; //是否自动注册
  registerOptions: Consul.Agent.Service.RegisterOptions; // 服务配置
  // 健康检查配置
  check?: Consul.Agent.Check.RegisterOptions & {
    id: string;
    grpc?: string;
  };
};

srvRegistration(): Promise<[err: string]>;

服务和健康检查注册,如果在 InitOptions 中提供了 autoRegister,那么这个 api 在初始化阶段会自动调用

const [err] = await consulService.srvRegistration();

srvDeregistration(): Promise<[err: string]>;

服务和健康检查注销

const [err] = await consulService.srvDeregistration();

kvSet(data: Consul.Kv.SetOptions): Promise<[err: string]>;

k/v 存的设置,data 类型是 Consul.kv.SetOptions

const [err] = await consulService.kvSet({
  key: 'someKey',
  value: 'someValue',
  dc: 'datacenter in your defination',
  ...
});

kvGet(data: Consul.Kv.GetOptions): Promise<[err: string, data: any]>;

k/v 获取的设置,data 类型是 Consul.kv.GetOptions

const [err, res] = await consulService.kvGet({
  key: 'someKey',
  dc: 'datacenter in your defination',
  ...
});

getService(serviceName?: string): Promise<[err: string, data: ConsulServiceList | ConsulServiceDetail | null]>;

获取 service 列表或者service的详情,传了serviceName返回对应的详情,反之返回列表

const [err, serviceList] = await consulSrv.getService();  // 返回列表

const [err, serviceDetail] = await consulSrv.getService("user-service") // 返回详情

getServiceUrl(serviceName?: string): Promise<[err: string, data: ConsulServiceList | ConsulServiceDetail | null]>;

获取 service 列表或者service的详情,传了serviceName返回对应的详情,反之返回列表

const [err, url] = await consulSrv.getServiceUrl('user-service');
// url host:port
// err null