5.6.2.2. 配置多个 Middleware 服务交互

多个 Middleware 服务器可以共同维护用户会话共享列表和其它类对象,还能协调处理过期的缓存。每个中间件服务都需要开启 cuba.cluster.enabled 参数启用这个功能。以下是 app_home/local.app.properties 文件的示例:

cuba.cluster.enabled = true

cuba.webHostName = host3
cuba.webPort = 8080

对于中间件服务来说,需要设定正确的 cuba.webHostNamecuba.webPort 这两个属性的值,这样能用这两个属性组成唯一的服务器 ID

服务之间的交互机制是基于 JGroups。平台为 JGroups 提供了两个配置文件:

  • jgroups.xml - 基于 UDP 的协议栈,适用于启用了广播通信的本地网络。这个配置当集群功能开启的时候会被默认使用。

  • jgroups_tcp.xml - 基于 TCP 的协议栈,适用于任何网络。使用这个协议要求在 TCP.bind_addrTCPPING.initial_hosts 参数中显式设定集群成员的地址。如果需要使用这个配置,需要设定 cuba.cluster.jgroupsConfig 这个应用程序属性。

    如果您的 middleware 服务器之间有防火墙,别忘了根据您的 JGroups 配置开启防火墙端口。

为了配置环境中的 JGroups 参数,从 cuba-core-<version>.jar 的根目录拷贝合适的 jgroups.xml 文件到项目的 core 模块根目录(src 目录)或者部署环境的 tomcat/conf/app-core 目录 ,并且修改这个文件。

ClusterManagerAPI bean 提供 Middleware 集群中服务器交互的编程接口。可以在应用程序中使用,需要时可参考 JavaDocs 和平台代码的用法。

用户会话的同步复制

默认情况下,所有发送至集群的消息都是 异步 的。也就是说在其他集群成员收到集群消息之前,中间件代码已经将响应返回给了客户端层。

这样的行为能提高系统的响应时间,但是在负载均衡使用轮询的方式(比如 NGINX 或 Kubernetes)在客户端层和中间件之间路由请求时,会产生问题。那就是,web 客户端的登录请求会在用户会话会话完全复制到其他集群成员之前返回。因此,接下来从 web 客户端发送的请求会被轮询机制重定向至其他的中间件节点,而此时由于其他节点还未收到用户会话,会导致请求失败并产生 NoUserSessionException 异常。

所以,如果集群使用了轮询负载均衡,为避免 NoUserSessionException 的发生,用户会话采取 同步 复制机制。可以在 app.properties 文件(或者目标服务的 app_home/local.app.properties 文件)中设置一下属性:

cuba.syncNewUserSessionReplication = true

# 如果使用 REST API 扩展插件
cuba.rest.syncTokenReplication = true