14.7. 分区客户端连接
分区客户端连接涉及在每次客户端发起连接时将单个客户端路由到同一代理。
分区客户端连接的两个用例是:
- 对持久订阅的客户端进行分区,以确保订阅者始终连接到持久订阅者队列所在的代理。
- 通过可以将客户端整合到数据的来源(也称为数据 gravity)来最小化数据需求。
可运行的订阅
一个 durable 订阅在代理上以队列表示,并在持久订阅者首先连接到代理时创建。此队列保留在代理中,并接收消息,直到客户端取消订阅为止。因此,您希望客户端重复连接到同一代理,以使用订阅者队列中的消息。
要为危险订阅队列分区客户端,您可以在客户端连接中过滤客户端 ID。
Data gravity
如果您在不考虑数据抓取的情况下扩展环境中的代理数量,则一些性能优势将会丢失,因为需要在代理间移动消息。为了支持日期,您应该对客户端连接进行分区,以便客户端用户连接到生成所需消息的代理。
要对客户端连接进行分区,您可以过滤客户端连接的任何属性:
- 分配给连接用户的角色(ROLE_NAME)
- 用户的用户名(USER_NAME)
- 客户端的主机名(SNI_HOST)
- 客户端的 IP 地址(SOURCE_IP)
14.7.1. 对客户端连接进行分区,以支持永久订阅
要为持久化订阅分区客户端,您可以使用一致的哈希算法或正则表达式来过滤进入连接中的客户端 ID。
先决条件
客户端已配置,以便他们可以连接到集群中的所有代理,例如,使用负载均衡器或连接 URL 中配置的所有代理实例。如果代理拒绝连接,因为客户端详情与代理的分区配置不匹配,客户端必须能够连接到集群中的其他代理,以查找接受来自它连接的代理。
14.7.1.1. 使用一致的哈希算法过滤客户端 ID
您可以将集群中的每个代理配置为使用一致的哈希算法来哈希每个客户端连接中的客户端 ID。代理哈希客户端 ID 后,它会对散列值执行 modulo 操作,以返回一个整数值,用于标识客户端连接的目标代理。代理将返回的整数值与代理中配置的唯一值进行比较。如果存在匹配项,代理会接受连接。如果值不匹配,代理会拒绝连接。这个过程会在集群中的每个代理上重复,直到找到匹配项并且代理接受连接。
流程
-
为第一个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 创建
connection-routers
元素并创建connection-route
,以使用一致的哈希算法过滤客户端 ID。例如:<configuration> <core> ... <connection-routers> <connection-route name=”consistent-hash-routing”> <key>CLIENT_ID</target-key> <local-target-filter>NULL|0</local-target-filter> <policy name="CONSISTENT_HASH_MODULO"> <property key="modulo" value="<number_of_brokers_in_cluster>"> </property> </policy> </connection-route> </connection-routers> ... </core> </configuration>
connection-route
-
对于
connection-route 名称
,请为这个连接路由配置指定一个识别字符串。您必须将此名称添加到要应用一致的哈希过滤器的每个代理接受程序中。 key
-
要将过滤器应用到的键类型。要过滤客户端 ID,请在
key
字段中指定CLIENT_ID
。 local-target-filter
-
代理与 modulo 操作返回的整数值进行比较,以确定是否有匹配项,代理可以接受连接。示例中的
NULL|0
值为没有客户端 ID(NULL)的连接提供了匹配的连接,其中 modulo 操作返回的数量为0
。 policy
接受
modulo
属性键,它对哈希的客户端 ID 执行 modulo 操作,以识别目标代理。modulo
属性键的值必须与集群中的代理数量相同。重要策略名称必须是
CONSISTENT_HASH_MODULO
。
-
为第二个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 创建
connection-routers
元素并创建连接路由
,以使用一致的哈希算法过滤客户端 ID。在以下示例中,
local-target-filter
值NULL|1
为没有客户端 ID (NULL)的连接提供匹配,其中 modulo 操作返回的值为1
。<configuration> <core> ... <connection-routers> <connection-route name=”consistent-hash-routing”> <key>CLIENT_ID</target-key> <local-target-filter>NULL|1</local-target-filter> <policy name="CONSISTENT_HASH_MODULO"> <property key="modulo" value="<number_of_brokers_in_cluster>"> </property> </policy> </connection-route> </connection-routers> ... </core> </configuration>
- 重复此步骤,为集群中的每个附加代理创建一致的 hash 过滤器。
14.7.1.2. 使用正则表达式过滤客户端 ID
您可以通过将代理配置为将正则表达式过滤器应用到客户端连接中的客户端 ID 的一部分来对客户端连接进行分区。只有在正则表达式过滤器的结果与为代理配置的本地目标过滤器匹配时,代理才会接受连接。如果没有找到匹配项,代理会拒绝连接。这个过程会在集群中的每个代理上重复,直到找到匹配项并且代理接受连接。
先决条件
- 每个客户端 ID 中的通用字符串,它们可以通过正则表达式过滤。
流程
-
为第一个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 创建
connection-routers
元素并创建connection-route
来过滤客户端 ID 的一部分。例如:<configuration> <core> ... <connection-routers> <connection-route name=”regex-routing”> <key>CLIENT_ID</target-key> <key-filter>^.{3}</key-filter> <local-target-filter>NULL|CL1</local-target-filter> </connection-route> </connection-routers> ... </core> </configuration>
connection-route
-
对于
connection-route 名称
,请为此路由配置指定一个识别字符串。您必须将此名称添加到要应用正则表达式过滤器的每个代理接收器中。 key
-
要将过滤器应用到的键。要过滤客户端 ID,请在
key
字段中指定CLIENT_ID
。 key-filter
正则表达式应用到的客户端 ID 字符串部分,以提取键值。在上面的第一个代理示例中,代理提取一个键值,它是客户端 ID 的前 3 个字符。例如,如果客户端 ID 字符串为
CL100.consumer
,则代理提取键值CL1
。代理提取键值后,它会将其与local-target-filter
的值进行比较。如果进入的连接没有客户端 ID,或者代理无法使用为
key-filter
指定的正则表达式提取键值,则密钥值设置为 NULL。local-target-filter
-
代理与键值比较的值,以确定是否有匹配项,代理可以接受连接。上面的第一个代理示例中所示
NULL|CL1
的值匹配,匹配客户端 ID (NULL)或客户端 ID 中有 3 个字符前缀CL1
的连接。
-
为第二个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 创建
connection-routers
元素并创建连接路由
,以根据客户端 ID 的一部分过滤连接。在以下过滤器示例中,代理使用正则表达式提取客户端 ID 的前 3 个字符的键值。代理将
NULL
和CL2
的值与键值进行比较,以确定是否存在匹配项,代理是否可以接受连接。<configuration> <core> ... <connection-routers> <connection-route name=”regex-routing”> <key>CLIENT_ID</target-key> <key-filter>^.{3}</key-filter> <local-target-filter>NULL|CL2</local-target-filter> </connection-route> </connection-routers> ... </core> </configuration>
- 重复此步骤,并为集群中的每个附加代理创建适当的连接路由过滤器。
14.7.2. 分区客户端连接以支持数据获取
要支持日期,您可以对客户端连接进行分区,以便客户端用户连接到生成所需消息的代理。例如,如果您有一组由生产者和消费者应用程序使用的地址,您可以在特定代理上配置地址。然后,您可以为使用这些地址的制作者和消费者对客户端连接进行分区,以便它们只能连接到该代理。
您可以根据分配给连接用户的角色、用户的用户名或客户端的主机名或 IP 地址对客户端连接进行分区。本节演示了如何通过过滤分配给客户端用户的用户角色来对客户端连接进行分区。如果需要客户端进行身份验证才能连接到代理,您可以将角色分配给客户端用户,并过滤连接,以便只有与角色条件匹配的用户才能连接到代理。
先决条件
- 客户端已配置,以便他们可以连接到集群中的所有代理,例如,使用负载均衡器或连接 URL 中配置的所有代理实例。如果代理拒绝连接,因为客户端与为那个代理配置的分区过滤器条件不匹配,客户端必须能够连接到集群中的其他代理,以查找接受来自它连接的代理。
流程
-
为第一个代理打开 <
broker_instance_dir> /etc/artemis-roles.properties
文件。添加broker1users
角色,并将用户添加到角色中。 -
为第一个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 创建
connection-routers
元素并创建connection-route
,根据分配给用户的角色过滤连接。例如:<configuration> <core> ... <connection-routers> <connection-route name=”role-based-routing”> <key>ROLE_NAME</target-key> <key-filter>broker1users</key-filter> <local-target-filter>broker1users</local-target-filter> </connection-route> </connection-routers> ... </core> </configuration>
connection-route
-
对于
connection-route 名称
,请为此路由配置指定一个识别字符串。您必须将此名称添加到要应用 role 过滤器的每个代理接受程序中。 key
-
要将过滤器应用到的键。要配置基于角色的过滤,在
key
字段中指定ROLE_NAME
。 key-filter
-
代理用来过滤用户角色并提取键值的字符串或正则表达式。如果代理找到匹配的角色,它会将 key 值设置为该角色。如果没有找到匹配的角色,代理会将 key 值设置为 NULL。在上例中,代理将
broker1users
的过滤器应用到客户端用户的角色。代理提取键值后,它会将其与local-target-filter
的值进行比较。 local-target-filter
-
代理与键值比较的值,以确定是否有匹配项,代理可以接受连接。在示例中,代理将
broker1users
的值与键值进行比较。它有一个匹配项,这意味着用户具有broker1users
角色,代理接受连接。
- 重复此步骤,并在过滤器中指定适当的角色来分区集群中的其他代理上的客户端。
14.7.3. 为接受程序添加连接路由
在代理上配置连接路由后,您必须将路由添加到一个或多个代理的 acceptors 中。将连接路由添加到 acceptor 后,代理会将连接路由中配置的过滤器应用到接受方接收的连接。
流程
-
为第一个代理打开 <
broker_instance_dir> /etc/broker.xml
配置文件。 对于您要启用分区的每个接受者,请附加
路由器
密钥并指定connection-route 名称
。在以下示例中,将具有consistent-hash-routing
的connection-route name
添加到artemis
acceptor 中。<configuration> <core> ... <acceptors> ... <!-- Acceptor for every supported protocol --> <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;router="consistent-hash-routing" </acceptor> </acceptors> ... </core> </configuration>
- 重复此步骤,为集群中的每个代理指定适当的连接路由过滤器。