Skip to content

Add gRPC keepalive max_connection_age settings on OTel sources (#6745)#6947

Open
srikanthpadakanti wants to merge 2 commits into
opensearch-project:mainfrom
srikanthpadakanti:feat/grpc-keepalive-6745-public
Open

Add gRPC keepalive max_connection_age settings on OTel sources (#6745)#6947
srikanthpadakanti wants to merge 2 commits into
opensearch-project:mainfrom
srikanthpadakanti:feat/grpc-keepalive-6745-public

Conversation

@srikanthpadakanti

Copy link
Copy Markdown
Collaborator

Description

Adds two optional gRPC server keepalive settings on every Data Prepper source that exposes a gRPC server: max_connection_age and connection_drain_duration. These map directly to Armeria's ServerBuilder.maxConnectionAge(Duration) and ServerBuilder.connectionDrainDuration(Duration), which are Armeria's implementations of gRPC's native MAX_CONNECTION_AGE and MAX_CONNECTION_AGE_GRACE.

Use case (from the issue): horizontally scaled Data Prepper deployments. gRPC clients do not re-resolve DNS once a channel is established, so new replicas never receive traffic until clients reconnect. Setting max_connection_age on the server side forces clients to reconnect periodically and pick up new endpoints.

Sources covered

All four gRPC-server-exposing sources:

  • otlp-source
  • otel-trace-source
  • otel-logs-source
  • otel-metrics-source

Configuration example

source:
  otlp:
    port: 21891
    max_connection_age: PT30M
    connection_drain_duration: PT15S

Same keys are accepted by otel_trace_source, otel_logs_source, and otel_metrics_source.

Behavior


┌──────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┐
│                        Configuration                         │                             Server behavior                             │
├──────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ Both keys omitted (existing pipelines)                       │ Armeria defaults. No upper bound on connection age. Identical to today. │
├──────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ max_connection_age: PT30M                                    │ Connections gracefully closed after 30 minutes.                         │
├──────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ max_connection_age: PT30M + connection_drain_duration: PT15S │ 30 minutes plus a 15 second drain for outstanding RPCs.                 │
├──────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤
│ Misconfigured value (sub-1s, above-24h, drain above-1h)      │ Startup fails with a JSR-303 validation error.                          │
└──────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘

Issues Resolved

Resolves #6745
#6745

Check List

  • [ X ] New functionality includes testing.
  • New functionality has a documentation issue. Please link to it in this PR.
  • [ X ] New functionality has javadoc added
  • [ X ] Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

…earch-project#6745)

Expose `max_connection_age` and `connection_drain_duration` on every
Data Prepper source that exposes a gRPC server (otlp, otel-logs,
otel-trace, otel-metrics). Both settings are optional `Duration` fields
on the existing per-source configuration. When set, they are applied
to the Armeria `ServerBuilder` via `maxConnectionAge(Duration)` and
`connectionDrainDuration(Duration)`. When unset they preserve current
behavior (no upper bound on connection age).

This addresses the horizontal-scaling problem where long-lived gRPC
channels never re-resolve DNS to discover new replicas. Configuring
`max_connection_age` forces clients to reconnect periodically and pick
up new endpoints.

Implementation details:
- New `Duration` fields with `@DurationMin` / `@DurationMax` validation
  on `OTLPSourceConfig`, `OTelLogsSourceConfig`, `OTelTraceSourceConfig`,
  `OTelMetricsSourceConfig`.
- `ServerConfiguration` in `http-common` carries the two new fields so
  `otlp-source` and `otel-metrics-source` pick them up through the
  shared `CreateServer.createGRPCServer(...)` path. `otel-logs-source`
  and `otel-trace-source` apply them directly to their inline
  `ServerBuilder`.
- `hibernate-validator` is promoted to the version catalog
  (`libs.hibernate.validator`) so all four source modules share a
  single pinned version, replacing the inline pin previously in
  `otlp-source`.

Resolves opensearch-project#6745

Signed-off-by: Srikanth Padakanti <srikanth_padakanti@apple.com>
@srikanthpadakanti

Copy link
Copy Markdown
Collaborator Author

@dlvenable please review this

@JsonProperty("max_connection_age")
@DurationMin(seconds = 1)
@DurationMax(hours = 24)
private Duration maxConnectionAge;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the default value set?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kkondaka No default on purpose. It's optional, stays null when unset, and we only apply it when non-null, so omitting it keeps Armeria's default and today's behavior. Can add an explicit default if you'd prefer.

@JsonProperty("connection_drain_duration")
@DurationMin(millis = 0)
@DurationMax(hours = 1)
private Duration connectionDrainDuration;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the default value set?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, no default. Null when unset and only kicks in with max_connection_age, so it's a no-op unless configured

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gRPC KeepAlive Max Connection Age/Grace configuration

2 participants