Kora фреймворк для написания Java / Kotlin приложений с упором на производительность, эффективность, прозрачность сделанный разработчиками Т-Банк / Тинькофф

Kora is a framework for writing Java / Kotlin applications with a focus on performance, efficiency, transparency made by T-Bank / Tinkoff developers

Skip to content

gRPC server

Module for gRPC server handlers support based on grpc.io functionality.

Dependency

Dependency build.gradle:

implementation "ru.tinkoff.kora:grpc-server"
implementation "io.grpc:grpc-protobuf:1.62.2"
implementation "javax.annotation:javax.annotation-api:1.3.2"

Module:

@KoraApp
public interface Application extends GrpcServerModule { }

Dependency build.gradle.kts:

implementation("ru.tinkoff.kora:grpc-server")
implementation "io.grpc:grpc-protobuf:1.62.2"
implementation("javax.annotation:javax.annotation-api:1.3.2")

Module:

@KoraApp
interface Application : GrpcServerModule

Plugin

The code for the gRPC server is created with protobuf gradle plugin.

Plugin build.gradle:

plugins {
    id "com.google.protobuf" version "0.9.4"
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.25.3" }
    plugins {
        grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.62.2" }
    }
    generateProtoTasks {
        all()*.plugins { grpc {} }
    }
}

sourceSets {
    main.java {
        srcDirs "build/generated/source/proto/main/grpc"
        srcDirs "build/generated/source/proto/main/java"
    }
}

Plugin build.gradle.kts:

import com.google.protobuf.gradle.id

plugins {
    id("com.google.protobuf") version ("0.9.4")
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.25.3" }
    plugins {
        id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:1.62.2" }
    }
    generateProtoTasks {
        ofSourceSet("main").forEach { it.plugins { id("grpc") { } } }
    }
}

kotlin {
    sourceSets.main {
        kotlin.srcDir("build/generated/source/proto/main/grpc")
        kotlin.srcDir("build/generated/source/proto/main/java")
    }
}

Configuration

Example of a complete configuration described in the GrpcServerConfig class (example values or default values are indicated):

grpcServer {
    port = 8090 //(1)!
    maxMessageSize = "4MiB" //(2)!
    reflectionEnabled = false //(3)!
    shutdownWait = "30s" //(4)!
    telemetry {
        logging {
            enabled = false //(5)!
        }
        metrics {
            enabled = true //(6)!
            slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(6)!
        }
        tracing {
            enabled = true //(8)!
        }
    }
}
  1. gRPC server port
  2. Maximum size of the incoming message (specified as a number in bytes / or as 4MiB / 4MB / 1000Kb etc.)
  3. Enables gRPC Server Reflection service
  4. Time to wait for processing before shutting down the server in case of graceful shutdown
  5. Enables module logging (default false)
  6. Enables module metrics (default true)
  7. Configures SLO for DistributionSummary metrics
  8. Enables module tracing (default true)
grpcServer:
  port: 8090 #(1)!
  maxMessageSize = "4MiB" #(2)!
  reflectionEnabled = false #(3)!
  shutdownWait: "30s" #(4)!
  telemetry:
    logging:
      enabled: false #(5)!
    metrics:
      enabled: true #(6)!
      slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(6)!
    telemetry:
      enabled: true #(8)!
  1. gRPC server port
  2. Maximum size of the incoming message (specified as a number in bytes / or as 4MiB / 4MB / 1000Kb etc.)
  3. Enables gRPC Server Reflection service
  4. Time to wait for processing before shutting down the server in case of graceful shutdown
  5. Enables module logging (default false)
  6. Enables module metrics (default true)
  7. Configures SLO for DistributionSummary metrics
  8. Enables module tracing (default true)

You can also configure Netty transport.

Handlers

Created gRPC service handlers are required to be tagged with the @Component annotation:

@Component
public class ExampleService extends ExampleGrpc.ExampleImplBase {}
@Component
class ExampleService : ExampleGrpc.ExampleImplBase {}

Interceptors

Interceptors allow you to intercept requests before they are passed to handlers.

Default

The following interceptors are used at server startup by default:

  • ContextServerInterceptor.
  • CoroutineContextInjectInterceptor.
  • MetricCollectorServerInterceptor
  • LoggingServerInterceptor.

To override the default interceptor list, you can override the serverBuilder method from the GrpcModule class

Custom

Adding your custom interceptor requires creating an inheritor of ServerInterceptor with the @Component annotation:

@Component
public class GrpcExceptionHandlerServerInterceptor implements ServerInterceptor {

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, 
                                                                 Metadata metadata,
                                                                 ServerCallHandler<ReqT, RespT> serverCallHandler) {
        // do something

        return serverCallHandler.startCall(serverCall, metadata):
    }
}
@Component
class GrpcExceptionHandlerServerInterceptor : ServerInterceptor {

    override fun <ReqT, RespT> interceptCall(
        serverCall: ServerCall<ReqT, RespT>,
        metadata: Metadata,
        serverCallHandler: ServerCallHandler<ReqT, RespT>
    ): ServerCall.Listener<ReqT> {
        // do something

        return serverCallHandler.startCall(serverCall, metadata)
    }
}

Reflection

Supported by gRPC Server Reflection which provides information about publicly available gRPC services on the server and helps clients at runtime build RPC requests and responses without pre-compiled service information. It is used by the gRPC command line tool (gRPC CLI), which can be used to examine server proto-files and send/receive test RPCs. Reflection is only supported for proto-based services.

You can learn more about working with gRPC Server Reflection here.

Dependency

An optional gRPC Server Reflection dependency is required.

Зависимость build.gradle:

implementation "io.grpc:grpc-services:1.62.2"

Зависимость build.gradle.kts:

implementation("io.grpc:grpc-services:1.62.2")

Configuration

You must also enable the gRPC Server Reflection service in the configuration:

grpcServer {
    reflectionEnabled = false //(1)!
}
  1. Enables gRPC Server Reflection service
grpcServer:
  reflectionEnabled: false #(1)!
  1. Enables gRPC Server Reflection service