У меня довольно странный случай использования, когда я хочу переопределить атрибут Grpc.TRANSPORT_ATTR_REMOTE_ADDR
на стороне клиента перед отправкой моего запроса.
На стороне сервера я получаю запросы от многих клиентов и извлекаю их источники, используя этот атрибут. Затем я добавляю источник в кеш, чтобы поддерживать состояние на сервере до истечения срока его действия.
Теперь я хочу выполнить некоторые нагрузочные тесты на стороне сервера и запустить много клиентов на одном хосте. сделать это. Я пытался запустить эти клиенты в docker контейнерах, но атрибут remote-addr
, когда запрос достигает сервера, всегда соответствует внешнему IP-адресу компьютера, на котором работает контейнер, то есть он не уникален и будет рассматриваться как кстати по серверу.
Вот как я получаю IP-адрес источника на сервере:
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call,
final Metadata headers,
final ServerCallHandler<ReqT, RespT> next) {
if (call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR) != null) {
final InetSocketAddress remoteAddress = (InetSocketAddress) call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
if (remoteAddress == null) {
throw DeviceModuleException.create(null,"Could not get remote address of grpc client");
}
final Context context = Context.current().withValue(ORIGIN_IP, remoteAddress.getHostName());
return Contexts.interceptCall(context, call, headers, next);
}
return next.startCall(call, headers);
}
И вот что я пытался сделать на стороне клиента:
return BaseApiGrpc.newBlockingStub(NettyChannelBuilder.forAddress(BRIDGE_HOST, BRIDGE_DEVICE_MODULE_PORT)
.sslContext(buildSslContext())
.intercept(new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return new ForwardingClientCall.SimpleForwardingClientCall<>(next.newCall(method, callOptions)) {
@Override
public Attributes getAttributes() {
return Attributes.newBuilder()
.setAll(super.getAttributes())
.set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, new InetSocketAddress("fakeip", 1337))
.set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, new InetSocketAddress("fakeip", 1337))
.build();
}
};
}
})
.build());
Однако сервер по-прежнему получает только фактический IP-адрес хоста, на котором я работаю. Я предполагаю, что есть перехватчики, примененные позже, чем мой перехватчик, и это переопределяет атрибут remote-addr
.
Но как я мог этого достичь? Это что-то сломает?
Я не хочу делать никаких исключений или специальных решений на стороне сервера, я бы хотел, чтобы это не затрагивалось, если это возможно.