Configuration

A gRPC client is configured with a GrpcClientSettingsGrpcClientSettings 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
GrpcClientSettings.connectToServiceAt("localhost", 443)
Java
GrpcClientSettings.connectToServiceAt("localhost", 443, actorSystem);

Further settings can be added via the with methods

Scala
GrpcClientSettings.connectToServiceAt("localhost", 443).withDeadline(1.second).withTls(false)
Java
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 akka.grpc.client

Scala
akka.grpc.client {
  "project.WithSpecificConfiguration" {
    service-discovery {
      service-name = "my-service"
    }
    host = "my-host"
    port = 42
    override-authority = "google.fr"
    deadline = 10m
    user-agent = "Akka-gRPC"
  }
}
Java
akka.grpc.client {
  "project.WithSpecificConfiguration" {
    service-discovery {
      service-name = "my-service"
    }
    host = "my-host"
    port = 42
    override-authority = "google.fr"
    deadline = 10m
    user-agent = "Akka-gRPC"
  }
}

Clients defined in configuration pick up defaults from reference.conf:

reference.conf
akka.grpc.client."*" {

  # 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://doc.akka.io/docs/akka-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-mechism 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 mechamism 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://doc.akka.io/docs/akka-management/current/discovery/index.html can be used
  # including Kubernetes, Consul, AWS API
}

Using Akka 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 Akka 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 Akka Management).

To see how to config a particular service discovery mechanism see the Akka 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
akka.grpc.client {
  "project.WithConfigServiceDiscovery" {
    service-discovery {
      mechanism = "config"
      service-name = "from-config"
      # optional for discovery
      protocol = "tcp"
      port-name = "http"
    }
    port = 43
  }
}
Java
akka.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
// an implicit ActorSystem is required to be in scope for service discovery
val settings = GrpcClientSettings.fromConfig(clientName = "project.WithConfigServiceDiscovery")
Java
// an ActorSystem is required for service discovery
GrpcClientSettings.fromConfig(
        "project.WithConfigServiceDiscovery", actorSystem
);

Alternatively if a SimpleServiceDiscovery instance is available elsewhere in your system it can be passed in:

Scala
// An ActorSystem's default service discovery mechanism
GrpcClientSettings
  .usingServiceDiscovery(serviceName = "my-service")
  .withServicePortName("https") // (optional) refine the lookup operation to only https ports
Java
// 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.

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.