or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-services.mdbinary-logging.mdchannelz.mdhealth-checking.mdindex.mdload-balancing.mdmetrics.mdserver-reflection.md

admin-services.mddocs/

0

# Admin Services

1

2

Collection of standard administrative services for gRPC servers including all built-in observability and management services. Provides a convenient way to add multiple admin services to your gRPC server.

3

4

## Capabilities

5

6

### AdminInterface

7

8

Utility class that provides a collection of standard gRPC administrative services, including channelz, health checking, and server reflection.

9

10

```java { .api }

11

/**

12

* Provides a class of services for exposing the overall state of gRPC activity.

13

* Offers standard administrative services in a single collection.

14

*/

15

@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7929")

16

@ThreadSafe

17

public final class AdminInterface {

18

19

/**

20

* Returns a list of gRPC's built-in admin services

21

* @return List of ServerServiceDefinition containing standard admin services

22

*/

23

public static List<ServerServiceDefinition> getStandardServices();

24

}

25

```

26

27

**Usage Examples:**

28

29

```java

30

import io.grpc.Server;

31

import io.grpc.ServerBuilder;

32

import io.grpc.services.AdminInterface;

33

34

// Add all standard admin services to your server

35

public class AdminEnabledServer {

36

37

public static void main(String[] args) throws Exception {

38

Server server = ServerBuilder.forPort(8080)

39

// Add all standard admin services at once

40

.addServices(AdminInterface.getStandardServices())

41

42

// Add your business services

43

.addService(new UserService())

44

.addService(new OrderService())

45

.build();

46

47

server.start();

48

System.out.println("Server started with admin services on port 8080");

49

50

// Print available admin services

51

System.out.println("Available admin services:");

52

AdminInterface.getStandardServices().forEach(service ->

53

System.out.println(" - " + service.getServiceDescriptor().getName())

54

);

55

56

server.awaitTermination();

57

}

58

}

59

```

60

61

## Standard Services Included

62

63

The AdminInterface provides the following standard services:

64

65

### Channelz Service

66

- **Service Name**: `grpc.channelz.v1.Channelz`

67

- **Purpose**: Runtime introspection and debugging

68

- **Endpoints**: Channel, server, and socket information

69

70

### Health Service

71

- **Service Name**: `grpc.health.v1.Health`

72

- **Purpose**: Health checking for load balancers

73

- **Endpoints**: Health status reporting

74

75

### Server Reflection Service

76

- **Service Name**: `grpc.reflection.v1.ServerReflection`

77

- **Purpose**: Service discovery and debugging tools

78

- **Endpoints**: Protocol buffer reflection

79

80

## Production Server Example

81

82

```java

83

import io.grpc.Server;

84

import io.grpc.ServerBuilder;

85

import io.grpc.services.AdminInterface;

86

import io.grpc.protobuf.services.HealthStatusManager;

87

88

public class ProductionServer {

89

private final Server server;

90

private final HealthStatusManager healthManager;

91

92

public ProductionServer(int port) {

93

// Create health manager for additional control

94

this.healthManager = new HealthStatusManager();

95

96

this.server = ServerBuilder.forPort(port)

97

// Add standard admin services

98

.addServices(AdminInterface.getStandardServices())

99

100

// Override health service with our managed instance

101

.addService(healthManager.getHealthService())

102

103

// Add business services

104

.addService(new UserService())

105

.addService(new OrderService())

106

.addService(new PaymentService())

107

.build();

108

}

109

110

public void start() throws IOException {

111

server.start();

112

113

// Set initial health status

114

healthManager.setStatus("", ServingStatus.SERVING);

115

healthManager.setStatus("com.example.UserService", ServingStatus.SERVING);

116

healthManager.setStatus("com.example.OrderService", ServingStatus.SERVING);

117

healthManager.setStatus("com.example.PaymentService", ServingStatus.SERVING);

118

119

System.out.println("Production server started on port " + server.getPort());

120

System.out.println("Admin services available for monitoring and debugging");

121

122

// Add shutdown hook

123

Runtime.getRuntime().addShutdownHook(new Thread(this::gracefulShutdown));

124

}

125

126

private void gracefulShutdown() {

127

System.out.println("Initiating graceful shutdown...");

128

129

// Mark services as not serving

130

healthManager.setStatus("", ServingStatus.NOT_SERVING);

131

132

// Wait for load balancers to drain traffic

133

try {

134

Thread.sleep(10000); // 10 second drain period

135

} catch (InterruptedException e) {

136

Thread.currentThread().interrupt();

137

}

138

139

// Enter terminal state and shutdown

140

healthManager.enterTerminalState();

141

server.shutdown();

142

143

try {

144

if (!server.awaitTermination(30, TimeUnit.SECONDS)) {

145

server.shutdownNow();

146

}

147

} catch (InterruptedException e) {

148

server.shutdownNow();

149

Thread.currentThread().interrupt();

150

}

151

}

152

153

public void awaitTermination() throws InterruptedException {

154

server.awaitTermination();

155

}

156

}

157

```

158

159

## Development Server with Enhanced Admin Services

160

161

```java

162

import io.grpc.Server;

163

import io.grpc.ServerBuilder;

164

import io.grpc.services.AdminInterface;

165

import io.grpc.protobuf.services.ProtoReflectionServiceV1;

166

import io.grpc.protobuf.services.BinaryLogs;

167

168

public class DevelopmentServer {

169

170

public static void main(String[] args) throws Exception {

171

// Enhanced development server with additional debugging capabilities

172

BinaryLog binaryLog = BinaryLogs.createBinaryLog(); // Debug logging

173

174

Server server = ServerBuilder.forPort(8080)

175

// Add standard admin services

176

.addServices(AdminInterface.getStandardServices())

177

178

// Add enhanced reflection service (latest version)

179

.addService(ProtoReflectionServiceV1.newInstance())

180

181

// Enable binary logging for debugging

182

.setBinaryLog(binaryLog)

183

184

// Add business services

185

.addService(new UserService())

186

.addService(new OrderService())

187

.build();

188

189

server.start();

190

191

System.out.println("Development server started on port 8080");

192

System.out.println("\nAvailable debugging tools:");

193

System.out.println(" grpcurl -plaintext localhost:8080 list");

194

System.out.println(" grpcurl -plaintext localhost:8080 grpc.health.v1.Health/Check");

195

System.out.println(" grpcurl -plaintext localhost:8080 grpc.channelz.v1.Channelz/GetTopChannels");

196

197

server.awaitTermination();

198

}

199

}

200

```

201

202

## Microservices Architecture Integration

203

204

```java

205

public class MicroserviceWithAdminServices {

206

private final Server server;

207

private final HealthStatusManager healthManager;

208

private final MetricRecorder metricRecorder;

209

210

public MicroserviceWithAdminServices(String serviceName, int port) {

211

this.healthManager = new HealthStatusManager();

212

this.metricRecorder = MetricRecorder.newInstance();

213

214

this.server = ServerBuilder.forPort(port)

215

// Standard admin services for observability

216

.addServices(AdminInterface.getStandardServices())

217

218

// Override with managed health service

219

.addService(healthManager.getHealthService())

220

221

// Add service-specific business logic

222

.addService(createBusinessService(serviceName))

223

224

// Add interceptors for metrics

225

.intercept(new MetricsInterceptor(metricRecorder))

226

.build();

227

}

228

229

private BindableService createBusinessService(String serviceName) {

230

switch (serviceName) {

231

case "user-service":

232

return new UserService();

233

case "order-service":

234

return new OrderService();

235

case "payment-service":

236

return new PaymentService();

237

default:

238

throw new IllegalArgumentException("Unknown service: " + serviceName);

239

}

240

}

241

242

public void start() throws IOException {

243

server.start();

244

245

// Set healthy status

246

healthManager.setStatus("", ServingStatus.SERVING);

247

248

// Start metrics reporting

249

startMetricsReporting();

250

251

System.out.println("Microservice started on port " + server.getPort());

252

System.out.println("Admin services enabled for service mesh integration");

253

}

254

255

private void startMetricsReporting() {

256

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

257

258

scheduler.scheduleAtFixedRate(() -> {

259

metricRecorder.setCpuUtilizationMetric(getCurrentCpuUsage());

260

metricRecorder.setMemoryUtilizationMetric(getCurrentMemoryUsage());

261

metricRecorder.setQpsMetric(getCurrentQps());

262

}, 0, 30, TimeUnit.SECONDS);

263

}

264

265

private double getCurrentCpuUsage() {

266

// Implementation to get CPU usage

267

return Math.random() * 0.8; // Example

268

}

269

270

private double getCurrentMemoryUsage() {

271

Runtime runtime = Runtime.getRuntime();

272

return (double) (runtime.totalMemory() - runtime.freeMemory()) / runtime.maxMemory();

273

}

274

275

private double getCurrentQps() {

276

// Implementation to calculate QPS

277

return Math.random() * 1000; // Example

278

}

279

}

280

```

281

282

## Monitoring and Observability Integration

283

284

```java

285

public class ObservableServer {

286

287

public static void main(String[] args) throws Exception {

288

// Server with comprehensive observability

289

Server server = ServerBuilder.forPort(8080)

290

// Standard admin services

291

.addServices(AdminInterface.getStandardServices())

292

293

// Business services

294

.addService(new UserService())

295

296

// Add interceptors for detailed observability

297

.intercept(new LoggingInterceptor())

298

.intercept(new TracingInterceptor())

299

.intercept(new MetricsInterceptor())

300

.build();

301

302

server.start();

303

304

// Start admin service monitoring

305

startAdminServiceMonitoring(server.getPort());

306

307

server.awaitTermination();

308

}

309

310

private static void startAdminServiceMonitoring(int port) {

311

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

312

313

scheduler.scheduleAtFixedRate(() -> {

314

try {

315

// Monitor channelz data

316

monitorChannelzData(port);

317

318

// Monitor health status

319

monitorHealthStatus(port);

320

321

} catch (Exception e) {

322

System.err.println("Monitoring error: " + e.getMessage());

323

}

324

}, 60, 60, TimeUnit.SECONDS); // Monitor every minute

325

}

326

327

private static void monitorChannelzData(int port) {

328

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", port)

329

.usePlaintext()

330

.build();

331

332

try {

333

ChannelzGrpc.ChannelzBlockingStub channelzStub =

334

ChannelzGrpc.newBlockingStub(channel);

335

336

GetServersResponse response = channelzStub.getServers(

337

GetServersRequest.newBuilder().setMaxResults(10).build());

338

339

response.getServerList().forEach(server -> {

340

ServerData data = server.getData();

341

System.out.printf("Server calls: started=%d, succeeded=%d, failed=%d%n",

342

data.getCallsStarted(),

343

data.getCallsSucceeded(),

344

data.getCallsFailed());

345

});

346

347

} finally {

348

channel.shutdown();

349

}

350

}

351

352

private static void monitorHealthStatus(int port) {

353

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", port)

354

.usePlaintext()

355

.build();

356

357

try {

358

HealthGrpc.HealthBlockingStub healthStub =

359

HealthGrpc.newBlockingStub(channel);

360

361

HealthCheckResponse response = healthStub.check(

362

HealthCheckRequest.newBuilder().setService("").build());

363

364

System.out.println("Overall server health: " + response.getStatus());

365

366

} finally {

367

channel.shutdown();

368

}

369

}

370

}

371

```

372

373

## Security Considerations

374

375

Admin services expose operational data and should be secured appropriately:

376

377

```java

378

public class SecureAdminServer {

379

380

public static void main(String[] args) throws Exception {

381

// Check if admin services should be enabled

382

boolean enableAdminServices = Boolean.parseBoolean(

383

System.getProperty("enable.admin.services", "false"));

384

385

ServerBuilder<?> serverBuilder = ServerBuilder.forPort(8080);

386

387

if (enableAdminServices) {

388

System.out.println("Admin services enabled - ensure proper network security");

389

serverBuilder.addServices(AdminInterface.getStandardServices());

390

} else {

391

System.out.println("Admin services disabled for security");

392

}

393

394

Server server = serverBuilder

395

.addService(new UserService())

396

.build();

397

398

server.start();

399

server.awaitTermination();

400

}

401

}

402

403

// Alternative: Admin services on separate port

404

public class SeparateAdminPortServer {

405

406

public static void main(String[] args) throws Exception {

407

// Main business server

408

Server businessServer = ServerBuilder.forPort(8080)

409

.addService(new UserService())

410

.addService(new OrderService())

411

.build();

412

413

// Admin server on separate port (can be firewalled differently)

414

Server adminServer = ServerBuilder.forPort(9090)

415

.addServices(AdminInterface.getStandardServices())

416

.build();

417

418

businessServer.start();

419

adminServer.start();

420

421

System.out.println("Business server on port 8080");

422

System.out.println("Admin server on port 9090");

423

424

// Wait for both servers

425

businessServer.awaitTermination();

426

adminServer.awaitTermination();

427

}

428

}

429

```