java 消息队列

Kafka

什么是Kafka

Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。该项目的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。Kafka最初是由LinkedIn开发,并随后于2011年初开源。

kafka软件结构

Kafka是一个结构相对简单的消息队列(MQ)软件

kafka软件结构图

 

Kafka Cluster(Kafka集群)

Partition(分片)

Producer:消息的发送方,也就是消息的来源,Kafka中的生产者

Consumer:消息的接收方,也是消息的目标,Kafka中的消费者

Topic:话题或主题的意思,消息的收发双方要依据同一个话题名称,才不会将信息错发给别人

Record:消息记录,就是生产者和消费者传递的信息内容,保存在指定的Topic中

Kafka的特征与优势

Kafka作为消息队列,它和其他同类产品相比,突出的特点就是性能强大

Kafka将消息队列中的信息保存在硬盘中

Kafka对硬盘的读取规则进行优化后,效率能够接近内存

硬盘的优化规则主要依靠"顺序读写,零拷贝,日志压缩等技术"

Kafka处理队列中数据的默认设置:

  • Kafka队列信息能够一直向硬盘中保存(理论上没有大小限制)
  • Kafka默认队列中的信息保存7天,可以配置这个时间,缩短这个时间可以减少Kafka的磁盘消耗

Kafka的安装和配置

必须将我们kafka软件的解压位置设置在一个根目录,文件夹名称尽量短(例如:kafka)

然后路径不要有空格和中文

我们要创建一个空目录用于保存Kafka运行过程中产生的数据

创建名称为data的空目录

kafka\config下配置有文件zookeeper.properties

找到dataDir属性修改如下

 F盘和data文件夹名称,匹配自己电脑的真实路径和文件夹名称

还要修改server.properties配置文件

修改注意事项和上面相同

启动kafka

要想启动Kafka必须先启动Zookeeper

Zookeeper介绍

zoo:动物园

keeper:园长

可以引申为管理动物的人

Linux服务器中安装的各种软件,很多都是有动物动物形象的

如果这些软件在Linux中需要修改配置信息的话,就需要进入这个软件,去修改配置,每个软件都需要单独修改配置的话,工作量很大

我们使用Zookeeper之后,可以创建一个新的管理各种软件配置的文件管理系统

在Zookeeper中,可以修改服务器系统中的所有软件配置

长此以往,很多软件就删除了自己写配置文件的功能,而直接从Zookeeper中获取

Kafka就是需要将配置编写在Zookeeper中的软件之一

Zookeeper启动

进入路径F:\kafka\bin\windows

输入cmd进入dos命令行

zookeeper-server-start.bat ..\..\config\zookeeper.properties

kafka启动

总体方式一样,输入不同指令

kafka-server-start.bat ..\..\config\server.properties

在启动kafka时有一个常见错误

wmic不是内部或外部命令

这样的提示,需要安装wmic命令,安装方式参考

我在cmd输入wmic,提示说不是内部或外部命令,也不是可运行的程序或批处理文件,请问如何解决_百度知道

Kafka使用演示

<!-- 使用Kafka 的依赖  -->
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>
<!--    能够将java对象和json字符串相互转换的依赖     -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

 修改yml文件进行配置

spring:
  kafka:
    # 定义kafka的配置信息,先配置kafka的位置
    bootstrap-servers: localhost:9092
    # consumer.group-id是必须配置的信息
    # 配置的名称是"话题分组",是为了区分其它项目的话题而定义的分组名称
    # 本质上在运行时,当前项目所有话题名称都会用csmall做前缀
    consumer:
      group-id: csmall

启动类加注解

// 启动支持Kafka功能
@EnableKafka
// 为了测试Kafka发送和接收消息的效果
// 我们利用SpringBoot自带的任务调度工具,周期的发送消息到Kafka
@EnableScheduling

// 周期性的向Kafka发送消息的类
// Producer实例化对象保存到Spring容器才能实现Springboot的周期调用
@Component
public class Producer {


    // 这个对象会在SpringBoot启动时,自动装配到Spring容器,能够操作Kafka发送消息
    // 需要时,从Spring容器中注入(获取)即可
    // KafkaTemplate<[话题的类型],[发送消息的类型]>
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;

    // 每隔10秒向kafka发送消息的方法
    int i=1;
    // 设置fixedRate周期运行,单位是毫秒 10000毫秒是10秒
    @Scheduled(fixedRate = 10000)
    // SpringBoot项目启动后,就会周期运行这个方法
    public void sendMessage(){
        //实例化一个CartTb对象,当做消息发送
        CartTb cart=new CartTb();
        cart.setId(i++);
        cart.setCommodityCode("PC100");
        cart.setPrice(RandomUtils.nextInt(350)+50);
        cart.setCount(RandomUtils.nextInt(10)+1);
        cart.setUserId("UU100");
        // 我们可以利用Gson类型对象,将cart对象转换为json格式字符串
        Gson gson=new Gson();
        String json=gson.toJson(cart);
        System.out.println("本次发送的消息为:"+json);
        // 执行发送
        kafkaTemplate.send("myCart",json);
    }


}

创建一个叫Consumer的类来接收消息

接收消息的类可以是本模块的类,也可以是其它模块的类,编写的代码是完全一致 

// 因为Kafka接收消息的功能在SpringBoot中配置,所以当前类也必须保存在Spring容器中,才能生效
@Component
public class Consumer {

    // SpringKafka接收消息依靠的是一个监听机制
    // SpringKafka提供一个监听线程,实时关注Kafka的消息往来
    // 如果有消息使用指定的话题名称(myCart)发送到kafka,就会自动调用下面的方法
    @KafkaListener(topics = "myCart")
    // 下面的方法会在kafka中出现话题名称为myCart时运行,而且方法的参数就是消息对象
    public void received(ConsumerRecord<String,String> record){
        // 方法参数类型必须是ConsumerRecord
        // ConsumerRecord<[话题类型],[消息类型]>
        // record就是消息本身,下面获得具体的值
        String json=record.value();
        // 将json格式字符串转换为java对象
        Gson gson=new Gson();
        // 执行转换时,还有额外指定转换目标类型的反射
        CartTb cart=gson.fromJson(json,CartTb.class);
        System.out.println("接收到消息:"+cart);

    }

}

RabbitMQ

什么是RabbitMQ

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。 AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。 RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

RabbitMQ特征

1.可靠性(Reliability) RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。

2.灵活的路由(Flexible Routing) 在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能,RabbitMQ已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。

3.消息集群(Clustering) 多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker

4.高可用(Highly Available Queues) 队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。

5.多种协议(Multi-protocol) RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。

6.多语言客户端(Many Clients) RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等等。

7.管理界面(Management UI) RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。

8.跟踪机制(Tracing) 如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。

9.插件机制(Plugin System) RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。

下载软件

RabbitMQ是Erlang语言开发的,所以要先安装Erlang语言的运行环境

下载Erlang的官方路径

OTP Versions Tree

安装的话就是双击

安装过程中都可以使用默认设置,需要注意的是

不要安装在中文路径和有空格的路径下!!!

下载RabbitMQ的官方网址

Installing on Windows — RabbitMQ

安装也是双击即可

不要安装在中文路径和有空格的路径下!!!

RabbitMQ的结构

RabbitMQ软件支持很多种消息队列的发送方式的

使用的比较多的是路由模式

和Kafka不同,Kafka是使用话题名称来收发信息,结构简单

RabbitMQ是使用交换机\路由key指定要发送消息的队列

消息的发送者发送消息时,需要指定交换机和路由key名称

消息的接收方接收消息时,只需要指定队列的名称

在编写代码上,相比于Kafka,每个业务要编写一个配置类

这个配置类中要绑定交换机和路由key的关系,以及路由Key和队列的关系

 

配置Erlang的环境变量

要想运行RabbitMQ必须保证系统有Erlang的环境变量

配置Erlang环境变量

把安装Erlang的bin目录配置在环境变量Path的属性中

 

启动RabbitMQ

找到RabbitMQ的安装目录

可能是:

F:\tools\rabbit\rabbitmq_server-3.10.1\sbin

具体路径根据自己的情况寻找

地址栏运行cmd

输入启动指令如下

F:\tools\rabbit\rabbitmq_server-3.10.1\sbin>rabbitmq-plugins enable rabbitmq_management

结果如下

运行完成后

可以在Window任务管理器中的服务选项卡里找到RabbitMQ的服务(Ctrl+Shift+ESC)

另外的验证方法:

因为RabbitMQ自带一个管理的界面,所以我们可以访问这个界面来验证它的运行状态

http://localhost:15672

登录界面用户名密码

guest

guest

登录成功后看到RabbitMQ运行的状态

如果启动失败,需要重新安装

参考路径如下 

百度安全验证

利用RabbitMQ完成消息的收发

csmall-stock-webapi项目中测试RabbitMQ

可以利用之前我们使用Quartz实现的每隔一段时间输出当前日期信息的方法改为发送消息

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

yml文件配置

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

交换机\路由Key\队列的配置类

RabbitMQ要求我们在java代码级别设置交换机\路由Key\队列的关系

包中创建配置信息类

// 这个类是配置RabbitMQ中交换机路由key和队列的配置类
// 其中交换机和队列是实际的对象,需要保存到Spring容器,而路由Key是绑定关系
@Configuration
public class RabbitMQConfig {
    // 使用常量定义交换机路由Key和队列的名称
    public static final String STOCK_EX="stock_ex";
    public static final String STOCK_ROUT="stock_rout";
    public static final String STOCK_QUEUE="stock_queue";

    // 声明交换机对象,保存到Spring容器
    // 根据实际需求生成交换机的数量,这里就是一个
    @Bean
    public DirectExchange stockDirectExchange(){
        return new DirectExchange(STOCK_EX);
    }

    // 声明队列对象,保存到Spring容器
    @Bean
    public Queue stockQueue(){
        return new Queue(STOCK_QUEUE);
    }
    // 声明路由Key的关系绑定,路由Key不是实际对象,本质上是一个记录关系的对象
    // 它记录了哪个交换机和哪个队列的关系
    @Bean
    public Binding stockBinding(){
        return BindingBuilder.bind(stockQueue()).to(stockDirectExchange()).with(STOCK_ROUT);
    }


}

RabbitMQ发送消息

在QuartzJob类中输出时间的代码后继续编写代码

实现RabbitMQ消息的发送

public class QuartzJob implements Job {

    // RabbitTemplate就是amqp协议框架提供的发送消息的对象
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 输出当前时间
        System.out.println("--------------"+ LocalDateTime.now()+"---------------");
        // 先简单的发送一个字符串
        // convertAndSend([交换机名称],[路由Key名称],[要发送的消息])
        rabbitTemplate.convertAndSend(RabbitMQConfig.STOCK_EX,
                RabbitMQConfig.STOCK_ROUT,"消息:执行减少库存的操作");
    }
}

接收RabbitMQ的消息 

// 当前类也要实例化对象保存到Spring容器才能实现监听效果
@Component
// 和Kafka不同,RabbitMQ的监听器注解编写在类上
@RabbitListener(queues = {RabbitMQConfig.STOCK_QUEUE})
public class RabbitMQConsumer {

    // 在类上编写监听,但是运行的也一定是个方法
    // 所以我们需要使用下面注解标记这个方法,让队列有消息时运行这个方法
    // 一个类只能有一个方法标记这个注解
    // 这个方法直接声明参数,就是消息的值,支持Object类型
    @RabbitHandler
    public void process(String str){
        System.out.println("消息的接收者看到消息:"+str);
    }


}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值