RABBITMQ JAVA

来源:互联网 发布:线切割3b编程实例匕首 编辑:程序博客网 时间:2024/05/20 13:05

一:”Hello RabbitMQ”
下面有一幅图,其中P表示生产者,C表示消费者,红色部分为消息队列
这里写图片描述
客户端:

package rabbitmq;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;public class Send {    private final static String QUEUE_NAME = "hello";    public static void main(String[] argv) throws Exception {        //创建连接工厂        ConnectionFactory factory = new ConnectionFactory();        //设置连接信息        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        //创建连接        Connection connection = factory.newConnection();        //打开通道        Channel channel = connection.createChannel();        //声明一个消息队列        /*注1:queueDeclare第一个参数表示队列名称、第二个参数为是否持久化(true表示是,队列将在服务器重启时生存)           、第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除)           、第四个参数为当所有消费者客户端连接断开时是否自动删除队列、第五个参数为队列的其他参数*/        channel.queueDeclare(QUEUE_NAME, false, false, false, null);        String message = "Hello World!";        //消息推送         /*注2:basicPublish第一个参数为交换机名称、第二个参数为队列映射的路由key            、第三个参数为消息的其他属性、第四个参数为发送信息的主体*/        channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));        System.out.println(" [x] Sent '" + message + "'");        //关闭通道,断开连接        channel.close();        connection.close();    }}

接收端:

import com.rabbitmq.client.*;import java.io.IOException;public class Recv {    private final static String QUEUE_NAME = "hello";    public static void main(String[] argv) throws Exception {        // 创建连接工厂        ConnectionFactory factory = new ConnectionFactory();        // 设置连接信息        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        // 创建连接        Connection connection = factory.newConnection();        // 打开通道        Channel channel = connection.createChannel();        // 声明一个消息队列(此队列和发送端的队列信息保持一致,否则会报错(Channel Error))        channel.queueDeclare(QUEUE_NAME, false, false, false, null);        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");        // DefaultConsumer类实现了Consumer接口,通过传入一个频道,        // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery        Consumer consumer = new DefaultConsumer(channel) {            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                    byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received '" + message + "'");            }        };        // 自动回复队列应答 -- RabbitMQ中的消息确认机制        // 第一个参数是消息队列,第二个参数是手动应答标志如果为true的话,每次生产者只要发送信息就会从内存中删除        // 第三个参数是消费者        channel.basicConsume(QUEUE_NAME, true, consumer);    }}

二:实现任务分发
工作队列

一个队列的优点就是很容易处理并行化的工作能力,但是如果我们积累了大量的工作,我们就需要更多的工作者来处理,这里就要采用分布机制了。
这里写图片描述
发送端:

import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.MessageProperties;public class NewTask {    private static final String TASK_QUEUE_NAME = "task_queue12";    public static void main(String[] argv) throws Exception {        //创建工厂        ConnectionFactory factory = new ConnectionFactory();        //创建工厂连接信息        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        //创建连接        Connection connection = factory.newConnection();        //创建通道        Channel channel = connection.createChannel();        //创建队列 消息本地持久化        channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);        for (int i = 0; i < 10; i++) {            String message = "hello" + i;            channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN,                    message.getBytes("UTF-8"));            System.out.println(" [x] Sent '" + message + "'");        }        channel.close();        connection.close();    }}

接收端1:

package rabbitmq;import com.rabbitmq.client.*;import java.io.IOException;public class Worker2 {    private static final String TASK_QUEUE_NAME = "task_queue12";    public static void main(String[] argv) throws Exception {        // 创建工厂        ConnectionFactory factory = new ConnectionFactory();        // 创建工厂连接信息        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        // 创建连接        Connection connection = factory.newConnection();        // 创建通道        Channel channel = connection.createChannel();        // 创建队列 消息本地持久化        channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");         //每次从队列获取的数量        channel.basicQos(1);        final Consumer consumer = new DefaultConsumer(channel) {            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                    byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received '" + message + "'");                try {                    doWork(message);                } finally {                    System.out.println(" [x] Done");                    //                    channel.basicAck(envelope.getDeliveryTag(), false);                }            }        };        //手动消息确认默认打开。在前面的例子中,我们明确地通过设置为true 标志关闭了它们。        //一旦我们完成了一项任务,现在是时候将这个标志设置为false,并且向工作人员发送一个正确的确认。        channel.basicConsume(TASK_QUEUE_NAME, false, consumer);    }    private static void doWork(String task) {        try {            Thread.sleep(1000);        } catch (InterruptedException _ignored) {            Thread.currentThread().interrupt();        }    }}

接收端2和接收端1代码一样

三:发布/订阅
在上一篇说到的队列都指定了名称,但是现在我们不需要这么做,我们需要所有的日志信息,而不只是其中的一个。如果要做这样的队列,我们需要2件事,一个就是获取一个新的空的队列,这样我就需要创建一个随机名称的队列,最好让服务器帮我们做出选择,第一个就是我们断开用户的队列,应该自动进行删除。ok下面是一副工作图。
这里写图片描述
交换机有几种类型: direct, topic, headers and fanout.
XCHANGE_TYPE:fanout
//fanout表示分发,所有的消费者得到同样的队列信息
发送端:

package rabbitmq;import com.rabbitmq.client.BuiltinExchangeType;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Channel;public class EmitLog {    private static final String EXCHANGE_NAME = "logs";    public static void main(String[] argv) throws Exception {        //创建工厂        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        //新建连接        Connection connection = factory.newConnection();        //新建通道        Channel channel = connection.createChannel();        //fanout表示分发,所有的消费者得到同样的队列信息        //建立交换机  第一个参数交换机名称 ,第二个参数交换机类型        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);        String message = "hello";         //消息推送        channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));        System.out.println(" [x] Sent '" + message + "'");        channel.close();        connection.close();    }}

接收端:

package rabbitmq;import com.rabbitmq.client.*;import java.io.IOException;public class Worker2 {    private static final String EXCHANGE_NAME = "logsq";    public static void main(String[] argv) throws Exception {        // 创建工厂        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        // 新建连接        Connection connection = factory.newConnection();        // 新建通道        Channel channel = connection.createChannel();         //交换机信息设置        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);        //系统随机生成对列名        String queueName = channel.queueDeclare().getQueue();        //对列绑定交换机        channel.queueBind(queueName, EXCHANGE_NAME, "");        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");        Consumer consumer = new DefaultConsumer(channel) {            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                    byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received '" + message + "'");            }        };        //队列会自动删除        channel.basicConsume(queueName, true, consumer);    }}

XCHANGE_TYPE:direct
发送端:

package rabbitmq;import com.rabbitmq.client.BuiltinExchangeType;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import java.util.Random;import java.util.UUID;/** * 生产者根据routing 分别将信息发送给不同的消费者,如果没有消费者接受,那么消息将丢弃 */public class DirectProducer {    // 交换名称    private static final String EXCHANGE_NAME = "ex_direct";    public static void main(String[] args) throws Exception {        // 创建一个频道        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("1y2812381");        factory.setUsername("wang");        factory.setPassword("wang");        Connection connection = factory.newConnection();        Channel channel = connection.createChannel();        // 声明转发器的类型        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);        String message = "123";        // 发布消息至转发器,指定routingkey        channel.basicPublish(EXCHANGE_NAME, "severity", null, message.getBytes());        System.out.println(" [x] Sent '" + message + "'");        channel.close();    }}

接收端:

package rabbitmq;import java.io.IOException;import java.util.Random;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.BuiltinExchangeType;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 DirectConsumer {    private static final String EXCHANGE_NAME = "ex_direct";    public static void main(String[] args) throws Exception {        // 创建一个频道           ConnectionFactory factory = new ConnectionFactory();           factory.setHost("1y2812381");           factory.setUsername("wang");           factory.setPassword("wang");           Connection connection = factory.newConnection();           Channel channel = connection.createChannel();        // 声明direct类型转发器        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);        String queueName = channel.queueDeclare().getQueue();        // 指定binding_key        channel.queueBind(queueName, EXCHANGE_NAME, "severity");        System.out.println(" [*] Waiting for "+"severity"+" logs. To exit press CTRL+C");        Consumer consumer = new DefaultConsumer(channel){            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                                       byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received '" + message + "'");            }        };        channel.basicConsume(queueName, true, consumer);    }}

Topics
发送端:

package rabbitmq;import java.util.UUID;  import com.rabbitmq.client.Channel;  import com.rabbitmq.client.Connection;  import com.rabbitmq.client.ConnectionFactory;  public class EmitLogTopic  {      private static final String EXCHANGE_NAME = "topic_logs";      public static void main(String[] argv) throws Exception      {          // 创建连接和频道          ConnectionFactory factory = new ConnectionFactory();          factory.setHost("192.168.71.127");        factory.setUsername("wang");        factory.setPassword("wang");        //创建连接        Connection connection = factory.newConnection();          //创建通道        Channel channel = connection.createChannel();           //设置交换机主题类型        channel.exchangeDeclare(EXCHANGE_NAME, "topic");          String[] routing_keys = new String[] { "kernel.info.on", "cron.warning",                  "auth.info", "kernel.critical" };          //信息推送        for (String routing_key : routing_keys)          {              String msg = UUID.randomUUID().toString();              channel.basicPublish(EXCHANGE_NAME, routing_key, null, msg                      .getBytes());              System.out.println(" [x] Sent routingKey = "+routing_key+" ,msg = " + msg + ".");          }          channel.close();          connection.close();      }  }  

接收端1:

package rabbitmq;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;import com.rabbitmq.client.QueueingConsumer;  public class ReceiveLogsTopicForCritical{      private static final String EXCHANGE_NAME = "topic_logs";      public static void main(String[] argv) throws Exception      {          // 创建连接和频道          ConnectionFactory factory = new ConnectionFactory();          factory.setHost("192.168.71.127");        factory.setUsername("wang");        factory.setPassword("wang");          Connection connection = factory.newConnection();          Channel channel = connection.createChannel();          // 声明转发器          channel.exchangeDeclare(EXCHANGE_NAME, "topic");          // 随机生成一个队列          String queueName = channel.queueDeclare().getQueue();        //接收所有与kernel相关的消息   * 代表一个单词  #代表一个或多个单词        channel.queueBind(queueName, EXCHANGE_NAME, "*.critical");          System.out.println(" [*] Waiting for critical messages. To exit press CTRL+C");          Consumer consumer = new DefaultConsumer(channel){            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                                       byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received *.critical'"+envelope.getRoutingKey() + message + "'");            }        };        channel.basicConsume(queueName, true, consumer);      }  }  

接收端2:

package rabbitmq;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;import com.rabbitmq.client.QueueingConsumer;    public class ReceiveLogsTopicForKernel1  {      private static final String EXCHANGE_NAME = "topic_logs";      public static void main(String[] argv) throws Exception      {          // 创建连接和频道          ConnectionFactory factory = new ConnectionFactory();          factory.setHost("192.168.71.127");        factory.setUsername("wang");        factory.setPassword("wang");         Connection connection = factory.newConnection();          Channel channel = connection.createChannel();          // 声明转发器          channel.exchangeDeclare(EXCHANGE_NAME, "topic");          // 随机生成一个队列          String queueName = channel.queueDeclare().getQueue();          //接收所有与kernel相关的消息   * 代表一个单词  #代表一个或多个单词        channel.queueBind(queueName, EXCHANGE_NAME, "kernel.#");          System.out.println(" [*] Waiting for messages about kernel. To exit press CTRL+C");          Consumer consumer = new DefaultConsumer(channel){            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,                                       byte[] body) throws IOException {                String message = new String(body, "UTF-8");                System.out.println(" [x] Received kernel.*'"+envelope.getRoutingKey()  + message + "'");            }        };        channel.basicConsume(queueName, true, consumer);      }}  
原创粉丝点击