本文适合JAVA新人,想了解RabbitMQ又不想去看官网文档的人(英语水看的头疼(◎﹏◎),但建议有能力还是去看官网文档)。

消息队列MQ(一)

MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法。

先引入一下常见的通讯方案。

为什么使用MQ

在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省服务器的请求响应时间,从而提高了系统的吞吐量。

开发中消息队列通常有如下应用场景:

应用解耦、异步处理(提高系统响应速度)、流量削峰(高峰堆积消息,峰后继续处理消息)、日志处理(分布式日志,一般使用kafka)、纯粹通讯。

AMQP 和 JMS

MQ是消息通信的模型;实现MQ的大致有两种主流方式:AMQP、JMS。

AMQP

AMQP高级消息队列协议,是一个进程间传递异步消息的网络协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。

JMS

JMS即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

AMQP 与 JMS 区别

JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式

JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。

JMS规定了两种消息模式;而AMQP的消息模式更加丰富。

消息队列产品:目前市面上成熟主流的MQ有Kafka 、RocketMQ、RabbitMQ,本文主要介绍RabbitMQ使用。

使用Erlang(语言)编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。

RabbitMQ介绍

RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。

RabbitMQ官方地址:http://www.rabbitmq.com/

RabbitMQ提供了6种模式:简单模式,work工作队列(集群)模式,Publish/Subscribe发布与订阅(交换机的广播)模式,Routing(交换机的定向)路由模式,Topics主题(路由灵活)模式,RPC远程调用模式(远程调用,不太算MQ;不作介绍);//括号内的是自己的理解方式仅供参考。详细可以去看官方介绍。

官网对应模式介绍:https://www.rabbitmq.com/getstarted.html

安装RabbirMQ

两种方式:windows环境与Linux环境(这里跳过)

我是LinuxCenOS6.7安装的3.6.10版本

启动成功参考如下两张图

先在WEB页面管理用户

角色说明: Tags

1、超级管理员(administrator)

可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。

2、监控者(monitoring)

可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

3、策略制定者(policymaker) :可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

4、普通管理者(management):仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。

5、其他 :  无法登陆管理控制台,通常就是普通的生产者和消费者。

Virtual Hosts配置

在RabbitMQ中可以虚拟消息服务器Virtual Host,每个Virtual Hosts相当于一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互隔离的。exchange、queue、message不能互通。 相当于mysql的db。Virtual Name一般以/开头。

添加队列,这里需要将上下两张图结合起来看

需改用户的密码

查看默认的交换机

常见的端口

RabbitMQ入门

目标:入门案例将使用RabbitMQ的简单模式实现通讯过程。

1.创建Maven工程,先在pom.xml添加依赖。

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jxjdemo</groupId>
<artifactId>rabbitmq1_demo</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency> <!--rabbitmq的依赖-->
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
</dependency>
</dependencies>
</project>

2.新建生产者类,生产发送消息

 package com.jxjdemo.mq.simple;

 import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; public class SimpleProducer {
public static void main(String args[]) throws Exception{
//1、创建链接工厂对象-factory=newConnectionFactory()。创建链接用
ConnectionFactory factory = new ConnectionFactory(); //2、设置RabbitMQ服务主机地址,默认localhost-factory.setHost("localhost")
factory.setHost("192.168.211.128");
//3、设置RabbitMQ服务端口,默认-1-factory.setPort(5672)
factory.setPort(5672);
//4、设置虚拟主机名字,默认/-factory.setVirtualHost("szitheima")
factory.setVirtualHost("shujuku1122");
//5、设置用户连接名,默认guest-factory.setUsername("admin")
factory.setUsername("admin");
//6、设置链接密码,默认guest-factory.setPassword("admin")
factory.setPassword("123456");
// factory.setConnectionTimeout(5000);
// factory.setWorkPoolTimeout(5000);
// factory.setHandshakeTimeout(5000);
//7、创建链接-connection=factory.newConnection()
Connection connection = factory.newConnection(); //报错,抛异常
//8、创建频道-channel=connection.createChannel()
Channel channel = connection.createChannel();
//9、声明队列-channel.queueDeclare(名称,是否持久化(true先存硬盘,读完再删),是否独占本连接,是否自动删除(false读完再删),附加参数)
channel.queueDeclare("simplequeue", true, false, false, null);
//10、创建消息-Stringm=xxx
String msg = "这是我们第一次发送 MQ消息";
//11、消息发送-channel.basicPublish(交换机[默认DefaultExchage],路由key[简单模式可以传递队列名称],消息其它属性,消息内容)
channel.basicPublish("", "simplequeue", null, msg.getBytes("utf-8"));
//12、关闭资源-channel.close();connection.close()
channel.close();
connection.close();
}
}

执行后发个消息,没看到异常。

扩展:这里遇到的异常有,时间超时

解决方法一:

发送不成功报错,就先重启MQ,在重启【管理员的方式启动】IDE,一般都是MQ的问题。

发送消息为空,消息不能有空格。注意库名字。

解决方法二:

我们安装系统会给系统起个名字导致:修改后的主机名并没有在linux系统的hosts文件中,因此解析的时候,无法直接从该文件中获取,需要多重解析,才能解析该主机名。

不同的linux版本,这个配置文件也可能不同vim /etc/hosts

继续说发送成功的事情。

3.创建消费者,接收消息。

 1 package com.jxjdemo.mq.simple;


import com.rabbitmq.client.*; import javax.security.auth.callback.Callback;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

//这里删除了文档注释
public class SimpleConsumer {
public static void main(String args[]) throws IOException, TimeoutException {
//1、创建链接工厂对象-factory=newConnectionFactory()
ConnectionFactory factory = new ConnectionFactory();
//2、设置RabbitMQ服务主机地址,默认localhost-factory.setHost("localhost")
factory.setHost("192.168.211.128");
//3、设置RabbitMQ服务端口,默认-1-factory.setPort(5672)
factory.setPort(5672);
//4、设置虚拟主机名字,默认/-factory.setVirtualHost("szitheima")
factory.setVirtualHost("shujuku1122");
//5、设置用户连接名,默认guest-factory.setUsername("admin")
factory.setUsername("admin");
//6、设置链接密码,默认guest-factory.setPassword("admin")
factory.setPassword("123456");
//7、创建链接-connection=factory.newConnection()
Connection connection = factory.newConnection();
//8、创建频道-channel=connection.createChannel()
Channel channel = connection.createChannel();
//9、声明队列-channel.queueDeclare(名称,是否持久化,是否独占本连接,是否自动删除,附加参数)
channel.queueDeclare("simplequeue",true ,false , false,null );
//10接收消息
Consumer callback = new DefaultConsumer(channel){
/**
* @param consumerTag 消费者标签,在channel.basicConsume时候可以指定
* @param envelope 信封,消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
* @param properties 属性信息(生产者的发送时指定)
* @param body 消息内容
* @throws IOException
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
Long deliveryTag = envelope.getDeliveryTag(); //消息ID
String exchange = envelope.getExchange();
String routingKey = envelope.getRoutingKey(); //路由KEY
//消息内容
String msg = new String(body,"utf-8");
System.out.println(
"routingKey:" + routingKey +
"routingKey:" + routingKey +
",exchange:" + exchange +
",deliveryTag:" + deliveryTag +
",message:" + msg);
}
};
channel.basicConsume("simplequeue", callback);
//不关闭,继续接受消息
}
}

执行后看到一下结果

当你的代码运行到这里,那么恭喜你入门成功。

这次暂时先到这里结束。欲知其他4种模式且看下回慢慢分解。

RabbitMQ的简单模式快速入门与超时异常的处理方法的更多相关文章

  1. MongoDB快速入门(十)- Limit(),Skip() 方法

    Limit() 方法 要限制 MongoDB 中的记录,需要使用 limit() 方法. limit() 方法接受一个数字型的参数,这是要显示的文档数. 语法: limit() 方法的基本语法如下 & ...

  2. Itextpdf + Adobe Acrobat DC填充模板生成pdf快速入门

    Itextpdf + Adobe Acrobat DC填充模板生成pdf快速入门 生成pdf有很多种方法,如通过freemarker,或 使用itextpdf.本文将使用itextpdf生成pdf 1 ...

  3. IdentityServer4 中文文档 -14- (快速入门)使用 ASP.NET Core Identity

    IdentityServer4 中文文档 -14- (快速入门)使用 ASP.NET Core Identity 原文:http://docs.identityserver.io/en/release ...

  4. RabbitMQ学习总结 第二篇:快速入门HelloWorld

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  5. 中小研发团队架构实践之RabbitMQ快速入门及应用

    原文:中小研发团队架构实践之RabbitMQ快速入门及应用 使用过分布式中间件的人都知道,程序员使用起来并不复杂,常用的客户端API就那么几个,比我们日常编写程序时用到的API要少得多.但是分布式中间 ...

  6. RabbitMQ(一):RabbitMQ快速入门

    RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要对RabbitMQ有所了解,本文是RabbitMQ快速入门文章. RabbitMQ ...

  7. 消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!

    前言 本章我们来一次快速入门RabbitMQ--生产者与消费者.需要构建一个生产端与消费端的模型.什么意思呢?我们的生产者发送一条消息,投递到RabbitMQ集群也就是Broker. 我们的消费端进行 ...

  8. 快速入门分布式消息队列之 RabbitMQ(3)

    目录 目录 前文列表 前言 通道 Channel 一个基本的生产者消费者实现 消费者 生产者 运行结果 应用预取计数 应用 ACK 机制 最后 前文列表 快速入门分布式消息队列之 RabbitMQ(1 ...

  9. 快速入门分布式消息队列之 RabbitMQ(2)

    目录 目录 前文列表 RabbitMQ 的特性 Message Acknowledgment 消息应答 Prefetch Count 预取数 RPC 远程过程调用 vhost 虚拟主机 插件系统 最后 ...

随机推荐

  1. Codeforces J. Soldier and Number Game(素数筛)

    题目描述: Soldier and Number Game time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  2. 如何修改dedecms专题目录默认名称special

    专题有一个聚合的效果,一般会比普通的文章页更符合用户需求.如果用dedecms建专题的话,默认的目录是special,怎么修改修改dedecms专题目录名称呢,比如将/special/改为/s/这样更 ...

  3. GIL全局解释器锁及协程

    GIL全局解释器锁 1.什么是GIL全局解释器锁 GIL本质是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL同一进程内的多线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码 ...

  4. stm32定时器频率采样的方式

    频率采样方法通常采样定时器的计数方法,在stm32中,输入捕捉模式,PWM输入模式,都是可以测试外部信号频率采样的.1.输入捕捉模式需要频繁的进中断,这个方式不太好的.如果一定要用,那么就软件上处理一 ...

  5. hadoop exit code 退出码含义

    原文传送门:http://www.2cto.com/database/201308/236519.html "OS error code 1: Operation not permitted ...

  6. Java中HTTP网络传输中文编码问题

    Java中HTTP网络传输中文编码问题 1.java中new String(str.getBytes("utf-8"),"iso-8859-1")编码详解 前提 ...

  7. Vue模板语法(二)

    Vue模板语法(二) 样式绑定  class绑定 使用方式:v-bind:class="expression" expression的类型:字符串.数组.对象 1.2 style绑 ...

  8. ESA2GJK1DH1K升级篇: 关于升级篇数据校验

    前言 鉴于大家都希望升级的时候加入数据校验,所以就满足大家的要求. 其实我也希望自己做的足够的稳定可靠,让大家使用起来放心. 上一节测试了一节加入校验以后的操作方式,这节来详细的说一下校验部分的代码. ...

  9. 箭头函数可不用return直接将表达式作为函数返回值

    箭头函数如果函数体只有一个表达式,那么表达式将作为函数的返回值,这种写法无须加上return关键字, 看下面两个函数定义 var testAf = () => '111'; var testAf ...

  10. webpack 配置多入口文件,输出多出口文件

    const path = require('path') module.exports = { // 入口文件的配置项 entry: { // 入口文件 entry: './src/entry.js' ...