给出两个或多个具有不同目的地名称的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
实例,我希望根据Consul中的信息正常工作此更改。