在Finagle中的客户端实例之间共享连接池

时间:2019-01-16 18:35:41

标签: 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连接到设备foobar,实例B连接到baz

您现在有了另一项服务,例如poke-service,需要与特定设备(通过device-service)进行通话。我解决此问题的方法是让device-service实例A寄存器foobar,实例B寄存器baz都针对自己的本地地址。因此,查找foo解析为device-service实例A的地址,而不是所有device-service实例的更通用的簇。

我要解决的问题是优化问题,我想让finagle认识到foobar实际上都解析为相同的地址并重用了它的所有资源。作为连接的一部分进行分配和维护。另外,如果foobar被重新分配给不同的device-service实例,我希望根据Consul中的信息正常工作此更改。

0 个答案:

没有答案