Service Discovery

A core abstraction in ServiceTalk is its ServiceDiscoverer used by the protocol Clients (eg. HTTP/1.1, HTTP/2, gRPC, etc.).

For scenarios where a client communicates with multiple homogeneous [1] server instances, managing addresses of multiple server instances for each client is complex. A ServiceTalk client leverages ServiceDiscoverer to find server instances that it can use for processing requests. A ServiceDiscoverer finds server instances associated with a logical name. ServiceTalk assumes that the client operates in a dynamic ephemeral environment and the server instances associated with a logical name may change over time. So, a ServiceDiscoverer returns a Publisher of ServiceDiscovererEvent(s) that provide information about server instances, their current relationship to the logical name (i.e. whether it is added or removed from the logical name), and any additional information that is supported by a ServiceDiscoverer implementation. Using this information the LoadBalancer of a Client can maintain an active collections to server instances that it can use.

                     |   Service  |
                     | Discoverer |
                           |                 +--------------+
                           |            /--->| Connection 1 |
                           V            |    +--------------+
+--------+ request  +--------------+    |
|        |--------->|              |    |    +--------------+
| Client |          | LoadBalancer |<---+--->| Connection 2 |
|        |<---------|              |    |    +--------------+
+--------+ response +--------------+    |
                                        |    +--------------+
                                        \--->| Connection x |

ServiceDiscoverer is typically not invoked in the request/response path and addresses are resolved "out of band", a.k.a in the background.


ServiceDiscoverer abstraction allows for various protocol-independent Service Discovery mechanisms to be implemented. This section will discuss the various implementations offered in ServiceTalk.

Domain Name System (DNS)

DefaultDnsServiceDiscovererBuilder is used to configure and build instances of ServiceDiscoverer that use Domain Name System (DNS) to resolve hosts represented by domain name into a set of IP-addresses needed for Clients to connect to the remote servers. Resolution happens every TTL seconds.

This is the default implementation that will be used automatically if no alternative ServiceDiscoverer is configured when users create a Client instance.

This implementation is backed by io.netty:netty-resolver-dns and provides non-blocking DNS resolutions.

By default, ServiceTalk implementation adds io.netty:netty-resolver-dns-native-macos:$nettyVersion:osx-x86_64 dependency to support native macOS API for retrieving the current nameserver configuration of the system. Users who never use macOS may safely exclude this dependency from the classpath. macOS users may experience problems with resolving host addresses in certain environments without this dependency.

1. belonging to the same service, providing same capabilities