Совместное использование пулов соединений между экземплярами клиента в finagle - PullRequest
0 голосов
/ 16 января 2019

С учетом двух или более клиентов 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 экземпляры, я бы хотел, чтобы все просто работали на основе информации в Консуле, которая отражала бы это изменение.

...