messere1 opened a new issue, #10601:
URL: https://github.com/apache/rocketmq/issues/10601

   ## Motivation
   
   Since 5.0, gRPC clients report Settings / Subscription / Heartbeat to the 
Proxy via the telemetry stream, but none of this runtime state is exposed 
through any admin interface. Management tools are therefore blind to gRPC 
clients, which is the common root cause behind several long-standing issues:
   
   - rocketmq-dashboard#381: gRPC consumer lag displayed as -1
   - rocketmq-dashboard#380: Pop consumers falsely reported as NOT_CONSUME_YET
   - rocketmq-dashboard#402: request code 106/206 not supported
   
   Tactical fixes on the dashboard side (e.g. rocketmq-dashboard#424) 
demonstrate the need, but the systematic solution requires the Proxy to expose 
its client runtime view through a standard admin API.
   
   This RIP proposes a new admin interface surface on the Proxy, starting with 
**online client query** as the first module. It directly serves the Control 
Plane 5.0 initiative.
   
   ---
   
   ## Proposal (first module)
   
   Two read-only RPCs, defined in rocketmq-apis:
   
   ### ListClients
   
   ```
   ListClients(filter, page_size, next_token) → ClientInstance[]
   ```
   
   **Filter fields:** group / topic / clientId prefix / language / role / 
connected_after
   
   Returns a paginated list of client connections on the local Proxy node.
   
   ### DescribeClient
   
   ```
   DescribeClient(client_id) → ClientDetail
   ```
   
   Returns: negotiated Settings, subscription entries, recent heartbeat 
records, auth status.
   
   ---
   
   ## Key Design Decisions
   
   ### D1 — Service placement (open for community discussion)
   
   **Option A (default proposal):** Extend the existing 
`apache.rocketmq.v2.Admin` service with these RPCs, on the same gRPC port as 
messaging.
   
   - Pro: Zero new concepts; minimal review friction; ACL isolation is 
independent of service placement (`proxy.admin.client` resource type works 
regardless).
   - Con: `ChangeLogLevel` is broker-ops, client query is proxy-runtime — 
conceptually mixed.
   
   **Option B (alternative):** New dedicated `ProxyAdminService`.
   
   - Pro: Clean conceptual separation.
   - Con: Adds a new service to the API surface; needs extra justification.
   
   Feedback requested: which approach does the community prefer?
   
   ### D2 — Authorization
   
   New ACL 2.0 resource type `proxy.admin.client` (read-only actions `LIST` / 
`GET`), so the admin surface has its own permission scope, independent from the 
data plane.
   
   Clusters without ACL enabled can use the admin API by default, with a global 
`proxyAdminEnable=false` kill switch.
   
   ### D3 — Multi-proxy semantics: local view
   
   Each Proxy returns its local view with `proxy_endpoint` + `epoch` fields; 
aggregation/dedup is done by the consumer (dashboard / CLI). A cluster-level 
aggregated view can be a future evolution.
   
   Rationale: no cross-node consensus overhead, clean failure domains, fastest 
path to a usable API.
   
   ### D4 — Pagination: cursor-based
   
   `ListClients` uses an opaque `next_token` cursor, filtering pushed down into 
the client managers — no full dump on proxies with a large number of 
connections.
   
   Rationale: client connections are highly dynamic; offset pagination is 
unstable under concurrent connect/disconnect events.
   
   ### D5 — Dual-protocol coverage
   
   Both gRPC and Remoting clients connected to the Proxy are included, 
distinguished by a `protocol` field, so management tools get a single 
protocol-agnostic client list.
   
   ---
   
   ## Proto Sketch
   
   ```protobuf
   message ClientFilter {
     optional string consumer_group = 1;
     optional string topic = 2;
     optional string client_id_prefix = 3;
     optional apache.rocketmq.v2.Language language = 4;
     optional ClientRole role = 5;       // PRODUCER / PUSH_CONSUMER / 
SIMPLE_CONSUMER
     optional google.protobuf.Timestamp connected_after = 6;
   }
   
   message ListClientsRequest {
     ClientFilter filter = 1;
     int32 page_size = 2;                // Server-enforced max, e.g. 1000
     string next_token = 3;
   }
   
   message ClientInstance {
     string client_id = 1;
     Language language = 2;
     string client_version = 3;
     string access_point = 4;
     google.protobuf.Timestamp connect_time = 5;
     google.protobuf.Timestamp last_active_time = 6;
     ClientRole role = 7;
     repeated string groups = 8;
     string auth_subject = 9;
   }
   
   message ListClientsResponse {
     Status status = 1;
     repeated ClientInstance clients = 2;
     string next_token = 3;
     string proxy_endpoint = 4;
     int64 epoch = 5;                    // Local-view: node epoch for 
consumer-side dedup
   }
   
   message DescribeClientRequest { string client_id = 1; }
   
   message ClientDetail {
     ClientInstance instance = 1;
     Settings settings = 2;              // Reuse existing Settings message
     repeated SubscriptionEntry subscriptions = 3;
     repeated HeartbeatRecord recent_heartbeats = 4;
     AuthStatus auth_status = 5;
   }
   ```
   
   Reuses existing `Language`, `Settings`, `Status` from `definition.proto` — 
no duplication.
   
   ---
   
   ## Existing Code Foundation (verified)
   
   The Proxy module already has the necessary infrastructure:
   
   | Component | Class | Role |
   |-----------|-------|------|
   | gRPC server assembly | `GrpcServerBuilder.addService()` | Supports 
registering additional services |
   | Client channel mgmt | `GrpcChannelManager` | clientId → channel mappings |
   | Client activity | `ClientActivity` | Registration, heartbeat, telemetry |
   | Client settings | `GrpcClientSettingsManager` | Settings negotiation data 
source |
   | Client registries | `ProducerManager` / `ConsumerManager` (broker module) 
| The actual client data |
   | Metrics | `ProxyMetricsManager` | OpenTelemetry infrastructure |
   | Config | `ProxyConfig` | Centralized configuration |
   
   ---
   
   ## Implementation Plan
   
   | Step | Repo | Description |
   |------|------|-------------|
   | PR-08 | rocketmq-apis | Proto definitions + buf lint |
   | PR-09 | rocketmq | ClientManager `scanClients()` with inline filtering |
   | PR-10 | rocketmq | `ListClients` gRPC implementation + GrpcServer 
registration |
   | PR-11 | rocketmq | `DescribeClient` gRPC implementation |
   | PR-12 | rocketmq | Filter semantics (by group/topic) + Remoting protocol 
coverage |
   | PR-13 | rocketmq | ACL 2.0 resource registration + gRPC interceptor |
   | PR-14 | rocketmq | Local-view epoch/endpoint semantics + docs |
   | PR-15 | rocketmq | Admin API OpenTelemetry metrics |
   | PR-16 | rocketmq | Benchmark: 1M clients, ListClients P99 < 1s |
   | PR-17 | rocketmq/docs | User guide + ACL policy template |
   
   ---
   
   ## Planned Follow-up Modules (not part of first module)
   
   - Proxy config query / hot-update
   - Rate-limit quota visibility
   - Client kick-out
   - Pop/Batch diagnostics
   
   ---
   
   ## DISCUSS
   
   A [DISCUSS] thread will be posted on [email protected]. Feedback is 
especially welcome on:
   
   1. **Service placement** (D1): Extend existing `Admin` vs. new 
`ProxyAdminService`?
   2. **Local view** (D3): Is local view acceptable for the first version?
   3. **ACL granularity** (D2): Is `proxy.admin.client` as a single resource 
sufficient?
   
   ---
   
   **References:**
   - dashboard#380: Pop consumers falsely reported as NOT_CONSUME_YET
   - dashboard#381: gRPC consumer lag displayed as -1
   - dashboard#402: request code 106/206 not supported
   - dashboard#424: Cross-broker offset matching hardening (transitional fix)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to