Совместное использование пулов соединений между экземплярами клиента в finagle
Учитывая два или более клиентов finagle, которые имеют разные имена получателей, если эти имена разрешаются по одному и тому же адресу в inet, как мне заставить finagle поддерживать только один пул соединений с этой конечной точкой?
Чрезмерно простой пример кода
Приведенный ниже код регистрирует очень простой (и в основном бесполезный) Resolver, который всегда разрешается по одному адресу. На практике это больше похоже на отношения многие к одному (а не все к одному). Есть еще одно простое приложение, которое запускает сервер и двух клиентов, которые оба используют распознаватель, чтобы найти адрес для связи с сервером.
// Registered with finagle Resolver via META-INF/services
class SmartResolver extends AbstractResolver {
@Override public String scheme() { return "smart"; }
@Override public Var<Addr> bind(String arg) {
return Vars.newConstVar(Addrs.newBoundAddr(Addresses.newInetAddress(
// assume this is more complicated and maps many names to
// one address
new InetSocketAddress("127.0.0.1", 9000)))));
}
}
class Main {
public static void main(String[] args) {
// Create a server, we record stats so we can see how many connections
// there are
InMemoryStatsReceiver stats = new InMemoryStatsReceiver();
ListeningServer server = Thrift.server()
.withStatsReceiver(stats)
.serveIface(":9000", (EchoService.ServiceIface) Future::value);
// create a few clients that all connect to a resolved server, the
// resolver ensures that they all are communicating with our server
EchoService.ServiceIface c1 = Thrift.client()
.newIface("smart!c1", EchoService.ServiceIface.class);
EchoService.ServiceIface c2 = Thrift.client()
.newIface("smart!c2", EchoService.ServiceIface.class);
// make sure any lazy connections have been opened
Await.result(c1.echo("c1"));
Await.result(c2.echo("c2"));
// I'm not sure how to see how many physical connections there are
// incoming to the server, or if it's possible to do this.
assertEquals(1, stats.counter(JavaConversions.asScalaBuffer(Arrays.asList("connects"))))
Await.result(server.close());
}
}
// echo.thrift
service EchoService {
string echo(1: string quack);
}
Все детали
Там, где я работаю, у нас есть микросервисная архитектура с использованием finagle и thrift, мы используем Consul для обнаружения сервисов. Некоторые из внешних систем, с которыми мы взаимодействуем, очень ограничивают количество и частоту принимаемых ими tcp-соединений, поэтому некоторые экземпляры служб "несут ответственность" за эти соединения. Чтобы убедиться, что запросы, которым необходимо использовать определенные соединения, отправляются в правильную службу, эта служба регистрирует новое имя службы в консуле, представляющее соединение, за которое она отвечает. Затем клиенты ищут службу по имени соединения, а не по имени службы.
Чтобы было понятнее: скажем, у вас есть device-service
который открывает TCP-соединения с настроенным списком устройств, устройства поддерживают только одно соединение за раз. У вас может быть несколько случаев этого device-service
с какой-то схемой для разделения устройств между device-service
экземпляров. Итак, экземпляр A
подключается к устройствам foo
а также bar
, пример B
подключается к baz
,
Теперь у вас есть другой сервис, скажем poke-service
что необходимо общаться с конкретными устройствами (через device-service
). Я решил эту проблему, чтобы иметь device-service
пример A
регистр foo
а также bar
и экземпляр B
регистр baz
все против своего собственного местного адреса. Итак, глядя вверх foo
разрешается по адресу для device-service
пример A
вместо более общего кластера всех device-service
экземпляров.
Проблема, которую я хотел бы решить, это проблема оптимизации, я хотел бы, чтобы finagle признал, что оба foo
а также bar
фактически использовать один и тот же адрес и повторно использовать все ресурсы, которые он выделяет и поддерживает как часть соединения. Дополнительно если foo
а также bar
переназначить на другой device-service
В некоторых случаях я хотел бы, чтобы все работало, основываясь на информации в Консуле, которая отражала бы это изменение.