æè¦ï¼ä»»ä½æ²¡æçæ§çç³»ç»ä¸çº¿ï¼ä¸æ¦å¨ç产ç¯å¢åçæ éï¼é£ä¹ææ¥åä¿®å¤é®é¢çåæ¶æ§å°æ æ³å¾å°ä¿è¯
ä¸ã为ä½è¦å¯¹æ¶æ¯ä¸é´ä»¶è¿è¡çæ§ï¼
ä¸çº¿çä¸å¡ç³»ç»éè¦çæ§ï¼ç¶èè¯¸å¦æ¶æ¯éåãæ°æ®åºãåå¸å¼ç¼åçç产ç¯å¢çä¸é´ä»¶ç³»ç»ä¹åæ ·éè¦çæ§ï¼å¦å䏿¦åºç°ä»»ä½æ
éï¼ææ¥åä¿®å¤èµ·æ¥çæ¶é´åæå
¥çäººåææ¬é½ä¼å¤§å¤§å¢å ï¼åæ¶ä¹ä¸æå©äºæ¥åè¿è¡é®é¢åå çæ»ç»åå¤çã
å¯¹äºæ¶æ¯ä¸é´ä»¶RabbitMQé群æ¥è¯´ï¼æ²¡æçæ§è½åæ´æ¯ç¾é¾æ§çãå设ï¼è¿è¡å¨ç产ç¯å¢ä¸çä¸å°è§æ¨¡RabbitMQéç¾¤ï¼æ»å
±æ30个èç¹ï¼ï¼åºç°é¨åèç¹æå¡ä¸å¯ç¨è导è´ç产è
åæ¶è´¹è
çä¸å¡å·¥ç¨æ æ³æ£å¸¸åå¸å订é
æ¶æ¯ï¼
æ¯å¦ï¼Erlangèææºå
åå³å°è¾¾å°ä¸éï¼æå¡å¨ç£ç容éä¸è¶³æè
éååºç°å¤§éæ¶æ¯å 积
ï¼ï¼æ¤æ¶éè¿å置软è´è½½HAProxyçWeb页é¢åæ æ³å¿«éå®ä½åææ¥åºæ ¹æ¬é®é¢æå¨ï¼é£ä¹ç ååè¿ç»´åäºå¯æå¯¹æ¯å°æå¡å¨çæ¥å¿è¿è¡ææ¥æå¯è½åç°å¹¶è§£å³åå¨çé®é¢ã
è¿ç§æ¹å¼èæ¶åèåï¼å¨ç产ç¯å¢å¯¹äºæ
éååºæ¶é´åè§£å³æ¶é´é½é常éè¦ï¼å æ¤é常æå¿
è¦å¯¹è¯¸å¦åRabbitMQè¿æ ·çæ¶æ¯ä¸é´ä»¶è¿è¡åç§åæ°ççæ§ã
äºãå¦ä½å¯¹RabbitMQéç¾¤çæ§ï¼
ï¼1ï¼RabbitMQèªå¸¦çWeb管ç端çæä»¶
RabbitMQä½ä¸ºä¸æ¬¾å¨éèé¢ååºç¨é常æççæ¶æ¯ä¸é´ä»¶,å¿
ç¶å°ä¸äºçæ§åè½ï¼RabbitMQæä¾äºWebçç页é¢çæ§ï¼åªå¨æ¬å°çæµè§å¨ç«¯è®¿é®å°åï¼
http://xxx.xxx.xxx.xxx:15672/
ï¼é»è®¤ç«¯å£å·æ¯15672ï¼ãWebçæ§é¡µé¢å¦ä¸å¾æç¤ºï¼
#å
å¯ç¨rabbitmq_managementæä»¶
./rabbtimq-plugins enable rabbitmq_management
#ç¶å忢MQæå¡åéå¯
rabbitmqctl stop
rabbitmq-server -detached
å¦æåªæ¯å¨æµè¯æç产ç¯å¢å°è§æ¨¡å°åºç¨RabbitMQæ¶æ¯éåï¼æ¯å¦ä¸å¡å¹¶å访é®éè¾ä½ï¼ï¼é£ä¹ç®åå°ç¨ç¨RabbitMQèªå¸¦çWeb页é¢è¿è¡çæ§ä¹å°±è¶³å¤äºã使¯ï¼å¦æå¯¹RabbitMQçå¹¶åæ§è½ãé«å¯ç¨åå
¶ä»åæ°é½æä¸äºå®å¶åççæ§éæ±çè¯ï¼é£ä¹æä»¬å°±æå¿
è¦éç¨å
¶ä»çæ¹å¼æ¥è¾¾å°è¯¥ç®æ ã
ï¼2ï¼RabbitMQçtracingæ¶æ¯è½¨è¿¹è¿½è¸ª
对äºéè级æè
å·¥ä¸çº§åºç¨åºæ¯æ¥è¯´ï¼æ¶æ¯æ¶åçå¯é æ§æ°¸è¿æ¯æå¨ç¬¬ä¸ä½çãæ¶æ¯éåé群å¯è½å 为åç§é®é¢ï¼æ¯å¦ï¼ç产è
/æ¶è´¹è
ä¸RabbitMQçæå¡å¨æå¼è¿æ¥ãErlangèææºæäºãæ¶æ¯ç§¯å导è´RabbitMQå
åè¾¾å°æå¤§éå¼ï¼ï¼é¾å
ä¼åºç°ææ¡æ¶æ¯å¼å¸¸ä¸¢å¤±æè
客æ·ç«¯ç¨åºæ æ³åéæ¥æ¶æ¶æ¯çæ
åµãå æ¤ï¼è¿ä¸ªæ¶åå°±éè¦æä¸ä¸ªè¾å¥½çæºå¶è·è¸ªè®°å½æ¶æ¯çæéè¿ç¨ï¼ä»¥æ¤åå©å¼ååè¿ç»´äººåè¿è¡é®é¢çå®ä½ã
(a)RabbitMQçtracingåç
RabbitMQèªå¸¦çtracing Logæä»¶åè½å¯ä»¥å®æå¯¹äºé群ä¸åä¸ªæ¶æ¯æé/订é
ç轨迹è¿è¡è¿½è¸ªãRabbitMQ tracing logçåçæ¯å°ç产è
æéç»RabbitMQæå¡å¨çæ¶æ¯ï¼æè
RabbitMQæå¡å¨æéç»æ¶è´¹è
çæ¶æ¯æç
§æå®æ ¼å¼åéè³é»è®¤ç交æ¢å¨ä¸ãè¿ä¸ªé»è®¤ç交æ¢å¨å称为âamq.rabbitmq.traceâï¼æ¯ä¸ä¸ªtopicç±»åç交æ¢å¨ãéåRabbitMQä¼å建ä¸ä¸ªç»å®äºè¿ä¸ªäº¤æ¢å¨çéåamq.genéåãéè¿è¿ä¸ªäº¤æ¢å¨ï¼ææ¶æ¯çæµå
¥åæµåºæ
åµè¿è¡å°è£
ååéå°amq.genéåä¸ï¼è¯¥éåä¼ææ¶æ¯æµè½¬çæ¥å¿è®°å½å¨ç¸åºçæ¥å¿ä¸ã
(b)å¯ç¨RabbitMQ tracingæ¥æ¶æ¯è¿½è¸ª
è¿éå¯ä»¥ä½¿ç¨rabbitmq-plugins enable rabbitmq_tracingå½ä»¤æ¥å¯å¨rabbitmq_tracingæä»¶ã
[root@mq-testvm1 sbin]# rabbitmq-plugins enable rabbitmq_tracing
The following plugins have been enabled:
rabbitmq_tracing
Applying plugin configuration to rabbit@rmq-broker-test-1... started 1 plugin.
å
¶å¯¹åºçå
³éæä»¶çå½ä»¤æ¯ï¼rabbitmq-plugins disable rabbitmq_tracing
å¨Web管ççé¢ âAdminâå³ä¾§åæ¬åªæâUsersâãâVirtual Hostsâ以åâPoliciesâè¿ä¸ªä¸Tab项ï¼å¨æ·»å rabbitmq_tracingæä»¶ä¹åï¼ä¼å¤åºâTracingâè¿ä¸é¡¹å
容ãåæ¶ï¼æ·»å å称为âtrace1âçæ¶æ¯è¿½è¸ªä»»å¡ã
å½éè¿Web UI页é¢åå¸ä¸æ¡æ¶æ¯åï¼å¯¹åºçTracing logçTextæ ¼å¼çæ¶æ¯æ¥å¿åèå¦ä¸ï¼
================================================================================
2018-05-27 8:16:34:545: Message published
Node: rabbit@rmq-broker-test-1
Connection: <rabbit@rmq-broker-test-1.2.10776.3>
Virtual host: /
User: root
Channel: 1
Exchange:
Routing keys: [<<"pressure_1">>]
Routed queues: [<<"pressure_1">>]
Properties: [{<<"delivery_mode">>,signedint,1},{<<"headers">>,table,[]}]
Payload:
adfadfadf
ï¼3ï¼éç¨RabbitMQçHTTP APIæ¥å£è¿è¡çæ§
è¦æå»ºç¬ç«ççæ§ç³»ç»ï¼å¯ä»¥ä½¿ç¨RabbitMQæ¬èº«æä¾çRestful HTTP APIæ¥å£æ¥è·ååç§ä¸å¡çæ§éè¦ç宿¶æ°æ®ãå½ç¶ï¼è¿ä¸ªæ¥å£çä½ç¨è¿ä¸æ¢äºè·åä¸äºçæ§æ°æ®ï¼ä¹å¯ä»¥éè¿è¿äºHTTP APIæ¥æä½RabbitMQè¿è¡åç§é群å
æ°æ®çæ·»å /å é¤/æ´æ°çæä½ã
ä¸é¢å举äºå¯ä»¥å©ç¨RabbitMQçHTTP APIæ¥å£å®ç°çåç§æä½ï¼
HTTP API URL
HTTP 请æ±ç±»å
ä¸é¢çHTTP APIæ¥å£åªæ¯å举äºRabbitMQææ¯æçé¨ååè½ï¼è¯»è
å¯ä»¥åèRabbitMQ宿¹ææ¡£å访é®http://server-name:15672/api/çWeb页颿¥è·åæ´å¤çå
¶ä»æ¥å£ä¿¡æ¯ã
ä¸å¡ç åçåå¦å¯ä»¥ä½¿ç¨Apacheçhttpcomponentsç»ä»¶âHttpClientæè
SpringçRestTemplateç»ä»¶çæå¹¶åéHTTPçGET/POST/DELETE/PUT请æ±è³RabbitMQ Serverï¼æ ¹æ®èªå·±çä¸å¡ç®æ 宿ç¸åºçä¸å¡çæ§éæ±ã
ä¸é¢æ¯ä¸ä¸ªä½¿ç¨RabbitMQ Http APIæ¥å£æ¥è·åéç¾¤çæ§åæ°çdemo代ç ï¼ä¸»è¦ä½¿ç¨HttpClient以åjacksonæ¥æ¥è¯¢MQéç¾¤çæ§è½åæ°ååå¨çç¨æ·ä¿¡æ¯ï¼
public class MonitorRabbitMQDemo {
//RabbitMQçHTTP APIââè·åé群å个å®ä¾çç¶æä¿¡æ¯ï¼ipæ¿æ¢ä¸ºèªå·±é¨ç½²ç¸åºå®ä¾ç
private static String RABBIT_NODES_STATUS_REST_URL = "http://ip:15672/api/nodes";
//RabbitMQçHTTP APIââè·åéç¾¤ç¨æ·ä¿¡æ¯ï¼ipæ¿æ¢ä¸ºèªå·±é¨ç½²ç¸åºå®ä¾ç
private static String RABBIT_USERS_REST_URL = "http://ip:15672/api/users";
//rabbitmqçç¨æ·å
private static String RABBIT_USER_NAME = "root";
//rabbitmqçå¯ç
private static String RABBIT_USER_PWD = "root123";
public static void main(String[] args) {
try {
//step1.è·årabbitmqé群å个èç¹å®ä¾çç¶æä¿¡æ¯
Map<String, ClusterStatus> clusterMap =
fetchRabbtMQClusterStatus(RABBIT_NODES_STATUS_REST_URL, RABBIT_USER_NAME, RABBIT_USER_PWD);
//step2.æå°è¾åºå个èç¹å®ä¾çç¶æä¿¡æ¯
for (Map.Entry entry : clusterMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
//step3.è·årabbitmqéç¾¤ç¨æ·ä¿¡æ¯
Map<String, User> userMap =
fetchRabbtMQUsers(RABBIT_USERS_REST_URL, RABBIT_USER_NAME, RABBIT_USER_PWD);
//step2.æå°è¾åºrabbitmqéç¾¤ç¨æ·ä¿¡æ¯
for (Map.Entry entry : userMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
} catch (IOException e) {
e.printStackTrace();
public static Map<String,ClusterStatus> fetchRabbtMQClusterStatus(String url, String username, String password) throws IOException {
Map<String, ClusterStatus> clusterStatusMap = new HashMap<String, ClusterStatus>();
String nodeData = getData(url, username, password);
JsonNode jsonNode = null;
try {
jsonNode = JsonUtil.toJsonNode(nodeData);
} catch (IOException e) {
e.printStackTrace();
Iterator<JsonNode> iterator = jsonNode.iterator();
while (iterator.hasNext()) {
JsonNode next = iterator.next();
ClusterStatus status = new ClusterStatus();
status.setDiskFree(next.get("disk_free").asLong());
status.setFdUsed(next.get("fd_used").asLong());
status.setMemoryUsed(next.get("mem_used").asLong());
status.setProcUsed(next.get("proc_used").asLong());
status.setSocketUsed(next.get("sockets_used").asLong());
clusterStatusMap.put(next.get("name").asText(), status);
return clusterStatusMap;
public static Map<String,User> fetchRabbtMQUsers(String url, String username, String password) throws IOException {
Map<String, User> userMap = new HashMap<String, User>();
String nodeData = getData(url, username, password);
JsonNode jsonNode = null;
try {
jsonNode = JsonUtil.toJsonNode(nodeData);
} catch (IOException e) {
e.printStackTrace();
Iterator<JsonNode> iterator = jsonNode.iterator();
while (iterator.hasNext()) {
JsonNode next = iterator.next();
User user = new User();
user.setName(next.get("name").asText());
user.setTags(next.get("tags").asText());
userMap.put(next.get("name").asText(), user);
return userMap;
public static String getData(String url, String username, String password) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader(BasicScheme.authenticate(creds, "UTF-8", false));
httpGet.setHeader("Content-Type", "application/json");
CloseableHttpResponse response = httpClient.execute(httpGet);
try {
if (response.getStatusLine().getStatusCode() != 200) {
System.out.println("call http api to get rabbitmq data return code: " + response.getStatusLine().getStatusCode() + ", url: " + url);
HttpEntity entity = response.getEntity();
if (entity != null) {
return EntityUtils.toString(entity);
} finally {
response.close();
return StringUtils.EMPTY;
public static class JsonUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
public static JsonNode toJsonNode(String jsonString) throws IOException {
return objectMapper.readTree(jsonString);
public static class User {
private String name;
private String tags;
@Override
public String toString() {
return "User{" +
"name=" + name +
", tags=" + tags +
//GET/SETæ¹æ³çç¥
public static class ClusterStatus {
private long diskFree;
private long diskLimit;
private long fdUsed;
private long fdTotal;
private long socketUsed;
private long socketTotal;
private long memoryUsed;
private long memoryLimit;
private long procUsed;
private long procTotal;
// æ¤å¤çç¥äºGetteråSetteræ¹æ³
@Override
public String toString() {
return "ClusterStatus{" +
"diskFree=" + diskFree +
", diskLimit=" + diskLimit +
", fdUsed=" + fdUsed +
", fdTotal=" + fdTotal +
", socketUsed=" + socketUsed +
", socketTotal=" + socketTotal +
", memoryUsed=" + memoryUsed +
", memoryLimit=" + memoryLimit +
", procUsed=" + procUsed +
", procTotal=" + procTotal +
//GET/SETæ¹æ³çç¥
è¿è¡ä¸é¢çdemoåå¯ä»¥çå°è¾åºçæ¥å¿å¦ä¸ï¼demoä¸ç¨httpclientä»
ä»
ä¸ºçæ¯å±ç¤ºï¼çæ£å¼åä¸åç代ç å¯ä»¥åè使ç¨Spring RestTemplateï¼å
¶ä¸ºå¼åè
è¿è¡äºäºæ¬¡å°è£
ï¼å¯ä»¥ä¸å®ç¨åº¦æé«å¼åæçï¼ï¼
#è¾åºæµè¯ç¯å¢æé¨ç½²ç10个èç¹çé群å®ä¾ä¿¡æ¯
rabbit@rmq-broker-test-8 : ClusterStatus{diskFree=34474188800, diskLimit=0, fdUsed=46, fdTotal=0, socketUsed=2, socketTotal=0, memoryUsed=383752384, memoryLimit=0, procUsed=1200, procTotal=0}
rabbit@rmq-broker-test-9 : ClusterStatus{diskFree=33215782912, diskLimit=0, fdUsed=34, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=139520504, memoryLimit=0, procUsed=378, procTotal=0}
rabbit@rmq-broker-test-6 : ClusterStatus{diskFree=37309734912, diskLimit=0, fdUsed=45, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=144497072, memoryLimit=0, procUsed=387, procTotal=0}
rabbit@rmq-broker-test-7 : ClusterStatus{diskFree=37314203648, diskLimit=0, fdUsed=45, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=204729280, memoryLimit=0, procUsed=387, procTotal=0}
rabbit@rmq-broker-test-4 : ClusterStatus{diskFree=36212776960, diskLimit=0, fdUsed=45, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=136635624, memoryLimit=0, procUsed=387, procTotal=0}
rabbit@rmq-broker-test-5 : ClusterStatus{diskFree=37313929216, diskLimit=0, fdUsed=46, fdTotal=0, socketUsed=2, socketTotal=0, memoryUsed=349737776, memoryLimit=0, procUsed=1206, procTotal=0}
rabbit@rmq-broker-test-2 : ClusterStatus{diskFree=37315076096, diskLimit=0, fdUsed=42, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=173172688, memoryLimit=0, procUsed=381, procTotal=0}
rabbit@rmq-broker-test-3 : ClusterStatus{diskFree=37338624000, diskLimit=0, fdUsed=46, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=88274008, memoryLimit=0, procUsed=387, procTotal=0}
rabbit@rmq-broker-test-1 : ClusterStatus{diskFree=36990242816, diskLimit=0, fdUsed=45, fdTotal=0, socketUsed=0, socketTotal=0, memoryUsed=180700296, memoryLimit=0, procUsed=409, procTotal=0}
rabbit@rmq-broker-test-10 : ClusterStatus{diskFree=33480851456, diskLimit=0, fdUsed=45, fdTotal=0, socketUsed=1, socketTotal=0, memoryUsed=126567928, memoryLimit=0, procUsed=792, procTotal=0}
#è¾åºRabbitMQé群ä¸çç¨æ·å
æ°æ®ï¼å
å«ç¨æ·ååTagæ ç¾ï¼
root : User{name=root, tags=administrator}
guest : User{name=guest, tags=administrator}
ä¸ãå
·å¤çæ§è½åçRabbitMQé群设计
ä¸é¢ä»ç»äºä¸ç§ä¸åçæ¹å¼æ¥å¯¹RabbitMQé群è¿è¡çæ§ï¼å
¶å®æ¬è´¨ä¸æ¥è¯´ï¼ç¬¬ä¸ç§å第ä¸ç§æ¹å¼æ¯ä¸è´çï¼ç»å¿çåå¦ä¼åç°RabbitMQçWeb UIæ¯å®ææ§è¡å·è¡å¨ä½ï¼åé¨ç½²çå®ä¾åéHTTP GET/POST/PUTçç¸åºç请æ±ã
å
¶ä¸ç¬¬ä¸ç§è½å¤çæ§çèå´ç¸å¯¹æéï¼æ´éåå°ä¼åå°ä½¿ç¨ï¼ç¬¬äºç§tracing logæ¹å¼è½å¤å¾å¥½ççæ§æ¶æ¯æé忥æ¶ç轨迹ï¼ä½æ¯å¤å°å¯¹é群æ§è½æææèï¼å¨å®é
åæµä¸åç°è¿ç§æ¹å¼ä¼å¯¼è´èç¹å¤§éå
åæ¶èï¼å
¶çæçlogæ¥å¿ä¹ä¼å½±åç£ççIOï¼å æ¤åªéäºå¨å¼ååæµè¯ç¯å¢è°è¯æ¶ä½¿ç¨ï¼è第ä¸ç§ä½¿ç¨HTTP APIçæ§åè½å¤æ ¹æ®å¼åè
çä¸å¡éæ±èªå®ä¹çæ§èå´ï¼å¯¹äºçæ§æ°æ®ç精度ä¹è½å¤éè¿è°æ´è°ç¨HTTP APIçé´éæ¥å®ç°ãå æ¤ï¼è¿éä½è
è¾ä¸ºæ¨è使ç¨ç¬¬ä¸ç§æ¹å¼æ¥å¯¹å¤§è§æ¨¡çRabbitMQé群è¿è¡çæ§ã