add option to enable compression for gRPC-server (#133)

* add grpc server compression

* change compression config defaults

* fix review issue

* add note about compression in readme

* add compression section to server config doc
This commit is contained in:
Vadim Vlasov
2023-02-10 17:27:52 +08:00
committed by GitHub
parent fc36e63ea6
commit 8649cc03aa
7 changed files with 116 additions and 2 deletions

View File

@@ -18,7 +18,11 @@ package io.emeraldpay.dshackle
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.monitoring.accesslog.AccessHandlerGrpc
import io.grpc.Codec
import io.grpc.Server
import io.grpc.ServerCall
import io.grpc.ServerCallHandler
import io.grpc.ServerInterceptor
import io.grpc.netty.NettyServerBuilder
import io.micrometer.core.instrument.Metrics
import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics
@@ -42,6 +46,17 @@ open class GrpcServer(
private var server: Server? = null
class CompressionInterceptor : ServerInterceptor {
override fun <ReqT : Any, RespT : Any> interceptCall(
call: ServerCall<ReqT, RespT>,
headers: io.grpc.Metadata,
next: ServerCallHandler<ReqT, RespT>
): ServerCall.Listener<ReqT> {
call.setCompression(Codec.Gzip().messageEncoding)
return next.startCall(call, headers)
}
}
@PostConstruct
fun start() {
log.info("Starting gRPC Server...")
@@ -53,9 +68,12 @@ open class GrpcServer(
.let {
if (mainConfig.accessLogConfig.enabled) {
it.intercept(accessHandler)
} else {
it
}
if (mainConfig.compression.grpc.serverEnabled) {
it.intercept(CompressionInterceptor())
log.info("Compression enabled for gRPC server")
}
it
}
tlsSetup.setupServer("Native gRPC", mainConfig.tls, true)?.let {

View File

@@ -0,0 +1,27 @@
package io.emeraldpay.dshackle.config
class CompressionConfig(
var grpc: GRPC = GRPC()
) {
/**
* Config example:
* ```
* compression:
* grpc:
* server:
* enabled: true
* client:
* enabled: false
* ```
*/
class GRPC(
var serverEnabled: Boolean = true,
var clientEnabled: Boolean = true
)
companion object {
fun default(): CompressionConfig {
return CompressionConfig()
}
}
}

View File

@@ -0,0 +1,32 @@
package io.emeraldpay.dshackle.config
import org.yaml.snakeyaml.nodes.MappingNode
import java.io.InputStream
class CompressionConfigReader : YamlConfigReader(), ConfigReader<CompressionConfig> {
fun read(input: InputStream): CompressionConfig? {
val configNode = readNode(input)
return read(configNode)
}
override fun read(input: MappingNode?): CompressionConfig {
val config = CompressionConfig()
getMapping(input, "compression")?.let { node ->
readGRPC(config.grpc, getMapping(node, "grpc"))
}
return config
}
private fun readGRPC(grpcCompressionConfig: CompressionConfig.GRPC, input: MappingNode?) {
getMapping(input, "server")?.let { serverNode ->
getValueAsBool(serverNode, "enabled")?.let {
grpcCompressionConfig.serverEnabled = it
}
}
getMapping(input, "client")?.let { clientNode ->
getValueAsBool(clientNode, "enabled")?.let {
grpcCompressionConfig.clientEnabled = it
}
}
}
}

View File

@@ -28,4 +28,5 @@ class MainConfig {
var accessLogConfig: AccessLogConfig = AccessLogConfig.default()
var health: HealthConfig = HealthConfig.default()
var signature: SignatureConfig? = null
var compression: CompressionConfig = CompressionConfig.default()
}

View File

@@ -37,6 +37,7 @@ class MainConfigReader(
private val accessLogReader = AccessLogReader()
private val healthConfigReader = HealthConfigReader()
private val signatureConfigReader = SignatureConfigReader(fileResolver)
private val compressionConfigReader = CompressionConfigReader()
fun read(input: InputStream): MainConfig? {
val configNode = readNode(input)
@@ -83,6 +84,9 @@ class MainConfigReader(
signatureConfigReader.read(input).let {
config.signature = it
}
compressionConfigReader.read(input).let {
config.compression = it
}
return config
}
}