0
# V2 Service Discovery (Asynchronous)
1
2
Modern asynchronous API for Nacos service discovery and registration operations with advanced features including GRPC support, batch operations, comprehensive data models, health monitoring, and subscription management.
3
4
## Capabilities
5
6
### Service Creation and Initialization
7
8
Create and initialize the asynchronous naming service.
9
10
```python { .api }
11
class NacosNamingService:
12
@staticmethod
13
async def create_naming_service(client_config: ClientConfig) -> 'NacosNamingService':
14
"""
15
Create and initialize a Nacos naming service.
16
17
Args:
18
client_config (ClientConfig): Client configuration containing server details,
19
authentication, and operational parameters
20
21
Returns:
22
NacosNamingService: Initialized naming service instance
23
24
Raises:
25
NacosException: If client_config is invalid or initialization fails
26
"""
27
```
28
29
Usage example:
30
31
```python
32
import asyncio
33
from v2.nacos import ClientConfig, NacosNamingService
34
35
async def main():
36
# Create client configuration
37
client_config = ClientConfig(
38
server_addresses="127.0.0.1:8848",
39
namespace_id="production",
40
username="nacos",
41
password="nacos"
42
)
43
44
# Create naming service
45
naming_service = await NacosNamingService.create_naming_service(client_config)
46
47
# Use the service...
48
49
# Always shutdown when done
50
await naming_service.shutdown()
51
52
asyncio.run(main())
53
```
54
55
### Service Instance Registration
56
57
Register service instances with comprehensive metadata and configuration options.
58
59
```python { .api }
60
async def register_instance(self, request: RegisterInstanceParam) -> bool:
61
"""
62
Register a service instance.
63
64
Args:
65
request (RegisterInstanceParam): Instance registration parameters
66
67
Returns:
68
bool: True if registration successful
69
70
Raises:
71
NacosException: If service_name is empty or invalid
72
"""
73
```
74
75
Usage example:
76
77
```python
78
from v2.nacos import RegisterInstanceParam
79
80
# Basic instance registration
81
register_param = RegisterInstanceParam(
82
service_name="user-service",
83
ip="192.168.1.100",
84
port=8080
85
)
86
success = await naming_service.register_instance(register_param)
87
print(f"Registration successful: {success}")
88
89
# Advanced registration with metadata
90
register_param = RegisterInstanceParam(
91
service_name="user-service",
92
ip="192.168.1.100",
93
port=8080,
94
weight=1.5,
95
cluster_name="production",
96
group_name="microservices",
97
ephemeral=True,
98
enabled=True,
99
healthy=True,
100
metadata={
101
"version": "1.2.0",
102
"region": "us-west-1",
103
"zone": "us-west-1a",
104
"protocol": "http",
105
"management.port": "8081"
106
}
107
)
108
await naming_service.register_instance(register_param)
109
110
# Register with custom health check intervals
111
register_param = RegisterInstanceParam(
112
service_name="critical-service",
113
ip="192.168.1.200",
114
port=9090,
115
metadata={
116
"preserved.heart.beat.timeout": "10000", # 10 seconds
117
"preserved.heart.beat.interval": "3000", # 3 seconds
118
"preserved.ip.delete.timeout": "30000" # 30 seconds
119
}
120
)
121
await naming_service.register_instance(register_param)
122
```
123
124
### Batch Service Instance Registration
125
126
Register multiple service instances in a single operation.
127
128
```python { .api }
129
async def batch_register_instances(self, request: BatchRegisterInstanceParam) -> bool:
130
"""
131
Register multiple service instances in batch.
132
133
Args:
134
request (BatchRegisterInstanceParam): Batch registration parameters
135
136
Returns:
137
bool: True if batch registration successful
138
139
Raises:
140
NacosException: If service_name is empty or instances list is empty
141
"""
142
143
async def batch_deregister_instances(self, request: BatchRegisterInstanceParam) -> bool:
144
"""
145
Deregister multiple service instances in batch.
146
147
Args:
148
request (BatchRegisterInstanceParam): Batch deregistration parameters
149
150
Returns:
151
bool: True if batch deregistration successful
152
"""
153
```
154
155
Usage example:
156
157
```python
158
from v2.nacos import BatchRegisterInstanceParam, RegisterInstanceParam
159
160
# Create multiple instances
161
instances = [
162
RegisterInstanceParam(
163
service_name="user-service",
164
ip="192.168.1.100",
165
port=8080,
166
cluster_name="production",
167
metadata={"node": "node1"}
168
),
169
RegisterInstanceParam(
170
service_name="user-service",
171
ip="192.168.1.101",
172
port=8080,
173
cluster_name="production",
174
metadata={"node": "node2"}
175
),
176
RegisterInstanceParam(
177
service_name="user-service",
178
ip="192.168.1.102",
179
port=8080,
180
cluster_name="production",
181
metadata={"node": "node3"}
182
)
183
]
184
185
# Batch register instances
186
batch_param = BatchRegisterInstanceParam(
187
service_name="user-service",
188
group_name="microservices",
189
instances=instances
190
)
191
success = await naming_service.batch_register_instances(batch_param)
192
print(f"Batch registration successful: {success}")
193
194
# Batch deregister instances
195
success = await naming_service.batch_deregister_instances(batch_param)
196
print(f"Batch deregistration successful: {success}")
197
```
198
199
### Service Instance Deregistration
200
201
Remove service instances from Nacos registry.
202
203
```python { .api }
204
async def deregister_instance(self, request: DeregisterInstanceParam) -> bool:
205
"""
206
Deregister a service instance.
207
208
Args:
209
request (DeregisterInstanceParam): Instance deregistration parameters
210
211
Returns:
212
bool: True if deregistration successful
213
214
Raises:
215
NacosException: If service_name is empty or invalid
216
"""
217
```
218
219
Usage example:
220
221
```python
222
from v2.nacos import DeregisterInstanceParam
223
224
# Basic instance deregistration
225
deregister_param = DeregisterInstanceParam(
226
service_name="user-service",
227
ip="192.168.1.100",
228
port=8080
229
)
230
success = await naming_service.deregister_instance(deregister_param)
231
print(f"Deregistration successful: {success}")
232
233
# Deregister from specific cluster and group
234
deregister_param = DeregisterInstanceParam(
235
service_name="user-service",
236
ip="192.168.1.100",
237
port=8080,
238
cluster_name="production",
239
group_name="microservices",
240
ephemeral=True
241
)
242
await naming_service.deregister_instance(deregister_param)
243
```
244
245
### Service Instance Updates
246
247
Update existing service instance properties.
248
249
```python { .api }
250
async def update_instance(self, request: RegisterInstanceParam) -> bool:
251
"""
252
Update a service instance. Uses the same parameters as registration.
253
254
Args:
255
request (RegisterInstanceParam): Instance update parameters
256
257
Returns:
258
bool: True if update successful
259
260
Raises:
261
NacosException: If service_name is empty or invalid
262
"""
263
```
264
265
Usage example:
266
267
```python
268
# Update instance weight and metadata
269
update_param = RegisterInstanceParam(
270
service_name="user-service",
271
ip="192.168.1.100",
272
port=8080,
273
weight=2.0, # Increased weight
274
metadata={
275
"version": "1.3.0", # Updated version
276
"status": "optimized",
277
"cpu_usage": "low"
278
}
279
)
280
success = await naming_service.update_instance(update_param)
281
print(f"Update successful: {success}")
282
283
# Toggle instance availability
284
update_param = RegisterInstanceParam(
285
service_name="user-service",
286
ip="192.168.1.100",
287
port=8080,
288
enabled=False, # Disable instance
289
healthy=False # Mark as unhealthy
290
)
291
await naming_service.update_instance(update_param)
292
```
293
294
### Service Instance Listing
295
296
Retrieve lists of service instances with filtering options.
297
298
```python { .api }
299
async def list_instances(self, request: ListInstanceParam) -> List[Instance]:
300
"""
301
List service instances.
302
303
Args:
304
request (ListInstanceParam): Instance listing parameters
305
306
Returns:
307
List[Instance]: List of service instances
308
309
Raises:
310
NacosException: If service_name is empty or invalid
311
"""
312
```
313
314
Usage example:
315
316
```python
317
from v2.nacos import ListInstanceParam
318
319
# List all instances
320
list_param = ListInstanceParam(service_name="user-service")
321
instances = await naming_service.list_instances(list_param)
322
for instance in instances:
323
print(f"Instance: {instance.ip}:{instance.port} - healthy: {instance.healthy}")
324
325
# List healthy instances only
326
list_param = ListInstanceParam(
327
service_name="user-service",
328
healthy_only=True
329
)
330
healthy_instances = await naming_service.list_instances(list_param)
331
332
# List instances from specific clusters
333
list_param = ListInstanceParam(
334
service_name="user-service",
335
clusters=["production", "staging"],
336
group_name="microservices"
337
)
338
instances = await naming_service.list_instances(list_param)
339
340
# List with subscription (enables real-time updates)
341
list_param = ListInstanceParam(
342
service_name="user-service",
343
subscribe=True, # Enable real-time updates
344
healthy_only=True
345
)
346
instances = await naming_service.list_instances(list_param)
347
```
348
349
### Service Information Retrieval
350
351
Get detailed service metadata and configuration.
352
353
```python { .api }
354
async def get_service(self, request: GetServiceParam) -> Service:
355
"""
356
Get service information.
357
358
Args:
359
request (GetServiceParam): Service query parameters
360
361
Returns:
362
Service: Service information including metadata and instances
363
364
Raises:
365
NacosException: If service_name is empty or invalid
366
"""
367
368
async def list_services(self, request: ListServiceParam) -> ServiceList:
369
"""
370
List services with pagination.
371
372
Args:
373
request (ListServiceParam): Service listing parameters
374
375
Returns:
376
ServiceList: Paginated list of services
377
"""
378
```
379
380
Usage example:
381
382
```python
383
from v2.nacos import GetServiceParam, ListServiceParam
384
385
# Get detailed service information
386
service_param = GetServiceParam(
387
service_name="user-service",
388
group_name="microservices"
389
)
390
service = await naming_service.get_service(service_param)
391
print(f"Service: {service.name}")
392
print(f"Clusters: {service.clusters}")
393
print(f"Instance count: {len(service.hosts)}")
394
395
# Get service from specific clusters
396
service_param = GetServiceParam(
397
service_name="user-service",
398
clusters=["production"]
399
)
400
service = await naming_service.get_service(service_param)
401
402
# List all services with pagination
403
list_param = ListServiceParam(
404
namespace_id="production",
405
group_name="microservices",
406
page_no=1,
407
page_size=20
408
)
409
service_list = await naming_service.list_services(list_param)
410
print(f"Total services: {service_list.count}")
411
for service_name in service_list.doms:
412
print(f"Service: {service_name}")
413
414
# List services from different namespace
415
list_param = ListServiceParam(
416
namespace_id="staging",
417
page_no=1,
418
page_size=50
419
)
420
staging_services = await naming_service.list_services(list_param)
421
```
422
423
### Service Subscription Management
424
425
Subscribe to service change notifications for real-time updates.
426
427
```python { .api }
428
async def subscribe(self, request: SubscribeServiceParam) -> None:
429
"""
430
Subscribe to service changes.
431
432
Args:
433
request (SubscribeServiceParam): Service subscription parameters
434
"""
435
436
async def unsubscribe(self, request: SubscribeServiceParam) -> None:
437
"""
438
Unsubscribe from service changes.
439
440
Args:
441
request (SubscribeServiceParam): Service subscription parameters to remove
442
"""
443
```
444
445
Usage example:
446
447
```python
448
from v2.nacos import SubscribeServiceParam
449
450
# Define async callback for service changes
451
async def service_change_callback(service_info):
452
print(f"Service changed: {service_info.name}")
453
print(f"Instance count: {len(service_info.hosts)}")
454
455
# Process each instance
456
for instance in service_info.hosts:
457
status = "healthy" if instance.healthy else "unhealthy"
458
print(f" {instance.ip}:{instance.port} - {status}")
459
460
# Handle service changes asynchronously
461
await update_load_balancer(service_info)
462
463
async def update_load_balancer(service_info):
464
# Your async service update logic
465
print(f"Updating load balancer for {service_info.name}")
466
467
# Subscribe to service changes
468
subscribe_param = SubscribeServiceParam(
469
service_name="user-service",
470
group_name="microservices",
471
subscribe_callback=service_change_callback
472
)
473
await naming_service.subscribe(subscribe_param)
474
475
# Subscribe to specific clusters
476
subscribe_param = SubscribeServiceParam(
477
service_name="user-service",
478
clusters=["production", "staging"],
479
subscribe_callback=service_change_callback
480
)
481
await naming_service.subscribe(subscribe_param)
482
483
# Unsubscribe from service changes
484
unsubscribe_param = SubscribeServiceParam(
485
service_name="user-service",
486
group_name="microservices"
487
)
488
await naming_service.unsubscribe(unsubscribe_param)
489
```
490
491
### Health Monitoring
492
493
Check service and server health status.
494
495
```python { .api }
496
async def server_health(self) -> bool:
497
"""
498
Check if Nacos server is healthy.
499
500
Returns:
501
bool: True if server is healthy
502
"""
503
```
504
505
Usage example:
506
507
```python
508
# Check server health
509
is_healthy = await naming_service.server_health()
510
if is_healthy:
511
print("Nacos server is healthy")
512
else:
513
print("Nacos server is unhealthy")
514
515
# Health monitoring loop
516
async def health_monitor():
517
while True:
518
try:
519
healthy = await naming_service.server_health()
520
print(f"Server health: {'OK' if healthy else 'FAIL'}")
521
522
if not healthy:
523
# Handle unhealthy server
524
await handle_server_unhealthy()
525
526
await asyncio.sleep(30) # Check every 30 seconds
527
except Exception as e:
528
print(f"Health check failed: {e}")
529
await asyncio.sleep(10)
530
531
async def handle_server_unhealthy():
532
print("Handling unhealthy server...")
533
# Implement fallback logic
534
535
# Start health monitoring
536
asyncio.create_task(health_monitor())
537
```
538
539
### Service Shutdown
540
541
Properly shutdown the naming service and cleanup resources.
542
543
```python { .api }
544
async def shutdown(self) -> None:
545
"""
546
Shutdown the naming service and cleanup resources.
547
This should always be called when the service is no longer needed.
548
"""
549
```
550
551
Usage example:
552
553
```python
554
async def main():
555
naming_service = None
556
try:
557
# Create service
558
client_config = ClientConfig(server_addresses="127.0.0.1:8848")
559
naming_service = await NacosNamingService.create_naming_service(client_config)
560
561
# Register instance
562
register_param = RegisterInstanceParam(
563
service_name="test-service",
564
ip="127.0.0.1",
565
port=8080
566
)
567
await naming_service.register_instance(register_param)
568
569
except Exception as e:
570
print(f"Error: {e}")
571
finally:
572
# Always shutdown
573
if naming_service:
574
await naming_service.shutdown()
575
```
576
577
## Data Models
578
579
### Instance Model
580
581
```python { .api }
582
class Instance(BaseModel):
583
instanceId: str = ''
584
ip: str
585
port: int
586
weight: float = 1.0
587
healthy: bool = True
588
enabled: bool = True
589
ephemeral: bool = True
590
clusterName: str = ''
591
serviceName: str = ''
592
metadata: dict = {}
593
594
def to_inet_addr(self) -> str: ...
595
def is_ephemeral(self) -> bool: ...
596
def get_weight(self) -> float: ...
597
def add_metadata(self, key: str, value: str) -> None: ...
598
def contains_metadata(self, key: str) -> bool: ...
599
def check_instance_is_legal(self): ...
600
```
601
602
### Parameter Models
603
604
```python { .api }
605
class RegisterInstanceParam(BaseModel):
606
ip: str
607
port: int
608
weight: float = 1.0
609
enabled: bool = True
610
healthy: bool = True
611
metadata: Dict[str, str] = {}
612
clusterName: str = ''
613
serviceName: str
614
groupName: str = 'DEFAULT_GROUP'
615
ephemeral: bool = True
616
617
class DeregisterInstanceParam(BaseModel):
618
ip: str
619
port: int
620
clusterName: str = ''
621
serviceName: str
622
groupName: str = 'DEFAULT_GROUP'
623
ephemeral: bool = True
624
625
class ListInstanceParam(BaseModel):
626
serviceName: str
627
groupName: str = 'DEFAULT_GROUP'
628
clusters: List[str] = []
629
subscribe: bool = True
630
healthyOnly: Optional[bool] = None
631
632
class SubscribeServiceParam(BaseModel):
633
serviceName: str
634
groupName: str = 'DEFAULT_GROUP'
635
clusters: List[str] = []
636
subscribeCallback: Optional[Callable] = None
637
638
class GetServiceParam(BaseModel):
639
serviceName: str
640
groupName: str = 'DEFAULT_GROUP'
641
clusters: List[str] = []
642
643
class ListServiceParam(BaseModel):
644
namespaceId: str = 'public'
645
groupName: str = 'DEFAULT_GROUP'
646
pageNo: int = 1
647
pageSize: int = 10
648
```
649
650
### Service Models
651
652
```python { .api }
653
class Service(BaseModel):
654
name: str
655
groupName: str
656
clusters: str
657
cacheMillis: int
658
hosts: List[Instance]
659
lastRefTime: int
660
checksum: str
661
allIPs: bool
662
reachProtectionThreshold: bool
663
664
class ServiceList(BaseModel):
665
count: int
666
services: List[str]
667
```
668
669
## Advanced Features
670
671
### Automatic Service Updates
672
673
The V2 API includes automatic service information updates:
674
675
```python
676
# Enable automatic service updates in ClientConfig
677
client_config = ClientConfig(
678
server_addresses="127.0.0.1:8848",
679
async_update_service=True,
680
update_thread_num=10 # Number of update threads
681
)
682
```
683
684
### Instance Health Management
685
686
Instances support automatic health check intervals through metadata:
687
688
```python
689
# Configure health check intervals
690
health_metadata = {
691
"preserved.heart.beat.interval": "5000", # 5 seconds
692
"preserved.heart.beat.timeout": "15000", # 15 seconds
693
"preserved.ip.delete.timeout": "30000" # 30 seconds
694
}
695
696
register_param = RegisterInstanceParam(
697
service_name="health-monitored-service",
698
ip="192.168.1.100",
699
port=8080,
700
metadata=health_metadata
701
)
702
```
703
704
### Service Instance Caching
705
706
The V2 API provides intelligent caching for improved performance:
707
708
- **Service Info Cache**: Automatic caching of service instance lists
709
- **Cache Updates**: Real-time cache updates through subscriptions
710
- **Cache Persistence**: Optional persistent caching for offline scenarios
711
- **Cache Invalidation**: Automatic cache invalidation on service changes