Skip to content

RFC: Client side address resolution

Julien Viet edited this page Apr 28, 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

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 connection using a pool of connections. When a connection is needed, an endpoint if created, whe a pool is empty, its endpoint is disposed.

We can introduce a connection manager that delegates to the original connection manager that performs the resolution of the name. Therefore the state shall be maintained by this connection manager as a map of name -> endpoint, each endpoint holding the state of the resolver. This connection manager interacts then with the original connection manager 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.

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).

Clone this wiki locally