2018 RabbitMQ(2)RPC Use Case and Cluster on MAC

本文介绍如何使用 RabbitMQ 实现远程过程调用 (RPC) 并提供了一个简单的 Java 示例。此外,还详细说明了在 Mac 系统上安装 Erlang 和 RabbitMQ,并设置集群的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2018 RabbitMQ(2)RPC Use Case and Cluster on MAC

Remote Procedure Call(RPC)
http://sillycat.iteye.com/blog/1582971
http://www.rabbitmq.com/tutorials/tutorial-six-java.html
2 important thing: correlationId and replyTo

RPCServer.java
package com.sillycat.easytalker.plugins.rabbitmq.rpc;
import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
public class RPCServer {
private static final String RPC_QUEUE_NAME = "rpc_queue";
private final static String SERVER_HOST = "centos-dev1";
private static int fib(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
public static void main(String[] argv) {
Connection connection = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
factory.setUsername("carl");
factory.setPassword("kaishi");
connection = factory.newConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);
channel.basicQos(1);
System.out.println(" [x] Awaiting RPC requests");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
AMQP.BasicProperties replyProps = new AMQP.BasicProperties.Builder()
.correlationId(properties.getCorrelationId()).build();
String response = "";
try {
String message = new String(body, "UTF-8");
int n = Integer.parseInt(message);
System.out.println(" [.] fib(" + message + ")");
response += fib(n);
} catch (RuntimeException e) {
System.out.println(" [.] " + e.toString());
} finally {
channel.basicPublish("", properties.getReplyTo(), replyProps, response.getBytes("UTF-8"));
channel.basicAck(envelope.getDeliveryTag(), false);
// RabbitMq consumer worker thread notifies the RPC server owner thread
synchronized (this) {
this.notify();
}
}
}
};
channel.basicConsume(RPC_QUEUE_NAME, false, consumer);
// Wait and be prepared to consume the message from RPC client.
while (true) {
synchronized (consumer) {
try {
consumer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (Exception ignore) {
}
}
}
}
}

RPCClient1.java
package com.sillycat.easytalker.plugins.rabbitmq.rpc;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
public class RPCClient1 {

private Connection connection;
private Channel channel;
private String requestQueueName = "rpc_queue";
private String replyQueueName;

private final static String SERVER_HOST = "centos-dev1";
public RPCClient1() throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
factory.setUsername("carl");
factory.setPassword("kaishi");
connection = factory.newConnection();
channel = connection.createChannel();
replyQueueName = channel.queueDeclare().getQueue();
}
public String call(String message) throws Exception {
final String corrId = UUID.randomUUID().toString();
AMQP.BasicProperties props = new AMQP.BasicProperties
.Builder()
.correlationId(corrId)
.replyTo(replyQueueName)
.build();
channel.basicPublish("", requestQueueName, props, message.getBytes("UTF-8"));
final BlockingQueue<String> response = new ArrayBlockingQueue<String>(1);
channel.basicConsume(replyQueueName, true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
if (properties.getCorrelationId().equals(corrId)) {
response.offer(new String(body, "UTF-8"));
}
}
});
return response.take();
}
public void close() throws Exception {
connection.close();
}
public static void main(String[] argv) {
RPCClient1 fibonacciRpc = null;
String response = null;
try {
fibonacciRpc = new RPCClient1();
System.out.println(" [x] Requesting fib(31)");
response = fibonacciRpc.call("31");
System.out.println(" [.] Got '" + response + "'");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fibonacciRpc != null) {
try {
fibonacciRpc.close();
} catch (Exception ignore) {
}
}
}
}
}

Set Up Cluster on MAC
Install erlang on MAC
https://www.macports.org/install.php
After installation, I can run this command
> sudo port selfupdate
> sudo port install erlang +ssl

Verify the Erlang installation by
>erl -version
Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 9.3

Download the latest version of RabbitMQ 3.7.4.tar.xz
> tar xvfJ rabbitmq-server-generic-unix-3.7.4.tar.xz
> sudo ln -s /Users/hluo/tool/rabbitmq-3.7.4 /opt/rabbitmq-3.7.4
> sudo ln -s /opt/rabbitmq-3.7.4 /opt/rabbitmq

Add the sbin to directory
export PATH=/opt/rabbitmq/sbin:$PATH

Start the cluster mode on MAC
> chmod 777 ~/.erlang.cookie
> chmod 400 ~/.erlang.cookie

Check current user
> whoami
hluo

> sudo chown -R hluo ~/.erlang.cookie
> sudo chgrp -R staff ~/.erlang.cookie

Enable plugin
> sudo rabbitmq-plugins enable rabbitmq_management

Start RabbitMQ1
> sudo RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15672}]" RABBITMQ_NODENAME=rabbit1 sbin/rabbitmq-server -detached

Start RabbitMQ2
> sudo RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=rabbit2 sbin/rabbitmq-server -detached

Check status
> rabbitmqctl -n rabbit2 cluster_status
> rabbitmqctl -n rabbit1 cluster_status

Visit the console
http://localhost:15672/#/

Stop and make the second node join the cluster
> sudo sbin/rabbitmqctl -n rabbit2 stop_app
> sbin/rabbitmqctl -n rabbit2 join_cluster rabbit1@machluo
> sudo sbin/rabbitmqctl -n rabbit2 start_app

Check the cluster status
> sbin/rabbitmqctl -n rabbit1 cluster_status
Cluster status of node rabbit1@machluo ...
[{nodes,[{disc,[rabbit1@machluo,rabbit2@machluo]}]},
{running_nodes,[rabbit2@machluo,rabbit1@machluo]},
{cluster_name,<<"rabbit1@machluo.attlocal.net">>},
{partitions,[]},
{alarms,[{rabbit2@machluo,[]},{rabbit1@machluo,[]}]}]


References:
http://sillycat.iteye.com/blog/2416110
http://sillycat.iteye.com/blog/2037218
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值