or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

clustering.mdconfiguration.mdextensions.mdindex.mdmetadata.mdregistry.mdrpc-core.mdserialization.mdspring-boot.md

registry.mddocs/

0

# Service Discovery and Registry

1

2

Apache Dubbo's registry system provides service discovery and registration capabilities with support for multiple backends including ZooKeeper, Nacos, Consul, and etcd. It handles dynamic service management, health monitoring, and provider/consumer coordination.

3

4

## Capabilities

5

6

### Registry Interface

7

8

Core registry interface for service registration and discovery operations.

9

10

```java { .api }

11

/**

12

* Registry interface for service discovery operations

13

*/

14

@SPI("dubbo")

15

public interface Registry extends Node, RegistryService {

16

// Inherits methods from RegistryService and Node interfaces

17

}

18

19

/**

20

* Registry service operations interface

21

*/

22

public interface RegistryService {

23

/**

24

* Register service provider

25

* @param url Service provider URL

26

*/

27

void register(URL url);

28

29

/**

30

* Unregister service provider

31

* @param url Service provider URL

32

*/

33

void unregister(URL url);

34

35

/**

36

* Subscribe to service changes

37

* @param url Consumer URL with subscription parameters

38

* @param listener Notification listener for service changes

39

*/

40

void subscribe(URL url, NotifyListener listener);

41

42

/**

43

* Unsubscribe from service changes

44

* @param url Consumer URL

45

* @param listener Notification listener to remove

46

*/

47

void unsubscribe(URL url, NotifyListener listener);

48

49

/**

50

* Lookup available providers

51

* @param url Service URL to lookup

52

* @return List of available provider URLs

53

*/

54

List<URL> lookup(URL url);

55

}

56

57

/**

58

* Node interface for lifecycle management

59

*/

60

public interface Node {

61

/** Get node URL */

62

URL getUrl();

63

64

/** Check if node is available */

65

boolean isAvailable();

66

67

/** Destroy node and release resources */

68

void destroy();

69

}

70

```

71

72

### Registry Factory

73

74

Factory interface for creating registry instances.

75

76

```java { .api }

77

/**

78

* Registry factory for creating registry instances

79

*/

80

@SPI("dubbo")

81

public interface RegistryFactory {

82

/**

83

* Create registry instance

84

* @param url Registry URL with connection parameters

85

* @return Registry instance

86

*/

87

Registry getRegistry(URL url);

88

}

89

90

/**

91

* Abstract registry factory with common functionality

92

*/

93

public abstract class AbstractRegistryFactory implements RegistryFactory {

94

/** Registry cache by URL */

95

private static final Map<String, Registry> REGISTRIES = new ConcurrentHashMap<>();

96

97

@Override

98

public Registry getRegistry(URL url) {

99

// Normalize URL and get from cache or create new

100

url = URLBuilder.from(url)

101

.setPath(RegistryService.class.getName())

102

.addParameter(INTERFACE_KEY, RegistryService.class.getName())

103

.removeParameters(EXPORT_KEY, REFER_KEY)

104

.build();

105

106

String key = url.toServiceStringWithoutResolving();

107

Registry registry = REGISTRIES.get(key);

108

if (registry != null) {

109

return registry;

110

}

111

112

synchronized (this) {

113

registry = REGISTRIES.get(key);

114

if (registry == null) {

115

registry = createRegistry(url);

116

REGISTRIES.put(key, registry);

117

}

118

}

119

return registry;

120

}

121

122

/** Template method for creating specific registry implementation */

123

protected abstract Registry createRegistry(URL url);

124

}

125

```

126

127

### Notification System

128

129

Event system for handling service provider changes.

130

131

```java { .api }

132

/**

133

* Notification listener for registry changes

134

*/

135

public interface NotifyListener {

136

/**

137

* Handle provider list changes

138

* @param urls Updated list of provider URLs

139

*/

140

void notify(List<URL> urls);

141

}

142

143

/**

144

* Registry event for service changes

145

*/

146

public class RegistryNotification {

147

public enum EventType {

148

REGISTER,

149

UNREGISTER,

150

UPDATE

151

}

152

153

private final EventType eventType;

154

private final URL url;

155

private final long timestamp;

156

157

public RegistryNotification(EventType eventType, URL url) {

158

this.eventType = eventType;

159

this.url = url;

160

this.timestamp = System.currentTimeMillis();

161

}

162

163

public EventType getEventType() { return eventType; }

164

public URL getUrl() { return url; }

165

public long getTimestamp() { return timestamp; }

166

}

167

```

168

169

### ZooKeeper Registry

170

171

ZooKeeper-based service registry implementation.

172

173

```java { .api }

174

/**

175

* ZooKeeper registry implementation

176

*/

177

public class ZookeeperRegistry extends FailbackRegistry {

178

public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter);

179

180

/** Get ZooKeeper client */

181

public ZookeeperClient getZookeeperClient();

182

183

/** Create ZooKeeper path */

184

protected void createPersistent(String path);

185

186

/** Create ephemeral ZooKeeper path */

187

protected void createEphemeral(String path);

188

189

/** Add child listener */

190

protected void addChildListener(String path, ChildListener listener);

191

192

/** Remove child listener */

193

protected void removeChildListener(String path, ChildListener listener);

194

195

@Override

196

protected void doRegister(URL url) {

197

// Create ephemeral sequential node for provider

198

String path = toUrlPath(url);

199

createEphemeral(path);

200

}

201

202

@Override

203

protected void doUnregister(URL url) {

204

// Delete ZooKeeper node

205

String path = toUrlPath(url);

206

zkClient.delete(path);

207

}

208

209

@Override

210

protected void doSubscribe(URL url, NotifyListener listener) {

211

// Subscribe to ZooKeeper path changes

212

String path = toCategoryPath(url);

213

addChildListener(path, new ZookeeperChildListener(listener));

214

}

215

}

216

217

/**

218

* ZooKeeper registry factory

219

*/

220

public class ZookeeperRegistryFactory extends AbstractRegistryFactory {

221

private ZookeeperTransporter zookeeperTransporter;

222

223

@Override

224

protected Registry createRegistry(URL url) {

225

return new ZookeeperRegistry(url, zookeeperTransporter);

226

}

227

}

228

```

229

230

**Usage Examples:**

231

232

```java

233

// ZooKeeper registry configuration

234

RegistryConfig registry = new RegistryConfig();

235

registry.setAddress("zookeeper://127.0.0.1:2181");

236

registry.setUsername("admin");

237

registry.setPassword("password");

238

registry.setTimeout(5000);

239

registry.setSession(60000);

240

241

// Cluster ZooKeeper setup

242

registry.setAddress("zookeeper://127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183");

243

244

// With namespace

245

registry.setAddress("zookeeper://127.0.0.1:2181/dubbo");

246

```

247

248

### Nacos Registry

249

250

Nacos-based service registry implementation for Alibaba's service discovery.

251

252

```java { .api }

253

/**

254

* Nacos registry implementation

255

*/

256

public class NacosRegistry extends FailbackRegistry {

257

public NacosRegistry(URL url, NacosNamingService nacosNamingService);

258

259

/** Get Nacos naming service */

260

public NacosNamingService getNacosNamingService();

261

262

@Override

263

protected void doRegister(URL url) {

264

// Register service instance to Nacos

265

Instance instance = createNacosInstance(url);

266

nacosNamingService.registerInstance(getServiceName(url), instance);

267

}

268

269

@Override

270

protected void doUnregister(URL url) {

271

// Deregister service instance from Nacos

272

Instance instance = createNacosInstance(url);

273

nacosNamingService.deregisterInstance(getServiceName(url), instance);

274

}

275

276

@Override

277

protected void doSubscribe(URL url, NotifyListener listener) {

278

// Subscribe to Nacos service changes

279

String serviceName = getServiceName(url);

280

nacosNamingService.subscribe(serviceName, new NacosEventListener(listener));

281

}

282

283

/** Convert Dubbo URL to Nacos instance */

284

private Instance createNacosInstance(URL url) {

285

Instance instance = new Instance();

286

instance.setIp(url.getHost());

287

instance.setPort(url.getPort());

288

instance.setWeight(url.getParameter(WEIGHT_KEY, DEFAULT_WEIGHT));

289

instance.setHealthy(true);

290

instance.setEnabled(true);

291

instance.setMetadata(new HashMap<>(url.getParameters()));

292

return instance;

293

}

294

}

295

296

/**

297

* Nacos registry factory

298

*/

299

public class NacosRegistryFactory extends AbstractRegistryFactory {

300

@Override

301

protected Registry createRegistry(URL url) {

302

return new NacosRegistry(url, buildNacosNamingService(url));

303

}

304

}

305

```

306

307

**Usage Examples:**

308

309

```java

310

// Nacos registry configuration

311

RegistryConfig registry = new RegistryConfig();

312

registry.setAddress("nacos://127.0.0.1:8848");

313

registry.setGroup("DEFAULT_GROUP");

314

registry.setNamespace("public");

315

316

// With configuration parameters

317

registry.setAddress("nacos://127.0.0.1:8848?namespace=dev&group=dubbo");

318

319

// Authentication

320

registry.setUsername("nacos");

321

registry.setPassword("nacos");

322

```

323

324

### Consul Registry

325

326

HashiCorp Consul integration for service discovery.

327

328

```java { .api }

329

/**

330

* Consul registry implementation

331

*/

332

public class ConsulRegistry extends FailbackRegistry {

333

public ConsulRegistry(URL url, ConsulClient consulClient);

334

335

/** Get Consul client */

336

public ConsulClient getConsulClient();

337

338

@Override

339

protected void doRegister(URL url) {

340

// Register service to Consul

341

NewService service = createConsulService(url);

342

consulClient.agentServiceRegister(service);

343

}

344

345

@Override

346

protected void doUnregister(URL url) {

347

// Deregister service from Consul

348

String serviceId = buildServiceId(url);

349

consulClient.agentServiceDeregister(serviceId);

350

}

351

352

@Override

353

protected void doSubscribe(URL url, NotifyListener listener) {

354

// Watch Consul service changes

355

String serviceName = getServiceName(url);

356

consulClient.healthServicesPass(serviceName, new ConsulQueryCallback(listener));

357

}

358

359

/** Convert Dubbo URL to Consul service */

360

private NewService createConsulService(URL url) {

361

NewService service = new NewService();

362

service.setId(buildServiceId(url));

363

service.setName(getServiceName(url));

364

service.setAddress(url.getHost());

365

service.setPort(url.getPort());

366

service.setTags(buildTags(url));

367

service.setCheck(createHealthCheck(url));

368

return service;

369

}

370

}

371

```

372

373

### Etcd Registry

374

375

etcd-based distributed registry for service discovery.

376

377

```java { .api }

378

/**

379

* Etcd registry implementation

380

*/

381

public class EtcdRegistry extends FailbackRegistry {

382

public EtcdRegistry(URL url, EtcdClient etcdClient);

383

384

@Override

385

protected void doRegister(URL url) {

386

// Register service to etcd with TTL

387

String key = buildEtcdKey(url);

388

String value = url.toFullString();

389

etcdClient.putEphemeral(key, value);

390

}

391

392

@Override

393

protected void doUnregister(URL url) {

394

// Remove service from etcd

395

String key = buildEtcdKey(url);

396

etcdClient.delete(key);

397

}

398

399

@Override

400

protected void doSubscribe(URL url, NotifyListener listener) {

401

// Watch etcd key prefix changes

402

String keyPrefix = buildEtcdKeyPrefix(url);

403

etcdClient.watchPrefix(keyPrefix, new EtcdWatchListener(listener));

404

}

405

}

406

```

407

408

### Multicast Registry

409

410

IP multicast-based registry for local network service discovery.

411

412

```java { .api }

413

/**

414

* Multicast registry for local network discovery

415

*/

416

public class MulticastRegistry extends FailbackRegistry {

417

public MulticastRegistry(URL url);

418

419

/** Get multicast socket */

420

public MulticastSocket getMulticastSocket();

421

422

@Override

423

protected void doRegister(URL url) {

424

// Broadcast registration message

425

String message = REGISTER + url.toFullString();

426

broadcast(message);

427

}

428

429

@Override

430

protected void doUnregister(URL url) {

431

// Broadcast unregistration message

432

String message = UNREGISTER + url.toFullString();

433

broadcast(message);

434

}

435

436

@Override

437

protected void doSubscribe(URL url, NotifyListener listener) {

438

// Add subscription listener

439

subscriptions.put(url, listener);

440

441

// Request current providers

442

String message = SUBSCRIBE + url.toFullString();

443

broadcast(message);

444

}

445

446

/** Broadcast message to multicast group */

447

private void broadcast(String message) {

448

byte[] data = message.getBytes();

449

DatagramPacket packet = new DatagramPacket(data, data.length, multicastAddress, multicastPort);

450

multicastSocket.send(packet);

451

}

452

}

453

```

454

455

**Usage Examples:**

456

457

```java

458

// Multicast registry (development/testing)

459

RegistryConfig registry = new RegistryConfig();

460

registry.setAddress("multicast://224.5.6.7:1234");

461

462

// Custom multicast parameters

463

registry.setAddress("multicast://239.255.255.255:1234?timeout=3000&cleanup=60000");

464

```

465

466

### Registry Configuration

467

468

Advanced registry configuration options and behavior customization.

469

470

```java { .api }

471

/**

472

* Registry configuration constants

473

*/

474

public class RegistryConstants {

475

/** Registry protocol */

476

public static final String REGISTRY_KEY = "registry";

477

public static final String REGISTRY_PROTOCOL = "registry";

478

479

/** Dynamic registration */

480

public static final String DYNAMIC_KEY = "dynamic";

481

public static final boolean DEFAULT_DYNAMIC = true;

482

483

/** Service categories */

484

public static final String CATEGORY_KEY = "category";

485

public static final String PROVIDERS_CATEGORY = "providers";

486

public static final String CONSUMERS_CATEGORY = "consumers";

487

public static final String ROUTERS_CATEGORY = "routers";

488

public static final String CONFIGURATORS_CATEGORY = "configurators";

489

490

/** Registry check */

491

public static final String REGISTRY_CHECK_KEY = "check";

492

493

/** Registry retry period */

494

public static final String REGISTRY_RETRY_PERIOD_KEY = "retry.period";

495

public static final int DEFAULT_REGISTRY_RETRY_PERIOD = 5000;

496

497

/** Registry session timeout */

498

public static final String SESSION_TIMEOUT_KEY = "session";

499

public static final int DEFAULT_SESSION_TIMEOUT = 60000;

500

}

501

```

502

503

### Failback Registry

504

505

Abstract registry with automatic retry capabilities for failed operations.

506

507

```java { .api }

508

/**

509

* Failback registry providing automatic retry for failed operations

510

*/

511

public abstract class FailbackRegistry extends AbstractRegistry {

512

/** Failed registration URLs */

513

private final Set<URL> failedRegistered = new ConcurrentHashSet<>();

514

515

/** Failed unregistration URLs */

516

private final Set<URL> failedUnregistered = new ConcurrentHashSet<>();

517

518

/** Failed subscriptions */

519

private final Map<URL, Set<NotifyListener>> failedSubscribed = new ConcurrentHashMap<>();

520

521

/** Failed unsubscriptions */

522

private final Map<URL, Set<NotifyListener>> failedUnsubscribed = new ConcurrentHashMap<>();

523

524

public FailbackRegistry(URL url) {

525

super(url);

526

// Start retry timer

527

this.retryTimer = new HashedWheelTimer(new NamedThreadFactory("DubboRegistryFailedRetryTimer", true),

528

retryPeriod, TimeUnit.MILLISECONDS, 128);

529

this.retryTimer.newTimeout(this::retry, retryPeriod, TimeUnit.MILLISECONDS);

530

}

531

532

@Override

533

public void register(URL url) {

534

super.register(url);

535

failedRegistered.remove(url);

536

failedUnregistered.remove(url);

537

try {

538

doRegister(url);

539

} catch (Exception e) {

540

failedRegistered.add(url);

541

throw new RpcException("Failed to register " + url, e);

542

}

543

}

544

545

@Override

546

public void unregister(URL url) {

547

super.unregister(url);

548

failedRegistered.remove(url);

549

failedUnregistered.remove(url);

550

try {

551

doUnregister(url);

552

} catch (Exception e) {

553

failedUnregistered.add(url);

554

throw new RpcException("Failed to unregister " + url, e);

555

}

556

}

557

558

/** Retry failed operations */

559

private void retry(Timeout timeout) {

560

// Retry failed registrations

561

if (!failedRegistered.isEmpty()) {

562

Set<URL> failed = new HashSet<>(failedRegistered);

563

for (URL url : failed) {

564

try {

565

doRegister(url);

566

failedRegistered.remove(url);

567

} catch (Exception e) {

568

// Keep in failed set for next retry

569

}

570

}

571

}

572

573

// Schedule next retry

574

retryTimer.newTimeout(this::retry, retryPeriod, TimeUnit.MILLISECONDS);

575

}

576

577

/** Template method for actual registration */

578

protected abstract void doRegister(URL url);

579

580

/** Template method for actual unregistration */

581

protected abstract void doUnregister(URL url);

582

583

/** Template method for actual subscription */

584

protected abstract void doSubscribe(URL url, NotifyListener listener);

585

586

/** Template method for actual unsubscription */

587

protected abstract void doUnsubscribe(URL url, NotifyListener listener);

588

}

589

```

590

591

### Service Instance Management

592

593

Modern service instance-based discovery for cloud-native environments.

594

595

```java { .api }

596

/**

597

* Service instance representation

598

*/

599

public interface ServiceInstance extends Serializable {

600

/** Get service name */

601

String getServiceName();

602

603

/** Get instance host */

604

String getHost();

605

606

/** Get instance port */

607

int getPort();

608

609

/** Check if instance is enabled */

610

boolean isEnabled();

611

612

/** Check if instance is healthy */

613

boolean isHealthy();

614

615

/** Get instance metadata */

616

Map<String, String> getMetadata();

617

618

/** Get instance ID */

619

String getId();

620

}

621

622

/**

623

* Service discovery interface for cloud-native service mesh

624

*/

625

@SPI("zookeeper")

626

public interface ServiceDiscovery extends Closeable {

627

/**

628

* Initialize service discovery

629

* @throws Exception if initialization fails

630

*/

631

void initialize(URL registryURL) throws Exception;

632

633

/**

634

* Register service instance

635

* @param serviceInstance Service instance to register

636

* @throws RuntimeException if registration fails

637

*/

638

void register(ServiceInstance serviceInstance) throws RuntimeException;

639

640

/**

641

* Update service instance

642

* @param serviceInstance Service instance to update

643

* @throws RuntimeException if update fails

644

*/

645

void update(ServiceInstance serviceInstance) throws RuntimeException;

646

647

/**

648

* Unregister service instance

649

* @param serviceInstance Service instance to unregister

650

* @throws RuntimeException if unregistration fails

651

*/

652

void unregister(ServiceInstance serviceInstance) throws RuntimeException;

653

654

/**

655

* Get service instances by service name

656

* @param serviceName Service name

657

* @return Set of service instances

658

* @throws RuntimeException if lookup fails

659

*/

660

Set<ServiceInstance> getInstances(String serviceName) throws RuntimeException;

661

662

/**

663

* Get all service names

664

* @return Set of service names

665

* @throws RuntimeException if lookup fails

666

*/

667

Set<String> getServices() throws RuntimeException;

668

669

/**

670

* Add service instance change listener

671

* @param serviceName Service name to watch

672

* @param listener Change listener

673

* @throws RuntimeException if listener addition fails

674

*/

675

void addServiceInstancesChangedListener(String serviceName,

676

ServiceInstancesChangedListener listener)

677

throws RuntimeException;

678

}

679

```

680

681

**Usage Examples:**

682

683

```java

684

// Complete registry setup with multiple backends

685

DubboBootstrap bootstrap = DubboBootstrap.getInstance();

686

687

// Primary registry (ZooKeeper)

688

RegistryConfig primaryRegistry = new RegistryConfig();

689

primaryRegistry.setAddress("zookeeper://127.0.0.1:2181");

690

primaryRegistry.setGroup("production");

691

692

// Backup registry (Nacos)

693

RegistryConfig backupRegistry = new RegistryConfig();

694

backupRegistry.setAddress("nacos://127.0.0.1:8848");

695

backupRegistry.setGroup("production");

696

backupRegistry.setBackup(true);

697

698

bootstrap.registries(Arrays.asList(primaryRegistry, backupRegistry));

699

700

// Service with multiple registry support

701

ServiceConfig<GreeterService> service = new ServiceConfig<>();

702

service.setInterface(GreeterService.class);

703

service.setRef(new GreeterServiceImpl());

704

service.setRegistry(primaryRegistry);

705

service.export();

706

```