-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Open
Labels
Description
Is your feature request related to a problem? Please describe.
JsonToGrpcGatewayFilter which converts a json to a gRPC creates ManagedChannel on every call.
package org.springframework.cloud.gateway.filter.factory;
public class JsonToGrpcGatewayFilterFactory
extends AbstractGatewayFilterFactory<JsonToGrpcGatewayFilterFactory.Config> {
... ...
class GRPCResponseDecorator extends ServerHttpResponseDecorator {
... ...
// We are creating this on every call, should optimize?
private ManagedChannel createChannelChannel(String host, int port) {
NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port);
try {
return grpcSslConfigurer.configureSsl(nettyChannelBuilder);
}
catch (SSLException e) {
throw new RuntimeException(e);
}
}
}
}Furthermore, there's no logic that call shutdown() ManagedChannel.
2023-11-03T12:12:05.152+09:00 ERROR 6277 --- [ctor-http-nio-3] i.g.i.ManagedChannelOrphanWrapper :
*~*~*~ Previous channel ManagedChannelImpl{logId=7, target=localhost:8081} was not shutdown properly!!! ~*~*~*
Make sure to call shutdown()/shutdownNow() and wait until awaitTermination() returns true.Describe the solution you'd like
So here below is my suggestion using ConcurrentHashMap to recycle ManagedChannels.
(or add something like lifecycle to manages all ManageChannels?)
Describe alternatives you've considered
package org.springframework.cloud.gateway.filter.factory;
public class JsonToGrpcGatewayFilterFactory
extends AbstractGatewayFilterFactory<JsonToGrpcGatewayFilterFactory.Config> {
// a container for ManagedChannel. key = host + ":" + port
private final ConcurrentHashMap<String, ManagedChannel> ManagedChannelContainer = new ConcurrentHashMap<>();
... ...
class GRPCResponseDecorator extends ServerHttpResponseDecorator {
... ...
// get ManageChannel from ManageChannelContainer and if it exists, return that value(ManageChannel);
// if it doesn't exist, create ManageChannel and put it in ManageChannelContainer and return it.
private ManagedChannel createChannelChannel(String host, int port) {
String key = host + ":" + port;
ManagedChannel managedChannel = ManagedChannelContainer.get(key);
if (managedChannel == null) {
NettyChannelBuilder nettyChannelBuilder = NettyChannelBuilder.forAddress(host, port);
try {
managedChannel = grpcSslConfigurer.configureSsl(nettyChannelBuilder);
ManagedChannelContainer.put(key, managedChannel);
return managedChannel;
}
catch (SSLException e) {
throw new RuntimeException(e);
}
} else {
return managedChannel;
}
}
}
}Additional context
build.gradle
// includes spring-cloud-gateway-server:4.0.7
implementation 'org.springframework.cloud:spring-cloud-gateway-starter:4.0.7'