or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ai-mcp.mdconfiguration.mdcore-api.mdexceptions.mdindex.mdnaming.mdremote.md

naming.mddocs/

0

# Service Discovery and Naming

1

2

Service registration, discovery, and health monitoring with event-driven updates. Essential for microservices architectures, load balancing, and dynamic service topology management.

3

4

## Capabilities

5

6

### NamingService

7

8

Main interface for service discovery and registration operations. Provides comprehensive functionality for managing service instances, health monitoring, and event-driven service updates.

9

10

```java { .api }

11

/**

12

* Main interface for service discovery and registration

13

*/

14

interface NamingService {

15

/**

16

* Register service instance with simple parameters

17

* @param serviceName Service name

18

* @param ip Instance IP address

19

* @param port Instance port

20

* @throws NacosException If registration fails

21

*/

22

void registerInstance(String serviceName, String ip, int port) throws NacosException;

23

24

/**

25

* Register service instance with group

26

* @param serviceName Service name

27

* @param groupName Service group name

28

* @param ip Instance IP address

29

* @param port Instance port

30

* @throws NacosException If registration fails

31

*/

32

void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException;

33

34

/**

35

* Register service instance with detailed configuration

36

* @param serviceName Service name

37

* @param instance Instance details including metadata

38

* @throws NacosException If registration fails

39

*/

40

void registerInstance(String serviceName, Instance instance) throws NacosException;

41

42

/**

43

* Register service instance with group and detailed configuration

44

* @param serviceName Service name

45

* @param groupName Service group name

46

* @param instance Instance details including metadata

47

* @throws NacosException If registration fails

48

*/

49

void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException;

50

51

/**

52

* Batch register multiple instances

53

* @param serviceName Service name

54

* @param groupName Service group name

55

* @param instances List of instances to register

56

* @throws NacosException If batch registration fails

57

*/

58

void batchRegisterInstance(String serviceName, String groupName, List<Instance> instances) throws NacosException;

59

60

/**

61

* Deregister service instance

62

* @param serviceName Service name

63

* @param ip Instance IP address

64

* @param port Instance port

65

* @throws NacosException If deregistration fails

66

*/

67

void deregisterInstance(String serviceName, String ip, int port) throws NacosException;

68

69

/**

70

* Deregister service instance with group

71

* @param serviceName Service name

72

* @param groupName Service group name

73

* @param ip Instance IP address

74

* @param port Instance port

75

* @throws NacosException If deregistration fails

76

*/

77

void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException;

78

79

/**

80

* Deregister service instance with detailed configuration

81

* @param serviceName Service name

82

* @param instance Instance to deregister

83

* @throws NacosException If deregistration fails

84

*/

85

void deregisterInstance(String serviceName, Instance instance) throws NacosException;

86

87

/**

88

* Deregister service instance with group and detailed configuration

89

* @param serviceName Service name

90

* @param groupName Service group name

91

* @param instance Instance to deregister

92

* @throws NacosException If deregistration fails

93

*/

94

void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException;

95

96

/**

97

* Batch deregister multiple instances

98

* @param serviceName Service name

99

* @param groupName Service group name

100

* @param instances List of instances to deregister

101

* @throws NacosException If batch deregistration fails

102

*/

103

void batchDeregisterInstance(String serviceName, String groupName, List<Instance> instances) throws NacosException;

104

105

/**

106

* Get all instances for a service

107

* @param serviceName Service name

108

* @return List of all service instances

109

* @throws NacosException If query fails

110

*/

111

List<Instance> getAllInstances(String serviceName) throws NacosException;

112

113

/**

114

* Get all instances for a service with group

115

* @param serviceName Service name

116

* @param groupName Service group name

117

* @return List of all service instances

118

* @throws NacosException If query fails

119

*/

120

List<Instance> getAllInstances(String serviceName, String groupName) throws NacosException;

121

122

/**

123

* Get all instances with cluster filtering

124

* @param serviceName Service name

125

* @param groupName Service group name

126

* @param clusters List of cluster names to filter

127

* @return List of filtered service instances

128

* @throws NacosException If query fails

129

*/

130

List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException;

131

132

/**

133

* Get instances filtered by health status

134

* @param serviceName Service name

135

* @param healthy Whether to return only healthy instances

136

* @return List of filtered instances

137

* @throws NacosException If query fails

138

*/

139

List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;

140

141

/**

142

* Get instances filtered by health status with group

143

* @param serviceName Service name

144

* @param groupName Service group name

145

* @param healthy Whether to return only healthy instances

146

* @return List of filtered instances

147

* @throws NacosException If query fails

148

*/

149

List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException;

150

151

/**

152

* Get instances with cluster and health filtering

153

* @param serviceName Service name

154

* @param groupName Service group name

155

* @param clusters List of cluster names

156

* @param healthy Whether to return only healthy instances

157

* @return List of filtered instances

158

* @throws NacosException If query fails

159

*/

160

List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException;

161

162

/**

163

* Select one healthy instance using load balancing

164

* @param serviceName Service name

165

* @return Single healthy instance or null if none available

166

* @throws NacosException If selection fails

167

*/

168

Instance selectOneHealthyInstance(String serviceName) throws NacosException;

169

170

/**

171

* Select one healthy instance with group

172

* @param serviceName Service name

173

* @param groupName Service group name

174

* @return Single healthy instance or null if none available

175

* @throws NacosException If selection fails

176

*/

177

Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException;

178

179

/**

180

* Select one healthy instance with cluster filtering

181

* @param serviceName Service name

182

* @param groupName Service group name

183

* @param clusters List of cluster names

184

* @return Single healthy instance or null if none available

185

* @throws NacosException If selection fails

186

*/

187

Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException;

188

189

/**

190

* Subscribe to service change events

191

* @param serviceName Service name

192

* @param listener Event listener for service changes

193

* @throws NacosException If subscription fails

194

*/

195

void subscribe(String serviceName, EventListener listener) throws NacosException;

196

197

/**

198

* Subscribe to service change events with group

199

* @param serviceName Service name

200

* @param groupName Service group name

201

* @param listener Event listener for service changes

202

* @throws NacosException If subscription fails

203

*/

204

void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException;

205

206

/**

207

* Subscribe with cluster filtering

208

* @param serviceName Service name

209

* @param groupName Service group name

210

* @param clusters List of cluster names

211

* @param listener Event listener for service changes

212

* @throws NacosException If subscription fails

213

*/

214

void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException;

215

216

/**

217

* Unsubscribe from service change events

218

* @param serviceName Service name

219

* @param listener Event listener to remove

220

* @throws NacosException If unsubscription fails

221

*/

222

void unsubscribe(String serviceName, EventListener listener) throws NacosException;

223

224

/**

225

* Unsubscribe with group

226

* @param serviceName Service name

227

* @param groupName Service group name

228

* @param listener Event listener to remove

229

* @throws NacosException If unsubscription fails

230

*/

231

void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException;

232

233

/**

234

* Fuzzy watch services with group pattern (3.0+)

235

* @param groupNamePattern Group name pattern (supports wildcards)

236

* @param listener Event listener for pattern matches

237

* @throws NacosException If watch setup fails

238

*/

239

void fuzzyWatch(String groupNamePattern, FuzzyWatchEventWatcher listener) throws NacosException;

240

241

/**

242

* Fuzzy watch services with service and group patterns (3.0+)

243

* @param serviceNamePattern Service name pattern (supports wildcards)

244

* @param groupNamePattern Group name pattern (supports wildcards)

245

* @param listener Event listener for pattern matches

246

* @throws NacosException If watch setup fails

247

*/

248

void fuzzyWatch(String serviceNamePattern, String groupNamePattern, FuzzyWatchEventWatcher listener) throws NacosException;

249

250

/**

251

* Fuzzy watch with service key retrieval (3.0+)

252

* @param groupNamePattern Group name pattern

253

* @param listener Event listener

254

* @return Future containing matched service keys

255

* @throws NacosException If operation fails

256

*/

257

Future<ListView<String>> fuzzyWatchWithServiceKeys(String groupNamePattern, FuzzyWatchEventWatcher listener) throws NacosException;

258

259

/**

260

* Get services list with pagination

261

* @param pageNo Page number (1-based)

262

* @param pageSize Page size

263

* @return Paginated list of services

264

* @throws NacosException If query fails

265

*/

266

ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;

267

268

/**

269

* Get services with group and pagination

270

* @param pageNo Page number (1-based)

271

* @param pageSize Page size

272

* @param groupName Service group name

273

* @return Paginated list of services

274

* @throws NacosException If query fails

275

*/

276

ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException;

277

278

/**

279

* Get services with group and selector

280

* @param pageNo Page number (1-based)

281

* @param pageSize Page size

282

* @param groupName Service group name

283

* @param selector Service selector for filtering

284

* @return Paginated list of services

285

* @throws NacosException If query fails

286

*/

287

ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException;

288

289

/**

290

* Get subscribed services information

291

* @return List of subscribed services

292

* @throws NacosException If query fails

293

*/

294

List<ServiceInfo> getSubscribeServices() throws NacosException;

295

296

/**

297

* Get server status

298

* @return Server status string

299

*/

300

String getServerStatus();

301

302

/**

303

* Shutdown naming service

304

* @throws NacosException If shutdown fails

305

*/

306

void shutDown() throws NacosException;

307

}

308

```

309

310

### Instance Model

311

312

Service instance model containing all metadata and configuration for a registered service instance.

313

314

```java { .api }

315

/**

316

* Service instance model

317

*/

318

class Instance implements Serializable {

319

/** Unique instance identifier */

320

private String instanceId;

321

322

/** Instance IP address */

323

private String ip;

324

325

/** Instance port */

326

private int port;

327

328

/** Instance weight for load balancing (default: 1.0) */

329

private double weight = 1.0D;

330

331

/** Health status (default: true) */

332

private boolean healthy = true;

333

334

/** Whether instance is enabled (default: true) */

335

private boolean enabled = true;

336

337

/** Whether instance is ephemeral (default: true) */

338

private boolean ephemeral = true;

339

340

/** Cluster name */

341

private String clusterName;

342

343

/** Service name */

344

private String serviceName;

345

346

/** Custom metadata */

347

private Map<String, String> metadata;

348

349

/**

350

* Default constructor

351

*/

352

public Instance();

353

354

/**

355

* Get unique instance identifier

356

*/

357

public String getInstanceId();

358

359

/**

360

* Set instance identifier

361

*/

362

public void setInstanceId(String instanceId);

363

364

/**

365

* Get instance IP address

366

*/

367

public String getIp();

368

369

/**

370

* Set instance IP address

371

*/

372

public void setIp(String ip);

373

374

/**

375

* Get instance port

376

*/

377

public int getPort();

378

379

/**

380

* Set instance port

381

*/

382

public void setPort(int port);

383

384

/**

385

* Get instance weight for load balancing

386

*/

387

public double getWeight();

388

389

/**

390

* Set instance weight

391

*/

392

public void setWeight(double weight);

393

394

/**

395

* Check if instance is healthy

396

*/

397

public boolean isHealthy();

398

399

/**

400

* Set health status

401

*/

402

public void setHealthy(boolean healthy);

403

404

/**

405

* Check if instance is enabled

406

*/

407

public boolean isEnabled();

408

409

/**

410

* Set enabled status

411

*/

412

public void setEnabled(boolean enabled);

413

414

/**

415

* Check if instance is ephemeral

416

*/

417

public boolean isEphemeral();

418

419

/**

420

* Set ephemeral flag

421

*/

422

public void setEphemeral(boolean ephemeral);

423

424

/**

425

* Get cluster name

426

*/

427

public String getClusterName();

428

429

/**

430

* Set cluster name

431

*/

432

public void setClusterName(String clusterName);

433

434

/**

435

* Get service name

436

*/

437

public String getServiceName();

438

439

/**

440

* Set service name

441

*/

442

public void setServiceName(String serviceName);

443

444

/**

445

* Get metadata map

446

*/

447

public Map<String, String> getMetadata();

448

449

/**

450

* Set metadata map

451

*/

452

public void setMetadata(Map<String, String> metadata);

453

454

/**

455

* Add single metadata entry

456

* @param key Metadata key

457

* @param value Metadata value

458

*/

459

public void addMetadata(String key, String value);

460

461

/**

462

* Get instance address as "ip:port"

463

*/

464

public String toInetAddr();

465

466

/**

467

* Convert instance to JSON string

468

*/

469

@Override

470

public String toString();

471

}

472

```

473

474

### Event Listeners and Events

475

476

Event-driven system for monitoring service changes with different listener implementations.

477

478

```java { .api }

479

/**

480

* Base event listener interface for service changes

481

*/

482

interface EventListener {

483

/**

484

* Handle service change event

485

* @param event Service change event

486

*/

487

void onEvent(Event event);

488

}

489

490

/**

491

* Abstract event listener implementation

492

*/

493

abstract class AbstractEventListener implements EventListener {

494

/**

495

* Abstract method to be implemented by subclasses

496

*/

497

@Override

498

public abstract void onEvent(Event event);

499

}

500

501

/**

502

* Naming service event containing service change information

503

*/

504

class NamingEvent implements Event {

505

/** Service name that changed */

506

private String serviceName;

507

508

/** Group name */

509

private String groupName;

510

511

/** Cluster names */

512

private String clusters;

513

514

/** Current instances */

515

private List<Instance> instances;

516

517

/**

518

* Constructor for naming event

519

*/

520

public NamingEvent(String serviceName, List<Instance> instances);

521

522

/**

523

* Get service name

524

*/

525

public String getServiceName();

526

527

/**

528

* Set service name

529

*/

530

public void setServiceName(String serviceName);

531

532

/**

533

* Get group name

534

*/

535

public String getGroupName();

536

537

/**

538

* Set group name

539

*/

540

public void setGroupName(String groupName);

541

542

/**

543

* Get cluster names

544

*/

545

public String getClusters();

546

547

/**

548

* Set cluster names

549

*/

550

public void setClusters(String clusters);

551

552

/**

553

* Get current instances

554

*/

555

public List<Instance> getInstances();

556

557

/**

558

* Set instances

559

*/

560

public void setInstances(List<Instance> instances);

561

}

562

```

563

564

### Service Information and Lists

565

566

Models for service metadata and paginated lists of services.

567

568

```java { .api }

569

/**

570

* Service information including instances and metadata

571

*/

572

class ServiceInfo implements Serializable {

573

/** Service name */

574

private String name;

575

576

/** Group name */

577

private String groupName;

578

579

/** Cluster names */

580

private String clusters;

581

582

/** Cache milliseconds */

583

private long cacheMillis = 1000L;

584

585

/** Service instances */

586

private List<Instance> hosts;

587

588

/** Last refresh time */

589

private long lastRefTime = 0L;

590

591

/** Checksum */

592

private String checksum = "";

593

594

/** All instances including unhealthy ones */

595

private volatile boolean allIPs = false;

596

597

/**

598

* Default constructor

599

*/

600

public ServiceInfo();

601

602

/**

603

* Constructor with service name and clusters

604

*/

605

public ServiceInfo(String name, String clusters);

606

607

/**

608

* Get service name

609

*/

610

public String getName();

611

612

/**

613

* Set service name

614

*/

615

public void setName(String name);

616

617

/**

618

* Get group name

619

*/

620

public String getGroupName();

621

622

/**

623

* Set group name

624

*/

625

public void setGroupName(String groupName);

626

627

/**

628

* Get cluster names

629

*/

630

public String getClusters();

631

632

/**

633

* Set cluster names

634

*/

635

public void setClusters(String clusters);

636

637

/**

638

* Get service instances

639

*/

640

public List<Instance> getHosts();

641

642

/**

643

* Set service instances

644

*/

645

public void setHosts(List<Instance> hosts);

646

647

/**

648

* Get cache validity in milliseconds

649

*/

650

public long getCacheMillis();

651

652

/**

653

* Set cache validity

654

*/

655

public void setCacheMillis(long cacheMillis);

656

657

/**

658

* Get last refresh time

659

*/

660

public long getLastRefTime();

661

662

/**

663

* Set last refresh time

664

*/

665

public void setLastRefTime(long lastRefTime);

666

667

/**

668

* Get checksum

669

*/

670

public String getChecksum();

671

672

/**

673

* Set checksum

674

*/

675

public void setChecksum(String checksum);

676

677

/**

678

* Check if service data is expired

679

*/

680

public boolean expired();

681

682

/**

683

* Validate service data

684

*/

685

public boolean validate();

686

}

687

688

/**

689

* Paginated list view for services

690

*/

691

class ListView<T> implements Serializable {

692

/** Total count of items */

693

private int count;

694

695

/** List of items in current page */

696

private List<T> data;

697

698

/**

699

* Default constructor

700

*/

701

public ListView();

702

703

/**

704

* Get total count

705

*/

706

public int getCount();

707

708

/**

709

* Set total count

710

*/

711

public void setCount(int count);

712

713

/**

714

* Get data list

715

*/

716

public List<T> getData();

717

718

/**

719

* Set data list

720

*/

721

public void setData(List<T> data);

722

}

723

```

724

725

### Health Checking

726

727

Health checking system with support for different protocols and custom health checkers.

728

729

```java { .api }

730

/**

731

* Abstract base class for health checkers

732

*/

733

abstract class AbstractHealthChecker implements Serializable {

734

/** Health checker type */

735

private String type;

736

737

/**

738

* Get health checker type

739

*/

740

public String getType();

741

742

/**

743

* Set health checker type

744

*/

745

public void setType(String type);

746

747

/**

748

* Clone health checker

749

*/

750

public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;

751

}

752

753

/**

754

* Health check type definitions

755

*/

756

class HealthCheckType {

757

/** TCP health check */

758

public static final String TCP = "TCP";

759

760

/** HTTP health check */

761

public static final String HTTP = "HTTP";

762

763

/** MySQL health check */

764

public static final String MYSQL = "MYSQL";

765

766

/** No health check */

767

public static final String NONE = "NONE";

768

}

769

770

/**

771

* HTTP health checker implementation

772

*/

773

class Http extends AbstractHealthChecker {

774

/** HTTP path for health check */

775

private String path = "";

776

777

/** HTTP headers */

778

private String headers = "";

779

780

/** Expected response code */

781

private int expectedResponseCode = 200;

782

783

/**

784

* Default constructor

785

*/

786

public Http();

787

788

/**

789

* Get health check path

790

*/

791

public String getPath();

792

793

/**

794

* Set health check path

795

*/

796

public void setPath(String path);

797

798

/**

799

* Get HTTP headers

800

*/

801

public String getHeaders();

802

803

/**

804

* Set HTTP headers

805

*/

806

public void setHeaders(String headers);

807

808

/**

809

* Get expected response code

810

*/

811

public int getExpectedResponseCode();

812

813

/**

814

* Set expected response code

815

*/

816

public void setExpectedResponseCode(int expectedResponseCode);

817

}

818

819

/**

820

* TCP health checker implementation

821

*/

822

class Tcp extends AbstractHealthChecker {

823

/**

824

* Default constructor

825

*/

826

public Tcp();

827

}

828

829

/**

830

* MySQL health checker implementation

831

*/

832

class Mysql extends AbstractHealthChecker {

833

/** Database user */

834

private String user;

835

836

/** Database password */

837

private String pwd;

838

839

/** SQL command to execute */

840

private String cmd;

841

842

/**

843

* Default constructor

844

*/

845

public Mysql();

846

847

/**

848

* Get database user

849

*/

850

public String getUser();

851

852

/**

853

* Set database user

854

*/

855

public void setUser(String user);

856

857

/**

858

* Get database password

859

*/

860

public String getPwd();

861

862

/**

863

* Set database password

864

*/

865

public void setPwd(String pwd);

866

867

/**

868

* Get SQL command

869

*/

870

public String getCmd();

871

872

/**

873

* Set SQL command

874

*/

875

public void setCmd(String cmd);

876

}

877

```

878

879

## Usage Examples

880

881

### Basic Service Registration and Discovery

882

883

```java

884

import com.alibaba.nacos.api.NacosFactory;

885

import com.alibaba.nacos.api.PropertyKeyConst;

886

import com.alibaba.nacos.api.naming.NamingService;

887

import com.alibaba.nacos.api.naming.pojo.Instance;

888

import java.util.Properties;

889

import java.util.List;

890

891

// Create naming service

892

Properties properties = new Properties();

893

properties.setProperty(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848");

894

properties.setProperty(PropertyKeyConst.NAMESPACE, "production");

895

NamingService namingService = NacosFactory.createNamingService(properties);

896

897

// Simple service registration

898

namingService.registerInstance("user-service", "192.168.1.100", 8080);

899

900

// Advanced service registration with metadata

901

Instance instance = new Instance();

902

instance.setIp("192.168.1.100");

903

instance.setPort(8080);

904

instance.setWeight(2.0);

905

instance.setHealthy(true);

906

instance.setEnabled(true);

907

instance.setEphemeral(true);

908

instance.setClusterName("default");

909

910

// Add custom metadata

911

instance.addMetadata("version", "1.2.0");

912

instance.addMetadata("region", "us-east-1");

913

instance.addMetadata("zone", "zone-a");

914

instance.addMetadata("protocol", "http");

915

916

namingService.registerInstance("user-service", "microservices", instance);

917

918

// Service discovery

919

List<Instance> instances = namingService.getAllInstances("user-service", "microservices");

920

System.out.println("Found " + instances.size() + " instances");

921

922

for (Instance inst : instances) {

923

System.out.printf("Instance: %s:%d, Weight: %.1f, Healthy: %s%n",

924

inst.getIp(), inst.getPort(), inst.getWeight(), inst.isHealthy());

925

System.out.println("Metadata: " + inst.getMetadata());

926

}

927

928

// Get healthy instances only

929

List<Instance> healthyInstances = namingService.selectInstances("user-service", "microservices", true);

930

931

// Load balanced instance selection

932

Instance selectedInstance = namingService.selectOneHealthyInstance("user-service", "microservices");

933

if (selectedInstance != null) {

934

String serviceUrl = String.format("http://%s:%d",

935

selectedInstance.getIp(), selectedInstance.getPort());

936

System.out.println("Selected service URL: " + serviceUrl);

937

}

938

```

939

940

### Event-Driven Service Discovery

941

942

```java

943

import com.alibaba.nacos.api.naming.listener.EventListener;

944

import com.alibaba.nacos.api.naming.listener.NamingEvent;

945

946

// Service change event listener

947

EventListener serviceListener = new EventListener() {

948

@Override

949

public void onEvent(Event event) {

950

if (event instanceof NamingEvent) {

951

NamingEvent namingEvent = (NamingEvent) event;

952

953

System.out.printf("Service changed: %s in group %s%n",

954

namingEvent.getServiceName(), namingEvent.getGroupName());

955

956

List<Instance> instances = namingEvent.getInstances();

957

System.out.printf("Current instances count: %d%n", instances.size());

958

959

// Update local service registry

960

updateLocalServiceRegistry(namingEvent.getServiceName(), instances);

961

962

// Trigger load balancer update

963

updateLoadBalancer(instances);

964

}

965

}

966

};

967

968

// Subscribe to service changes

969

namingService.subscribe("user-service", "microservices", serviceListener);

970

namingService.subscribe("order-service", "microservices", serviceListener);

971

namingService.subscribe("payment-service", "microservices", serviceListener);

972

973

// Advanced event listener with filtering

974

EventListener clusterAwareListener = new AbstractEventListener() {

975

@Override

976

public void onEvent(Event event) {

977

NamingEvent namingEvent = (NamingEvent) event;

978

979

// Filter instances by cluster

980

List<Instance> clusterInstances = namingEvent.getInstances().stream()

981

.filter(instance -> "production".equals(instance.getClusterName()))

982

.filter(Instance::isHealthy)

983

.filter(Instance::isEnabled)

984

.collect(Collectors.toList());

985

986

if (!clusterInstances.isEmpty()) {

987

System.out.printf("Production cluster instances for %s: %d%n",

988

namingEvent.getServiceName(), clusterInstances.size());

989

990

// Update service mesh configuration

991

updateServiceMesh(namingEvent.getServiceName(), clusterInstances);

992

}

993

}

994

};

995

996

// Subscribe with cluster filtering

997

List<String> clusters = Arrays.asList("production", "staging");

998

namingService.subscribe("api-gateway", "microservices", clusters, clusterAwareListener);

999

```

1000

1001

### Batch Operations and Advanced Management

1002

1003

```java

1004

import java.util.Arrays;

1005

import java.util.concurrent.CompletableFuture;

1006

1007

// Batch registration for horizontal scaling

1008

public void registerServiceCluster(String serviceName, String groupName,

1009

List<String> ipAddresses, int port) throws NacosException {

1010

List<Instance> instances = ipAddresses.stream()

1011

.map(ip -> {

1012

Instance instance = new Instance();

1013

instance.setIp(ip);

1014

instance.setPort(port);

1015

instance.setWeight(1.0);

1016

instance.setHealthy(true);

1017

instance.setEnabled(true);

1018

instance.setClusterName("auto-scale-cluster");

1019

instance.addMetadata("deployment", "auto-scaling");

1020

instance.addMetadata("created", String.valueOf(System.currentTimeMillis()));

1021

return instance;

1022

})

1023

.collect(Collectors.toList());

1024

1025

namingService.batchRegisterInstance(serviceName, groupName, instances);

1026

System.out.printf("Batch registered %d instances for %s%n", instances.size(), serviceName);

1027

}

1028

1029

// Graceful service shutdown

1030

public void gracefulServiceShutdown(String serviceName, String groupName,

1031

String ip, int port) throws NacosException {

1032

// First, mark instance as not ready for new requests

1033

Instance instance = new Instance();

1034

instance.setIp(ip);

1035

instance.setPort(port);

1036

instance.setEnabled(false); // Stop accepting new traffic

1037

instance.addMetadata("status", "draining");

1038

1039

// Update instance to drain traffic

1040

namingService.registerInstance(serviceName, groupName, instance);

1041

1042

// Wait for existing requests to complete

1043

try {

1044

Thread.sleep(30000); // 30 second drain period

1045

} catch (InterruptedException e) {

1046

Thread.currentThread().interrupt();

1047

}

1048

1049

// Finally deregister

1050

namingService.deregisterInstance(serviceName, groupName, ip, port);

1051

System.out.printf("Gracefully shutdown instance %s:%d%n", ip, port);

1052

}

1053

1054

// Service health monitoring

1055

public void monitorServiceHealth(String serviceName, String groupName) {

1056

CompletableFuture.runAsync(() -> {

1057

while (true) {

1058

try {

1059

List<Instance> instances = namingService.getAllInstances(serviceName, groupName);

1060

1061

long healthyCount = instances.stream()

1062

.filter(Instance::isHealthy)

1063

.filter(Instance::isEnabled)

1064

.count();

1065

1066

double healthRatio = (double) healthyCount / instances.size();

1067

1068

System.out.printf("Service %s health: %d/%d instances (%.1f%%)%n",

1069

serviceName, healthyCount, instances.size(), healthRatio * 100);

1070

1071

if (healthRatio < 0.5) {

1072

System.err.printf("WARNING: %s has less than 50%% healthy instances!%n",

1073

serviceName);

1074

// Trigger alerting system

1075

triggerHealthAlert(serviceName, healthRatio);

1076

}

1077

1078

Thread.sleep(10000); // Check every 10 seconds

1079

1080

} catch (Exception e) {

1081

System.err.printf("Health monitoring error for %s: %s%n",

1082

serviceName, e.getMessage());

1083

}

1084

}

1085

});

1086

}

1087

```

1088

1089

### Fuzzy Watch and Pattern-Based Discovery (3.0+)

1090

1091

```java

1092

import com.alibaba.nacos.api.naming.listener.FuzzyWatchEventWatcher;

1093

import java.util.concurrent.Future;

1094

1095

// Fuzzy watch for microservices pattern

1096

FuzzyWatchEventWatcher microserviceWatcher = new FuzzyWatchEventWatcher() {

1097

@Override

1098

public void onEvent(FuzzyWatchEvent event) {

1099

System.out.printf("Microservice change: %s in group %s%n",

1100

event.getServiceName(), event.getGroupName());

1101

1102

// Parse service metadata

1103

if (event.getServiceName().endsWith("-api")) {

1104

handleApiServiceChange(event);

1105

} else if (event.getServiceName().endsWith("-worker")) {

1106

handleWorkerServiceChange(event);

1107

} else if (event.getServiceName().endsWith("-db")) {

1108

handleDatabaseServiceChange(event);

1109

}

1110

}

1111

1112

@Override

1113

public Executor getExecutor() {

1114

return Executors.newFixedThreadPool(4);

1115

}

1116

};

1117

1118

// Watch all microservices in specific groups

1119

namingService.fuzzyWatch("microservice-*", microserviceWatcher);

1120

1121

// Watch specific service patterns across groups

1122

namingService.fuzzyWatch("*-api", "production-*", microserviceWatcher);

1123

1124

// Get matched service keys for discovery

1125

Future<ListView<String>> future = namingService.fuzzyWatchWithServiceKeys("microservice-*", microserviceWatcher);

1126

ListView<String> matchedServices = future.get();

1127

1128

System.out.println("Discovered microservices:");

1129

for (String serviceName : matchedServices.getData()) {

1130

System.out.println(" - " + serviceName);

1131

1132

// Get instances for each discovered service

1133

List<Instance> instances = namingService.getAllInstances(serviceName);

1134

System.out.printf(" Instances: %d%n", instances.size());

1135

}

1136

```

1137

1138

### Service Registry with Health Checking

1139

1140

```java

1141

import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Http;

1142

import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Tcp;

1143

1144

// Register service with HTTP health check

1145

public void registerWithHttpHealthCheck(String serviceName, String ip, int port,

1146

String healthPath) throws NacosException {

1147

Instance instance = new Instance();

1148

instance.setIp(ip);

1149

instance.setPort(port);

1150

instance.setHealthy(true);

1151

instance.setEnabled(true);

1152

1153

// Configure HTTP health check

1154

Http httpCheck = new Http();

1155

httpCheck.setPath(healthPath);

1156

httpCheck.setHeaders("User-Agent=Nacos-Health-Check");

1157

httpCheck.setExpectedResponseCode(200);

1158

1159

// Add health check metadata

1160

instance.addMetadata("healthcheck.type", "http");

1161

instance.addMetadata("healthcheck.path", healthPath);

1162

instance.addMetadata("healthcheck.interval", "5000");

1163

1164

namingService.registerInstance(serviceName, instance);

1165

System.out.printf("Registered %s with HTTP health check at %s%n",

1166

serviceName, healthPath);

1167

}

1168

1169

// Register service with TCP health check

1170

public void registerWithTcpHealthCheck(String serviceName, String ip, int port) throws NacosException {

1171

Instance instance = new Instance();

1172

instance.setIp(ip);

1173

instance.setPort(port);

1174

instance.setHealthy(true);

1175

instance.setEnabled(true);

1176

1177

// Configure TCP health check

1178

Tcp tcpCheck = new Tcp();

1179

1180

// Add health check metadata

1181

instance.addMetadata("healthcheck.type", "tcp");

1182

instance.addMetadata("healthcheck.timeout", "3000");

1183

instance.addMetadata("healthcheck.interval", "5000");

1184

1185

namingService.registerInstance(serviceName, instance);

1186

System.out.printf("Registered %s with TCP health check%n", serviceName);

1187

}

1188

```

1189

1190

### Load Balancing and Service Selection

1191

1192

```java

1193

import java.util.Random;

1194

import java.util.concurrent.atomic.AtomicInteger;

1195

1196

public class ServiceLoadBalancer {

1197

1198

private final NamingService namingService;

1199

private final AtomicInteger roundRobinCounter = new AtomicInteger(0);

1200

private final Random random = new Random();

1201

1202

public ServiceLoadBalancer(NamingService namingService) {

1203

this.namingService = namingService;

1204

}

1205

1206

// Round-robin load balancing

1207

public Instance selectRoundRobin(String serviceName, String groupName) throws NacosException {

1208

List<Instance> instances = namingService.selectInstances(serviceName, groupName, true);

1209

1210

if (instances.isEmpty()) {

1211

return null;

1212

}

1213

1214

int index = roundRobinCounter.getAndIncrement() % instances.size();

1215

return instances.get(index);

1216

}

1217

1218

// Weighted random selection

1219

public Instance selectWeightedRandom(String serviceName, String groupName) throws NacosException {

1220

List<Instance> instances = namingService.selectInstances(serviceName, groupName, true);

1221

1222

if (instances.isEmpty()) {

1223

return null;

1224

}

1225

1226

// Calculate total weight

1227

double totalWeight = instances.stream()

1228

.mapToDouble(Instance::getWeight)

1229

.sum();

1230

1231

// Random selection based on weight

1232

double randomWeight = random.nextDouble() * totalWeight;

1233

double currentWeight = 0;

1234

1235

for (Instance instance : instances) {

1236

currentWeight += instance.getWeight();

1237

if (currentWeight >= randomWeight) {

1238

return instance;

1239

}

1240

}

1241

1242

return instances.get(instances.size() - 1);

1243

}

1244

1245

// Select instance by zone preference

1246

public Instance selectByZone(String serviceName, String groupName, String preferredZone) throws NacosException {

1247

List<Instance> instances = namingService.selectInstances(serviceName, groupName, true);

1248

1249

// First try preferred zone

1250

List<Instance> zoneInstances = instances.stream()

1251

.filter(instance -> preferredZone.equals(instance.getMetadata().get("zone")))

1252

.collect(Collectors.toList());

1253

1254

if (!zoneInstances.isEmpty()) {

1255

return zoneInstances.get(random.nextInt(zoneInstances.size()));

1256

}

1257

1258

// Fallback to any available instance

1259

if (!instances.isEmpty()) {

1260

return instances.get(random.nextInt(instances.size()));

1261

}

1262

1263

return null;

1264

}

1265

}