@danqiusheng/nest-nacos 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +509 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/nacos-config.service.d.ts +62 -0
- package/dist/nacos-config.service.d.ts.map +1 -0
- package/dist/nacos-config.service.js +179 -0
- package/dist/nacos-config.service.js.map +1 -0
- package/dist/nacos-naming.service.d.ts +68 -0
- package/dist/nacos-naming.service.d.ts.map +1 -0
- package/dist/nacos-naming.service.js +153 -0
- package/dist/nacos-naming.service.js.map +1 -0
- package/dist/nacos.constants.d.ts +8 -0
- package/dist/nacos.constants.d.ts.map +1 -0
- package/dist/nacos.constants.js +13 -0
- package/dist/nacos.constants.js.map +1 -0
- package/dist/nacos.decorators.d.ts +9 -0
- package/dist/nacos.decorators.d.ts.map +1 -0
- package/dist/nacos.decorators.js +27 -0
- package/dist/nacos.decorators.js.map +1 -0
- package/dist/nacos.health.d.ts +14 -0
- package/dist/nacos.health.d.ts.map +1 -0
- package/dist/nacos.health.js +57 -0
- package/dist/nacos.health.js.map +1 -0
- package/dist/nacos.interfaces.d.ts +99 -0
- package/dist/nacos.interfaces.d.ts.map +1 -0
- package/dist/nacos.interfaces.js +3 -0
- package/dist/nacos.interfaces.js.map +1 -0
- package/dist/nacos.module.d.ts +17 -0
- package/dist/nacos.module.d.ts.map +1 -0
- package/dist/nacos.module.js +78 -0
- package/dist/nacos.module.js.map +1 -0
- package/dist/nacos.providers.d.ts +16 -0
- package/dist/nacos.providers.d.ts.map +1 -0
- package/dist/nacos.providers.js +78 -0
- package/dist/nacos.providers.js.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 丹丘生
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# nest-nacos 使用文档
|
|
2
|
+
|
|
3
|
+
> NestJS Nacos 插件 —— 服务发现 + 配置中心,基于 [nacos-sdk-nodejs](https://github.com/nacos-group/nacos-sdk-nodejs),支持 gRPC 传输协议(Nacos 2.x / 3.x)。
|
|
4
|
+
|
|
5
|
+
**版本**:v1.0.0 | **License**:MIT
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 目录
|
|
10
|
+
|
|
11
|
+
1. [介绍](#1-介绍)
|
|
12
|
+
2. [安装](#2-安装)
|
|
13
|
+
3. [快速开始](#3-快速开始)
|
|
14
|
+
4. [同步配置 forRoot](#4-同步配置-forroot)
|
|
15
|
+
5. [异步配置 forRootAsync](#5-异步配置-forrootasync)
|
|
16
|
+
6. [服务发现](#6-服务发现)
|
|
17
|
+
7. [配置中心](#7-配置中心)
|
|
18
|
+
8. [装饰器](#8-装饰器)
|
|
19
|
+
9. [健康检查](#9-健康检查)
|
|
20
|
+
10. [API: NacosNamingService](#10-api-nacosnamingservice)
|
|
21
|
+
11. [API: NacosConfigService](#11-api-nacosconfigservice)
|
|
22
|
+
12. [配置项参考](#12-配置项参考)
|
|
23
|
+
13. [常见问题](#13-常见问题)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. 介绍
|
|
28
|
+
|
|
29
|
+
**nest-nacos** 是一个 NestJS 插件,封装了 `nacos-sdk-nodejs`,为 NestJS 应用提供 **服务发现** 和 **配置中心** 能力。基于 gRPC 传输协议,支持 Nacos 2.x / 3.x 服务端。
|
|
30
|
+
|
|
31
|
+
### 特性
|
|
32
|
+
|
|
33
|
+
| 特性 | 说明 |
|
|
34
|
+
|------|------|
|
|
35
|
+
| 动态模块 | 支持 `forRoot` / `forRootAsync`,可配合 `@nestjs/config` 从环境变量读取配置 |
|
|
36
|
+
| 自动注册 | 模块初始化时自动注册服务实例,销毁时自动注销,无需手动管理生命周期 |
|
|
37
|
+
| 配置热更新 | 订阅配置变更,服务端实时推送,内置本地缓存与 JSON 解析 |
|
|
38
|
+
| gRPC 传输 | 默认使用 gRPC,服务端实时推送,无需 UDP 端口,支持自动重连 |
|
|
39
|
+
| 装饰器注入 | 提供 `@InjectNacosNaming` / `@InjectNacosConfig` 装饰器,简化依赖注入 |
|
|
40
|
+
| 健康检查 | 内置 `NacosHealthIndicator`,可对接 `@nestjs/terminus` 暴露健康端点 |
|
|
41
|
+
|
|
42
|
+
### 兼容性
|
|
43
|
+
|
|
44
|
+
| nest-nacos | nacos-sdk-nodejs | Nacos Server | 传输协议 |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| 1.x | 2.6.x | 3.x / 2.x | gRPC(默认)/ HTTP(仅 2.x) |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 2. 安装
|
|
51
|
+
|
|
52
|
+
### 步骤 1:安装 nest-nacos 和 nacos SDK
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# 使用 npm
|
|
56
|
+
npm install nest-nacos nacos
|
|
57
|
+
|
|
58
|
+
# 使用 yarn
|
|
59
|
+
yarn add nest-nacos nacos
|
|
60
|
+
|
|
61
|
+
# 使用 pnpm
|
|
62
|
+
pnpm add nest-nacos nacos
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 步骤 2:确保宿主依赖已安装
|
|
66
|
+
|
|
67
|
+
以下包是 peerDependencies,通常 NestJS 项目中已存在:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install @nestjs/common @nestjs/core reflect-metadata rxjs
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 步骤 3:(可选)安装配置模块
|
|
74
|
+
|
|
75
|
+
如果需要从 `.env` 文件读取 Nacos 配置,安装 `@nestjs/config`:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install @nestjs/config
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> **提示**:Nacos Server 版本选择:如果使用 Nacos 3.x,必须使用 gRPC 传输(默认)。HTTP 传输仅支持 Nacos 2.x。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 3. 快速开始
|
|
86
|
+
|
|
87
|
+
以下是一个最小可用示例,展示如何在 `AppModule` 中同时启用服务发现和配置中心:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Module } from '@nestjs/common';
|
|
91
|
+
import { NacosModule } from 'nest-nacos';
|
|
92
|
+
|
|
93
|
+
@Module({
|
|
94
|
+
imports: [
|
|
95
|
+
NacosModule.forRoot({
|
|
96
|
+
naming: {
|
|
97
|
+
serverList: '127.0.0.1:8848',
|
|
98
|
+
username: 'nacos',
|
|
99
|
+
password: 'nacos',
|
|
100
|
+
},
|
|
101
|
+
config: {
|
|
102
|
+
serverAddr: '127.0.0.1:8848',
|
|
103
|
+
},
|
|
104
|
+
instances: [
|
|
105
|
+
{ serviceName: 'order-service', ip: '192.168.1.100', port: 3000 },
|
|
106
|
+
],
|
|
107
|
+
}),
|
|
108
|
+
],
|
|
109
|
+
})
|
|
110
|
+
export class AppModule {}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
应用启动后,nest-nacos 会自动:
|
|
114
|
+
|
|
115
|
+
- 连接 Nacos 服务端
|
|
116
|
+
- 注册 `order-service` 实例(192.168.1.100:3000)
|
|
117
|
+
- 应用关闭时自动注销该实例
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 4. 同步配置 forRoot
|
|
122
|
+
|
|
123
|
+
适用于配置固定的场景,直接在代码中写入连接参数:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { NacosModule } from 'nest-nacos';
|
|
127
|
+
|
|
128
|
+
NacosModule.forRoot({
|
|
129
|
+
naming: {
|
|
130
|
+
serverList: '127.0.0.1:8848',
|
|
131
|
+
namespace: 'production',
|
|
132
|
+
username: 'nacos',
|
|
133
|
+
password: 'nacos',
|
|
134
|
+
},
|
|
135
|
+
config: {
|
|
136
|
+
serverAddr: '127.0.0.1:8848',
|
|
137
|
+
namespace: 'production',
|
|
138
|
+
},
|
|
139
|
+
// 启动时自动注册的实例
|
|
140
|
+
instances: [
|
|
141
|
+
{
|
|
142
|
+
serviceName: 'order-service',
|
|
143
|
+
ip: '192.168.1.100',
|
|
144
|
+
port: 3000,
|
|
145
|
+
weight: 1.0,
|
|
146
|
+
metadata: { version: '1.0.0' },
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
// 启动时预订阅的配置项
|
|
150
|
+
subscribeConfigs: [
|
|
151
|
+
{ dataId: 'database.yaml', group: 'DEFAULT_GROUP' },
|
|
152
|
+
{ dataId: 'redis.yaml', group: 'DEFAULT_GROUP' },
|
|
153
|
+
],
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 5. 异步配置 forRootAsync
|
|
160
|
+
|
|
161
|
+
适用于生产环境,配合 `@nestjs/config` 从环境变量或配置文件读取参数:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { Module } from '@nestjs/common';
|
|
165
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
166
|
+
import { NacosModule } from 'nest-nacos';
|
|
167
|
+
|
|
168
|
+
@Module({
|
|
169
|
+
imports: [
|
|
170
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
171
|
+
NacosModule.forRootAsync({
|
|
172
|
+
imports: [ConfigModule],
|
|
173
|
+
inject: [ConfigService],
|
|
174
|
+
useFactory: (config: ConfigService) => ({
|
|
175
|
+
naming: {
|
|
176
|
+
serverList: config.get('NACOS_SERVER_ADDR'),
|
|
177
|
+
namespace: config.get('NACOS_NAMESPACE'),
|
|
178
|
+
username: config.get('NACOS_USERNAME'),
|
|
179
|
+
password: config.get('NACOS_PASSWORD'),
|
|
180
|
+
},
|
|
181
|
+
config: {
|
|
182
|
+
serverAddr: config.get('NACOS_SERVER_ADDR'),
|
|
183
|
+
namespace: config.get('NACOS_NAMESPACE'),
|
|
184
|
+
},
|
|
185
|
+
instances: [
|
|
186
|
+
{
|
|
187
|
+
serviceName: config.get('SERVICE_NAME'),
|
|
188
|
+
ip: config.get('SERVICE_IP'),
|
|
189
|
+
port: config.get<number>('SERVICE_PORT'),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
}),
|
|
193
|
+
}),
|
|
194
|
+
],
|
|
195
|
+
})
|
|
196
|
+
export class AppModule {}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
对应的 `.env` 文件:
|
|
200
|
+
|
|
201
|
+
```env
|
|
202
|
+
NACOS_SERVER_ADDR=127.0.0.1:8848
|
|
203
|
+
NACOS_NAMESPACE=public
|
|
204
|
+
NACOS_USERNAME=nacos
|
|
205
|
+
NACOS_PASSWORD=nacos
|
|
206
|
+
SERVICE_NAME=order-service
|
|
207
|
+
SERVICE_IP=192.168.1.100
|
|
208
|
+
SERVICE_PORT=3000
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
> **说明**:`forRootAsync` 还支持 `useClass` 和 `useExisting` 两种方式,适合需要从远程配置中心或数据库读取 Nacos 连接参数的场景。
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 6. 服务发现
|
|
216
|
+
|
|
217
|
+
注入 `NacosNamingService` 即可使用服务注册与发现功能:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
221
|
+
import { NacosNamingService, InjectNacosNaming } from 'nest-nacos';
|
|
222
|
+
|
|
223
|
+
@Injectable()
|
|
224
|
+
export class RpcService implements OnModuleInit {
|
|
225
|
+
@InjectNacosNaming()
|
|
226
|
+
private readonly naming: NacosNamingService;
|
|
227
|
+
|
|
228
|
+
async onModuleInit() {
|
|
229
|
+
// 订阅 user-service 实例变更(服务端推送)
|
|
230
|
+
this.naming.subscribe('user-service', (hosts) => {
|
|
231
|
+
console.log(`user-service 实例数: ${hosts.length}`);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// 查询健康实例并调用
|
|
236
|
+
async callUserService() {
|
|
237
|
+
const instances = await this.naming.selectInstances('user-service');
|
|
238
|
+
if (instances.length === 0) {
|
|
239
|
+
throw new Error('user-service 无可用实例');
|
|
240
|
+
}
|
|
241
|
+
const target = instances[0];
|
|
242
|
+
return `http://${target.ip}:${target.port}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 运行时动态注册新实例
|
|
246
|
+
async registerTemp() {
|
|
247
|
+
await this.naming.register({
|
|
248
|
+
serviceName: 'temp-service',
|
|
249
|
+
ip: '10.0.0.5',
|
|
250
|
+
port: 8080,
|
|
251
|
+
ephemeral: true,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 7. 配置中心
|
|
260
|
+
|
|
261
|
+
注入 `NacosConfigService` 即可读取和订阅配置:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { Injectable, OnModuleInit } from '@nestjs/common';
|
|
265
|
+
import { NacosConfigService, InjectNacosConfig } from 'nest-nacos';
|
|
266
|
+
|
|
267
|
+
@Injectable()
|
|
268
|
+
export class DbService implements OnModuleInit {
|
|
269
|
+
@InjectNacosConfig()
|
|
270
|
+
private readonly nacosConfig: NacosConfigService;
|
|
271
|
+
|
|
272
|
+
private dbConfig: any;
|
|
273
|
+
|
|
274
|
+
async onModuleInit() {
|
|
275
|
+
// 1. 读取配置(自动解析 JSON)
|
|
276
|
+
this.dbConfig = await this.nacosConfig.getConfigAsJson('database.yaml');
|
|
277
|
+
|
|
278
|
+
// 2. 订阅配置热更新
|
|
279
|
+
this.nacosConfig.subscribe('database.yaml', 'DEFAULT_GROUP', (content) => {
|
|
280
|
+
this.dbConfig = JSON.parse(content);
|
|
281
|
+
console.log('数据库配置已热更新');
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async updateConfig() {
|
|
286
|
+
// 发布新配置
|
|
287
|
+
await this.nacosConfig.publish(
|
|
288
|
+
'database.yaml',
|
|
289
|
+
'DEFAULT_GROUP',
|
|
290
|
+
JSON.stringify({ host: '10.0.0.1', port: 3306 }),
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
> **缓存机制**:`getConfig()` 首次从 Nacos 拉取后会缓存到内存,后续调用直接返回缓存值。订阅配置变更时会自动更新缓存,无需手动管理。
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 8. 装饰器
|
|
301
|
+
|
|
302
|
+
nest-nacos 提供四个装饰器简化依赖注入:
|
|
303
|
+
|
|
304
|
+
| 装饰器 | 注入对象 | 说明 |
|
|
305
|
+
|--------|----------|------|
|
|
306
|
+
| `@InjectNacosNaming()` | `NacosNamingService` | 注入封装后的 Naming 服务 |
|
|
307
|
+
| `@InjectNacosConfig()` | `NacosConfigService` | 注入封装后的 Config 服务 |
|
|
308
|
+
| `@InjectNacosNamingClient()` | `NacosNamingClient` | 注入原始 SDK 客户端(高级用法) |
|
|
309
|
+
| `@InjectNacosConfigClient()` | `NacosConfigClient` | 注入原始 SDK 客户端(高级用法) |
|
|
310
|
+
|
|
311
|
+
使用示例:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
import { Injectable } from '@nestjs/common';
|
|
315
|
+
import {
|
|
316
|
+
NacosNamingService,
|
|
317
|
+
NacosConfigService,
|
|
318
|
+
InjectNacosNaming,
|
|
319
|
+
InjectNacosConfig,
|
|
320
|
+
} from 'nest-nacos';
|
|
321
|
+
|
|
322
|
+
@Injectable()
|
|
323
|
+
export class MyService {
|
|
324
|
+
@InjectNacosNaming()
|
|
325
|
+
private readonly naming: NacosNamingService;
|
|
326
|
+
|
|
327
|
+
@InjectNacosConfig()
|
|
328
|
+
private readonly config: NacosConfigService;
|
|
329
|
+
|
|
330
|
+
// 也可以用构造函数注入
|
|
331
|
+
constructor(
|
|
332
|
+
private readonly naming2: NacosNamingService,
|
|
333
|
+
private readonly config2: NacosConfigService,
|
|
334
|
+
) {}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 9. 健康检查
|
|
341
|
+
|
|
342
|
+
内置 `NacosHealthIndicator` 可对接 `@nestjs/terminus`:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { Controller, Get } from '@nestjs/common';
|
|
346
|
+
import { HealthCheckService } from '@nestjs/terminus';
|
|
347
|
+
import { NacosHealthIndicator } from 'nest-nacos';
|
|
348
|
+
|
|
349
|
+
@Controller('health')
|
|
350
|
+
export class HealthController {
|
|
351
|
+
constructor(
|
|
352
|
+
private health: HealthCheckService,
|
|
353
|
+
private nacos: NacosHealthIndicator,
|
|
354
|
+
) {}
|
|
355
|
+
|
|
356
|
+
@Get()
|
|
357
|
+
check() {
|
|
358
|
+
return this.health.check([
|
|
359
|
+
() => this.nacos.isHealthy(),
|
|
360
|
+
]);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
如果未安装 `@nestjs/terminus`,也可直接调用 `isHealthy()` 方法,返回 `{ status: 'up' | 'down' }`。
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 10. API: NacosNamingService
|
|
370
|
+
|
|
371
|
+
| 方法 | 参数 | 返回值 | 说明 |
|
|
372
|
+
|------|------|--------|------|
|
|
373
|
+
| `register(inst)` | `NacosInstanceOptions` | `Promise<void>` | 注册服务实例 |
|
|
374
|
+
| `deregister(inst)` | `NacosInstanceOptions` | `Promise<void>` | 注销服务实例 |
|
|
375
|
+
| `getAllInstances(serviceName, groupName?, clusters?, subscribe?)` | `string, ...` | `Promise<Host[]>` | 查询所有实例 |
|
|
376
|
+
| `selectInstances(serviceName, groupName?, clusters?, healthy?, subscribe?)` | `string, ...` | `Promise<Host[]>` | 查询健康实例 |
|
|
377
|
+
| `subscribe(info, listener)` | `string \| SubscribeInfo, Function` | `void` | 订阅实例变更推送 |
|
|
378
|
+
| `unSubscribe(info, listener?)` | `string \| SubscribeInfo, Function?` | `void` | 取消订阅 |
|
|
379
|
+
| `getServerStatus()` | 无 | `'UP' \| 'DOWN'` | 获取服务端状态 |
|
|
380
|
+
| `getRawClient()` | 无 | `NacosNamingClient \| null` | 获取原始 SDK 客户端 |
|
|
381
|
+
|
|
382
|
+
### subscribe 参数说明
|
|
383
|
+
|
|
384
|
+
`info` 参数支持两种形式:
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// 形式一:字符串(serviceName)
|
|
388
|
+
naming.subscribe('user-service', (hosts) => { ... });
|
|
389
|
+
|
|
390
|
+
// 形式二:对象(可指定分组和集群)
|
|
391
|
+
naming.subscribe(
|
|
392
|
+
{ serviceName: 'user-service', groupName: 'PROD_GROUP', clusters: 'BJ' },
|
|
393
|
+
(hosts) => { ... },
|
|
394
|
+
);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## 11. API: NacosConfigService
|
|
400
|
+
|
|
401
|
+
| 方法 | 参数 | 返回值 | 说明 |
|
|
402
|
+
|------|------|--------|------|
|
|
403
|
+
| `getConfig(dataId, group?)` | `string, string?` | `Promise<string>` | 获取配置内容(带缓存) |
|
|
404
|
+
| `getConfigAsJson<T>(dataId, group?)` | `string, string?` | `Promise<T>` | 获取配置并解析为 JSON |
|
|
405
|
+
| `publish(dataId, group, content)` | `string, string, string` | `Promise<boolean>` | 发布配置 |
|
|
406
|
+
| `remove(dataId, group)` | `string, string` | `Promise<boolean>` | 删除配置 |
|
|
407
|
+
| `subscribe(dataId, group, listener)` | `string, string, Function` | `void` | 订阅配置变更推送 |
|
|
408
|
+
| `unSubscribe(dataId, group, listener?)` | `string, string, Function?` | `void` | 取消订阅 |
|
|
409
|
+
| `getRawClient()` | 无 | `NacosConfigClient \| null` | 获取原始 SDK 客户端 |
|
|
410
|
+
|
|
411
|
+
> **默认 group**:`getConfig()` 和 `getConfigAsJson()` 的 `group` 参数默认值为 `'DEFAULT_GROUP'`,如果配置在默认分组下可省略。
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 12. 配置项参考
|
|
416
|
+
|
|
417
|
+
### NacosModuleOptions
|
|
418
|
+
|
|
419
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
420
|
+
|------|------|------|------|
|
|
421
|
+
| `naming` | `NacosNamingOptions` | 否 | Naming 服务发现配置,不传则不启用 |
|
|
422
|
+
| `config` | `NacosConfigOptions` | 否 | Config 配置中心配置,不传则不启用 |
|
|
423
|
+
| `instances` | `NacosInstanceOptions[]` | 否 | 启动时自动注册的服务实例列表 |
|
|
424
|
+
| `subscribeConfigs` | `{ dataId, group }[]` | 否 | 启动时预订阅的配置项列表 |
|
|
425
|
+
|
|
426
|
+
### NacosNamingOptions
|
|
427
|
+
|
|
428
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
429
|
+
|------|------|--------|------|
|
|
430
|
+
| `serverList` | `string \| string[]` | - | Nacos 服务端地址 |
|
|
431
|
+
| `namespace` | `string` | `'public'` | 命名空间 ID |
|
|
432
|
+
| `transport` | `'grpc' \| 'http'` | `'grpc'` | 传输协议 |
|
|
433
|
+
| `username` | `string` | - | 用户名 |
|
|
434
|
+
| `password` | `string` | - | 密码 |
|
|
435
|
+
| `ssl` | `boolean` | `false` | 是否启用 TLS/SSL |
|
|
436
|
+
| `ak` | `string` | - | 阿里云 RAM AccessKey |
|
|
437
|
+
| `sk` | `string` | - | 阿里云 RAM SecretKey |
|
|
438
|
+
| `appName` | `string` | - | 应用名 |
|
|
439
|
+
|
|
440
|
+
### NacosConfigOptions
|
|
441
|
+
|
|
442
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
443
|
+
|------|------|--------|------|
|
|
444
|
+
| `serverAddr` | `string \| string[]` | - | Nacos 服务端地址 |
|
|
445
|
+
| `namespace` | `string` | `'public'` | 命名空间 ID |
|
|
446
|
+
| `transport` | `'grpc' \| 'http'` | `'grpc'` | 传输协议 |
|
|
447
|
+
| `username` | `string` | - | 用户名 |
|
|
448
|
+
| `password` | `string` | - | 密码 |
|
|
449
|
+
| `ssl` | `boolean` | `false` | 是否启用 TLS/SSL |
|
|
450
|
+
| `accessKey` | `string` | - | 阿里云 RAM AccessKey |
|
|
451
|
+
| `secretKey` | `string` | - | 阿里云 RAM SecretKey |
|
|
452
|
+
| `signatureRegionId` | `string` | - | v4 签名区域 ID |
|
|
453
|
+
|
|
454
|
+
### NacosInstanceOptions
|
|
455
|
+
|
|
456
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
457
|
+
|------|------|--------|------|
|
|
458
|
+
| `serviceName` | `string` | - | 服务名 |
|
|
459
|
+
| `ip` | `string` | - | 实例 IP |
|
|
460
|
+
| `port` | `number` | - | 实例端口 |
|
|
461
|
+
| `weight` | `number` | `1.0` | 权重 |
|
|
462
|
+
| `ephemeral` | `boolean` | `true` | 是否临时实例 |
|
|
463
|
+
| `clusterName` | `string` | - | 集群名 |
|
|
464
|
+
| `groupName` | `string` | `'DEFAULT_GROUP'` | 分组名 |
|
|
465
|
+
| `metadata` | `Record<string, string>` | - | 元数据 |
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 13. 常见问题
|
|
470
|
+
|
|
471
|
+
### 只启用配置中心,不启用服务发现可以吗?
|
|
472
|
+
|
|
473
|
+
可以。`naming` 和 `config` 都是可选的,只传 `config` 即可:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
NacosModule.forRoot({
|
|
477
|
+
config: { serverAddr: '127.0.0.1:8848' },
|
|
478
|
+
// 不传 naming,NacosNamingService 注入后客户端为 null
|
|
479
|
+
})
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
此时 `NacosNamingService` 仍可注入,但调用其方法会抛出 `NacosNamingClient 未初始化` 错误。
|
|
483
|
+
|
|
484
|
+
### 如何选择 gRPC 还是 HTTP 传输?
|
|
485
|
+
|
|
486
|
+
| 传输协议 | Nacos 2.x | Nacos 3.x | 推荐场景 |
|
|
487
|
+
|----------|-----------|-----------|----------|
|
|
488
|
+
| `grpc`(默认) | 支持 | 支持 | 推荐,实时推送,无需 UDP |
|
|
489
|
+
| `http` | 支持 | 不支持 | 仅兼容旧版 Nacos 2.x 时使用 |
|
|
490
|
+
|
|
491
|
+
### Nacos 3.x 连接失败怎么办?
|
|
492
|
+
|
|
493
|
+
Nacos 3.x 已移除 HTTP API 支持,必须使用 gRPC 传输(默认)。确保:
|
|
494
|
+
|
|
495
|
+
- 未设置 `transport: 'http'`
|
|
496
|
+
- Nacos Server 的 gRPC 端口(默认 9848,即 serverPort + 1000)已开放
|
|
497
|
+
- 检查用户名密码是否正确
|
|
498
|
+
|
|
499
|
+
### 配置更新后业务代码没有生效?
|
|
500
|
+
|
|
501
|
+
确保通过 `subscribe()` 订阅了配置变更,并在回调中更新本地变量。`getConfig()` 返回的是缓存值,订阅后缓存会自动更新,但业务代码中引用的变量需要手动更新。
|
|
502
|
+
|
|
503
|
+
### 如何获取原始 SDK 客户端?
|
|
504
|
+
|
|
505
|
+
使用 `getRawClient()` 方法或 `@InjectNacosNamingClient()` / `@InjectNacosConfigClient()` 装饰器获取原始 `NacosNamingClient` / `NacosConfigClient` 实例,调用 SDK 未封装的高级 API。
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
*nest-nacos v1.0.0 · MIT License · 基于 nacos-sdk-nodejs v2.6.x*
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NestJS Nacos 插件 - 统一导出
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export * from './nacos.constants';
|
|
7
|
+
export * from './nacos.interfaces';
|
|
8
|
+
export * from './nacos.module';
|
|
9
|
+
export * from './nacos.providers';
|
|
10
|
+
export * from './nacos-naming.service';
|
|
11
|
+
export * from './nacos-config.service';
|
|
12
|
+
export * from './nacos.decorators';
|
|
13
|
+
export * from './nacos.health';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* NestJS Nacos 插件 - 统一导出
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
__exportStar(require("./nacos.constants"), exports);
|
|
23
|
+
__exportStar(require("./nacos.interfaces"), exports);
|
|
24
|
+
__exportStar(require("./nacos.module"), exports);
|
|
25
|
+
__exportStar(require("./nacos.providers"), exports);
|
|
26
|
+
__exportStar(require("./nacos-naming.service"), exports);
|
|
27
|
+
__exportStar(require("./nacos-config.service"), exports);
|
|
28
|
+
__exportStar(require("./nacos.decorators"), exports);
|
|
29
|
+
__exportStar(require("./nacos.health"), exports);
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;GAIG;AACH,oDAAkC;AAClC,qDAAmC;AACnC,iDAA+B;AAC/B,oDAAkC;AAClC,yDAAuC;AACvC,yDAAuC;AACvC,qDAAmC;AACnC,iDAA+B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NestJS Nacos 插件 - Config 服务(配置中心)
|
|
3
|
+
*
|
|
4
|
+
* 封装 NacosConfigClient,负责:
|
|
5
|
+
* - 配置读取与发布
|
|
6
|
+
* - 配置变更订阅(服务端推送)
|
|
7
|
+
* - 本地配置缓存(支持热更新)
|
|
8
|
+
*/
|
|
9
|
+
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
10
|
+
import { NacosConfigClient } from 'nacos';
|
|
11
|
+
import { NacosModuleOptions } from './nacos.interfaces';
|
|
12
|
+
export declare class NacosConfigService implements OnModuleInit, OnModuleDestroy {
|
|
13
|
+
private readonly client;
|
|
14
|
+
private readonly options;
|
|
15
|
+
private readonly logger;
|
|
16
|
+
/** 配置缓存:key = `${dataId}@@${group}` */
|
|
17
|
+
private readonly cache;
|
|
18
|
+
/** 订阅回调集合:key = `${dataId}@@${group}` */
|
|
19
|
+
private readonly listeners;
|
|
20
|
+
constructor(client: NacosConfigClient | null, options: NacosModuleOptions | null);
|
|
21
|
+
/** 模块初始化:等待客户端就绪 + 预加载订阅配置 */
|
|
22
|
+
onModuleInit(): Promise<void>;
|
|
23
|
+
onModuleDestroy(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 获取配置内容
|
|
26
|
+
* @param dataId 配置 ID
|
|
27
|
+
* @param group 分组名,默认 'DEFAULT_GROUP'
|
|
28
|
+
* @returns 配置内容字符串
|
|
29
|
+
*/
|
|
30
|
+
getConfig(dataId: string, group?: string): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* 获取配置并解析为 JSON 对象
|
|
33
|
+
*/
|
|
34
|
+
getConfigAsJson<T = any>(dataId: string, group?: string): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* 发布配置
|
|
37
|
+
* @param dataId 配置 ID
|
|
38
|
+
* @param group 分组名
|
|
39
|
+
* @param content 配置内容
|
|
40
|
+
*/
|
|
41
|
+
publish(dataId: string, group: string, content: string): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* 删除配置
|
|
44
|
+
*/
|
|
45
|
+
remove(dataId: string, group: string): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* 订阅配置变更(服务端推送)
|
|
48
|
+
* @param dataId 配置 ID
|
|
49
|
+
* @param group 分组名
|
|
50
|
+
* @param listener 回调函数,参数为新配置内容
|
|
51
|
+
*/
|
|
52
|
+
subscribe(dataId: string, group: string, listener: (content: string) => void): void;
|
|
53
|
+
/**
|
|
54
|
+
* 取消订阅
|
|
55
|
+
*/
|
|
56
|
+
unSubscribe(dataId: string, group: string, listener?: (content: string) => void): void;
|
|
57
|
+
/** 获取原始客户端 */
|
|
58
|
+
getRawClient(): NacosConfigClient | null;
|
|
59
|
+
/** 内部方法:加载配置并建立订阅 */
|
|
60
|
+
private loadAndSubscribe;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=nacos-config.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nacos-config.service.d.ts","sourceRoot":"","sources":["../src/nacos-config.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA8B,eAAe,EAAE,YAAY,EAAY,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,qBACa,kBAAmB,YAAW,YAAY,EAAE,eAAe;IAQ3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;gBAGnB,MAAM,EAAE,iBAAiB,GAAG,IAAI,EACtC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAGxF,8BAA8B;IACxB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAe7B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtC;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAWzE;;OAEG;IACG,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAUnF;;;;;OAKG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS/E;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7D;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAiBnF;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAYtF,cAAc;IACd,YAAY,IAAI,iBAAiB,GAAG,IAAI;IAIxC,qBAAqB;YACP,gBAAgB;CAY/B"}
|