or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-config.mdindex.mdv1-config.mdv1-naming.mdv2-config.mdv2-naming.md

v2-naming.mddocs/

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