Skip to content

RFC: Client side address resolution

Julien Viet edited this page May 26, 2023 · 2 revisions

Introduction

Vert.x clients interact with remote servers using socket addresses which are resolved from inet addresses using DNS.

This proposal aims to allow the usage of unresolved addresses that would be resolved to socket addresses with resolver plugins (e.g Kubernetes) and selection (e.g round-robin)

Goals

  • provide an alternative configuration of a Vert.x client resolving an abstract address to an inet address or socket address.
  • any Vert.x client should be capable of using it when it makes sense
  • supersede vertx-service-discovery (Vert.x 5)

Non goals

  • not be a fault tolerance mechanism or retry mechanism

Current status

  • Vert.x TCP clients rely on the Netty name resolver to perform the DNS name
    • HTTP based: HTTP/Web/gRPC/Consul
    • TCP based: Redis/Pg/MySQL/MsSQL/DB2/Stomp/MQTT/Mail
  • Other clients often rely on the built-in client mechanism
    • Cassandra
    • JDBC/Oracle
    • Mongo
    • Kafka
    • RabbitMQ

Some clients are capable of connection pooling.

About this RFC

This RFC is split in two parts

1/ An API that provides client capable of doing alternative resolution 2/ An SPI that defines name resolution used by clients, name resolution can be statefull (list of addresses, selection state e.g. Round-Robin)

In addition a Vert.x project implementing the SPI will likely be created to provide replace the vertx-service-discovery project.

HTTP client

We introduce a new Address interface that represents an endpoint that can be addressed from a client, the SocketAddress interface inherits from Address. Clients will delegate to the SPI the resolution of Address to SocketAddress.

The HTTP client relies on a connection manager that maintains a list of endpoints keyed by various attributes (server name and port, proxy options, ...), each endpoint manages connections using a pool of connections. When a connection is needed, an endpoint is created, when a pool is empty, its endpoint is destroyed.

A new connection manager delegates to the original connection manager and performs the resolution of Address to SocketAddress. Therefore the state shall be maintained by this connection manager as a map of address -> endpoint, each endpoint holding the state of the resolver. This connection manager interacts then with original connection managers to be aware of the state of the corresponding endpoint (e.g the endpoint is disposed because all TCP connections are closed) to notify the resolver when an logical endpoint should be destroyed

This architecture allows to maintain the pool configuration for socket connections, so a resolver to a particular endpoint would use the same connection if that endpoint is used directly or if another name resolves to this same endpoint again.

There are a few other things we need to clarify like interaction with a proxy server which are done on a a per host basis.

We can expect this to be valid also for Vert.x client using the Vert.x pool (SQL client, Redis client and mail client) or based on the HTTP client (Web client, gRPC client).