Configuration
A gRPC client is configured with a GrpcClientSettings
GrpcClientSettings
instance. There are a number of ways of creating one and the API docs are the best reference. An ActorSystem
is always required as it is used for default configuration and service discovery.
By Code
The simplest way to create a client is to provide a static host and port.
- Scala
-
source
GrpcClientSettings.connectToServiceAt("localhost", 443)
- Java
-
source
GrpcClientSettings.connectToServiceAt("localhost", 443, actorSystem);
Further settings can be added via the with
methods
- Scala
-
source
GrpcClientSettings.connectToServiceAt("localhost", 443).withDeadline(1.second).withTls(false)
- Java
-
source
GrpcClientSettings.connectToServiceAt("localhost", 443, actorSystem) .withDeadline(Duration.ofSeconds(1)) .withTls(false);
By Configuration
Instead a client can be defined in configuration. All client configurations need to be under pekko.grpc.client
- Scala
-
source
pekko.grpc.client { "project.WithSpecificConfiguration" { service-discovery { service-name = "my-service" } host = "my-host" port = 42 override-authority = "google.fr" deadline = 10m user-agent = "Pekko-gRPC" } }
- Java
-
source
pekko.grpc.client { "project.WithSpecificConfiguration" { service-discovery { service-name = "my-service" } host = "my-host" port = 42 override-authority = "google.fr" deadline = 10m user-agent = "Pekko-gRPC" } }
Clients defined in configuration pick up defaults from reference.conf
:
reference.conf
-
source
pekko.grpc.client."*" { # netty or pekko-http (experimental) backend = "netty" # Host to use if service-discovery-mechanism is set to static or grpc-dns host = "" service-discovery { mechanism = "static" # Service name to use if a service-discovery.mechanism other than static or grpc-dns service-name = "" # See https://pekko.apache.org/docs/pekko-management/current/discovery/index.html for meanings for each mechanism # if blank then not passed to the lookup port-name = "" protocol = "" # timeout for service discovery resolving resolve-timeout = 1s } # port to use if service-discovery-mechanism is static or service discovery does not return a port port = 0 # Experimental in grpc-java https://github.com/grpc/grpc-java/issues/1771 # pick_first or round_robin load-balancing-policy = "" deadline = infinite override-authority = "" user-agent = "" # Location on the classpath of CA PEM to trust trusted = "" use-tls = true # SSL provider to use: # leave empty to auto-detect, or configure 'jdk' or 'openssl'. ssl-provider = "" # TODO: Enforce HTTP/2 TLS restrictions: https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-9.2 # The number of times to try connecting before giving up. # '-1': means retry indefinitely, '0' is invalid, '1' means fail # after the first failed attempt. # When load balancing we don't count individual connection # failures, so in that case any value larger than '1' is also # interpreted as retrying 'indefinitely'. connection-attempts = 20 # Service discovery mechanism to use. The default is to use a static host # and port that will be resolved via DNS. # Any of the mechanisms described in https://pekko.apache.org/docs/pekko-management/current/discovery/index.html can be used # including Kubernetes, Consul, AWS API }
Using Pekko Discovery for Endpoint Discovery
The examples above all use a hard coded host and port for the location of the gRPC service which is the default if you do not configure a service-discovery-mechanism
. Alternatively Pekko Discovery can be used. This allows a gRPC client to switch between discovering services via DNS, config, Kubernetes and Consul and others by just changing the configuration (see Discovery methods in Pekko Management).
To see how to config a particular service discovery mechanism see the Pekko Discovery docs. Once it is configured a service discovery mechanism name can either be passed into settings or put in the client’s configuration.
- Scala
-
source
pekko.grpc.client { "project.WithConfigServiceDiscovery" { service-discovery { mechanism = "config" service-name = "from-config" # optional for discovery protocol = "tcp" port-name = "http" } port = 43 } }
- Java
-
source
pekko.grpc.client { "project.WithConfigServiceDiscovery" { service-discovery { mechanism = "config" service-name = "from-config" # optional for discovery protocol = "tcp" port-name = "http" } port = 43 } }
The above example configures the client project.WithConfigServiceDiscovery
to use config
based service discovery.
Then to create the GrpcClientSettings
:
- Scala
-
source
// an implicit ActorSystem is required to be in scope for service discovery val settings = GrpcClientSettings.fromConfig(clientName = "project.WithConfigServiceDiscovery")
- Java
-
source
// an ActorSystem is required for service discovery GrpcClientSettings.fromConfig( "project.WithConfigServiceDiscovery", actorSystem );
Alternatively if a default instance is available (configured by pekko.discovery.method
) in your system it can be use like this:
- Scala
-
source
// An ActorSystem's default service discovery mechanism GrpcClientSettings .usingServiceDiscovery(serviceName = "my-service") .withServicePortName("https") // (optional) refine the lookup operation to only https ports
- Java
-
source
// An ActorSystem's default service discovery mechanism GrpcClientSettings .usingServiceDiscovery("my-service", actorSystem) .withServicePortName("https"); // (optional) refine the lookup operation to only https ports
Currently service discovery is only queried on creation of the client. A client can be automatically re-created, and go via service discovery again, if a connection can’t be established, see the lifecycle section.
Debug logging
To enable fine grained debug running the following logging configuration can be used.
Put this in a file grpc-debug-logging.properties
:
handlers=java.util.logging.ConsoleHandler
io.grpc.netty.level=FINE
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
Run with -Djava.util.logging.config.file=/path/to/grpc-debug-logging.properties
.