Client/Server连接如何工作
Apache Geode客户端进程中的服务器池进程,管理面向服务器层的所有客户端连接请求。 要充分利用池功能,您应该了解连接池如何管理服务器连接。
Client/server通信使用两种不同的方式完成。 每种通信都使用不同类型的连接,以获得最佳性能和可用性。
- 池连接 Pool connections 池连接用于将单独的操作发送到服务器以更新缓存的数据,以满足本地缓存未命中或运行特定查询。 每个池连接都转到服务器正在侦听的host/port位置。 服务器响应同一连接上的请求。 通常,客户端线程对单个操作使用池连接,然后将连接返回到池以供重用,但您可以配置为具有线程绑定的连接。 此图显示了一个客户端和一个服务器的池连接。 在任何时候,池可能具有从零到多个池连接到任何服务器。
订阅连接Subscription connections 订阅连接用于将缓存事件从服务器流转到客户端。 要使用它,请将客户端属性
subscription-enabled
设置为true。 服务器建立队列以异步发送订阅事件,池建立订阅连接以处理传入消息。 事件的发送取决于客户端的订阅方式。
连接池如何选择服务器连接
连接池从locator获取服务器连接信息,或者从静态服务器列表获取服务器连接信息。
- locator locator维护有关哪些服务器可用以及哪些服务器负载最小的信息。 新连接将发送到负载最小的服务器。 连接池在需要新连接时从locator请求服务器信息。 连接池随机选择要使用的locator,直到连接失败连接池会一直粘性使用一个locator。
- 静态服务器列表 如果使用静态服务器列表,则池在启动时将其洗牌一次,以在具有相同列表配置的客户端之间提供随机性,然后运行列表循环连接,根据需要连接到列表中的下一个服务器。 静态服务器列表没有负载平衡或动态服务器发现。
连接池如何连接到服务器
当池需要新连接时,它会执行这些步骤,直到它成功建立连接,已耗尽所有可用服务器,或直到达到free-connection-timeout
。
- 从locator请求服务器连接信息,或从静态服务器列表中检索下一个服务器。
- 向服务器发送连接请求。
如果池在创建订阅连接或配置池以达到min-connections
设置时无法连接,则会记录一个fine
级别的日志消息,并在“ping-interval”指示的时间后重试。
如果应用程序线程调用需要连接的操作,并且连接池无法创建它,则该操作将返回“NoAvailableServersException”。
连接池如何管理池连接
客户端中的每个Pool
实例都维护自己的连接池。连接池尽可能有效地响应连接丢失,新连接请求和根据需要打开新连接。当您将连接池与Locator一起使用时,连接可以快速响应服务器可用性的更改,添加新服务器并断开与不健康或死机服务器的连接,而对客户端线程几乎没有影响。静态服务器列表需要更加小心一些,因为客户端连接池只能连接到列表中指定位置的服务器。
当发生以下某种情况时,连接池会添加新的池连接:
- 打开连接的数量少于
Pool
的'min-connections`设置。 - 线程需要连接,所有打开的连接都在使用中并且添加另一个连接,则不会在连接池的
max-connections
设置的上进行当前在用连接计数。如果已达到最大连接数设置,则线程将阻塞,直到连接可用。
发生以下任一情况时,连接池将关闭池连接:
- 客户端从服务器收到连接异常。
- 服务器不响应客户端配置的
read-timeout
期间的直接请求或ping。在这种情况下,池将删除与该服务器的所有连接。 - 池连接数超过池的
min-connections
设置,且客户端没通过连接发送任何idle-timeout
期间的请求。
当连接池关闭线程正在使用的连接时,连接池会将线程切换到另一个服务器连接,并在需要时打开一个新连接。
连接池如何管理订阅连接
连接池的订阅连接的建立方式与池连接的方式相同,方法是从Locator请求服务器信息,然后向服务器发送请求,或者,如果您使用的是静态服务器列表,则连接到名单上的下一个服务器。
订阅连接根据需要一直保持打开状态,不适用于池连接的超时限制。
连接池如何适应服务器负载情况
使用Locator时,连接池会定期调整其池连接。 每个连接都有一个内部寿命计数器。 当计数器达到配置的load-conditioning-interval
时,池会检查Locator以查看连接是否正在使用负载最小的服务器。 如果没有,则池建立与最少加载的服务器的新连接,静默地替换旧连接,并关闭旧连接。 在任何一种情况下,当操作完成时,计数器从零开始。 调整发生在幕后,不会影响应用程序的连接使用。 这种自动调节功能可以非常有效地应对服务器集群水平延展。 在计划内和计划外服务器中断之后,它也很有用,在此期间,整个客户端负载将被放置在正常服务器集的子集上。