測試數據:
topic為:topic_a
consume group為:group
broker為:broker_a
consumer的cid分別為:cid_0,cid_1,...
queue id分別為:0,1,...
代碼測試的是,3個mq,在2/3/4個consumer情況下的mq分配情況
public class StrategyTest {
public static void allocate(AllocateMessageQueueStrategy strategy, int mqSize, int cidSize) {
List<String> cidList = new ArrayList<String>();
for (int i = 0; i < cidSize; i++) {
cidList.add("cid_" + i);
}
List<MessageQueue> mqList = new ArrayList<MessageQueue>(mqSize);
for (int i = 0; i < mqSize; i++) {
mqList.add(makeMq(i));
}
for (int i = 0; i < cidSize; i++) {
doTest(strategy, i, cidList, mqList);
}
System.out.println("-----");
}
private static void doTest(AllocateMessageQueueStrategy strategy, int currentCid, List<String> cidList, List<MessageQueue> mqList) {
List<MessageQueue> result = strategy.allocate("group","cid_" + currentCid, mqList, cidList);
List<Integer> queueIdList = new ArrayList<>(result.size());
for (MessageQueue mq : result) {
queueIdList.add(mq.getQueueId());
}
System.out.println("cid: " + currentCid + " queueId: " + queueIdList);
}
private static MessageQueue makeMq(int queueId) {
MessageQueue q = new MessageQueue();
q.setTopic("topic_a");
q.setBrokerName("broker_a");
q.setQueueId(queueId);
return q;
}
public static void main(String[] args) {
test(new AllocateMessageQueueAveragely());
test(new AllocateMessageQueueAveragelyByCircle());
}
private static void test(AllocateMessageQueueStrategy strategy) {
System.out.println(strategy.getClass().getSimpleName());
System.out.println(" ");
StrategyTest.allocate(strategy, 3, 2);
StrategyTest.allocate(strategy, 3, 3);
StrategyTest.allocate(strategy, 3, 4);
System.out.println("|||||");
}
}
結果如下面所示:
cid: 0 queueId: [0, 1]
cid: 1 queueId: [2]
-----
cid: 0 queueId: [0]
cid: 1 queueId: [1]
cid: 2 queueId: [2]
-----
cid: 0 queueId: [0]
cid: 1 queueId: [1]
cid: 2 queueId: [2]
cid: 3 queueId: []
分配示意圖.png
mqadmin工具提供了一個allocateMQ子命令,通過其我們可以預覽某個Topic在多個消費者分區是如何分配的,使用方式如下:
sh bin/mqadmin allocateMQ -i ip1,ip2,ip3 -t TopicA -n localhost:9876
這個工具可以將模擬分配的結果進行json格式展示。