RabbitMQ简介与应用

本文深入解析RabbitMQ的特点与优势,涵盖其在金融领域的应用背景,详细阐述消息队列的基本概念,如Exchange、Queue、Routing等。并通过Java实例演示如何搭建与使用RabbitMQ,包括消息的发布与订阅流程。同时,介绍了Spring框架下RabbitMQ的整合实践,展示了消息生产与消费的高效处理方式。

1、RabbitMQ简介

(1)RabbitMQ特点:

RabbitMQ是一个由ERlang语言开发的基于AMQP(高级消息队列协议)标准的消息队列开源实现。RabbitMQ最初起源于金融系统,用于分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面有很好的表现。主要特点包括:

  • 可靠性:RabbitMQ支持持久化、传输确认、发布确认等
  • 灵活的路由功能:在消息进入队列之前,通过Exchange交换机来实现灵活路由。
  • 支持消息集群:多态RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。
  • 高可用性:队列可以在集群中镜像,实现高可用。
  • 支持多种协议:如AMQP、STOMP、MQTT等。
  • 支持多语言客户端:如java、.NET、Ruby等
  • 提供管理界面:便于监控和管理连接、交换机、队列等信息
  • 提供插件机制:方便扩展。
(2)RabbitMQ基本概念

RabbitMQ整体结构如图:
在这里插入图片描述

  • Message(消息):消息由消息头和消息体组成,消息包括routing-key(路由键)、priority(优先级)、delivery-mode(持久化存储)等属性。
  • Publisher(消息发布者):向交换机发布消息的客户端程序。
  • Exchange(交换器):用来接收消息发布者发送到的消息,并将消息路由给服务器中的队列
  • Binding(绑定):一个绑定就是基于路由键将交换器与消息队列连接起来的路由规则。
  • Queue(消息队列):是消息的容器,又来保存消息直到消息被发送到消费者。一个消息可以被投入到一个或多个队列中。
  • Connection(网络连接):比如一个TCP连接。
  • Channel(信道):多路复用连接中的一条独立的双向数据流通道,信道是建立在真实的TCP连接里面的虚拟连接,AMQP命令通过信道发送。
  • Consumer(消息消费者):从消息队列取消息的客户端程序。
  • Virtual Host(虚拟主机):表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。RabbitMQ默认的vhost是"/"。
  • Broker(消息队列服务器实体)
(3)AMQP消息路由

相比于JMS,AMQP的路由加入了Exchange和Binding两个角色。消息由消息生产者发送到交换器,Binding再决定交换器中的消息应发送到哪个队列。
交换器类型
不同的交换器分发消息的策略也不同。交换器有4中类型:Direct、Fanout、Topic、Headers。

  • Headers交换器:不处理路由键,匹配消息的Header。几乎不用。
  • Fanout交换器:不处理路由键,只是简单地将队列绑定到交换器,发送交换器中的消息时会发送到所有绑定的队列中。通过该类型交换器转发消息是最快的。
  • Direct交换器:如果消息中的路由键和Binding中的绑定键完全一致,则发送到对应的队列中。比如dog只匹配dog,不匹配dog.black
  • Topic交换器:最灵活的交换器。将路由键和绑定的字符串切分成单词,单词间用".“隔开,识别两个通配符:”*":匹配一个单词,“#”:匹配0个或多个单词。

2、RabbitMQ应用实例

下面是一个在java中使用RabbitMQ的例子:
下载安装Erlang
下载安装RabbitMQ服务
启动RabbitMQ服务
创建java工程
在Maven工程中添加依赖:

	<dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>4.1.0</version>
    </dependency>

消息生产者:

package com.youzi.rabbitMQ.amqp;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        //设置rabbitmq地址
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        //建立到代理服务器的连接
        Connection conn = factory.newConnection();
        //创建信道
        Channel channel = conn.createChannel();
        //声明交换器
        String exchangeName = "helloexchange";
        channel.exchangeDeclare(exchangeName,"direct",true);
        String routingKey = "testRoutingKey";
        //发布消息
        byte[] messageBytes = "hello rabbitmq!!".getBytes();
        channel.basicPublish(exchangeName,routingKey,null,messageBytes);
        //关闭信道和连接
        channel.close();
        conn.close();

    }
}

消息消费者:

package com.youzi.rabbitMQ.amqp;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        //设置rabbitmq地址
        factory.setHost("localhost");
        factory.setVirtualHost("/");
        //建立到代理服务器的连接
        Connection conn = factory.newConnection();
        //创建信道
        final Channel channel = conn.createChannel();
        //声明交换器
        String exchangeName = "helloexchange";
        channel.exchangeDeclare(exchangeName,"direct",true);
        //声明队列
        String queueName = channel.queueDeclare().getQueue();
        String RoutingKey = "testRoutingKey";
        //绑定路由键
        channel.queueBind(queueName,exchangeName,RoutingKey);
        while (true){
            //消费消息
            boolean autoAck = false;
            String consumerTag = "";
            channel.basicConsume(queueName,autoAck,consumerTag,new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope,
                                           AMQP.BasicProperties properties,byte[] body) throws IOException {
                    String routingKey = envelope.getRoutingKey();
                    String contentType = properties.getContentType();
                    System.out.println("消费路由键:"+routingKey);
                    System.out.println("消息内容的类型:"+contentType);
                    long deliveryTag = envelope.getDeliveryTag();
                    //确认消息
                    channel.basicAck(deliveryTag,false);
                    String bodyStr = new String(body,"UTF-8");
                    System.out.println("消费的消息体内容是:"+bodyStr);
                }
            });
        }
    }
}

先运行Consumer、在运行Producer,Consumer控制台打印消息:
在这里插入图片描述

3、Sring整合RabbitMQ应用实例

一个消息生产者生产50条消息,每条间隔时间一秒,两个消息消费者监听一个队列。
添加依赖:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <!-- spring版本号 -->
    <spring.version>4.1.3.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- Spring -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.amqp</groupId>
      <artifactId>spring-rabbit</artifactId>
      <version>2.1.0.RELEASE</version>
    </dependency>

Spring配置文件spring-context:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/rabbit
       http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
	<!--这里配置了两个消息消费者-->
    <bean id="myMessageListener1" class="com.youzi.rabbitMQ.spring.MyMessageListener1"/>
    <bean id="myMessageListener2" class="com.youzi.rabbitMQ.spring.MyMessageListener2"/>
    <!--配置连接-->
    <rabbit:connection-factory id="connectionFactory" host="127.0.0.1" port="5672" username="guest" password="guest"
                               virtual-host="/" requested-heartbeat="60"/>
    <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter"/>
    <!-- 定义Rabbit模板,指定连接工厂以及定义exchange以及消息路由键 -->
    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="myExchange" routing-key="message.test"
                     message-converter="jsonMessageConverter" />
    <!--配置RabbitAdmin-->
    <rabbit:admin connection-factory="connectionFactory" />
    <!--配置队列名称-->
    <rabbit:queue name="myQueue"/>
    <!--配置交换器-->
    <rabbit:topic-exchange name="myExchange">
        <rabbit:bindings>
            <rabbit:binding queue="myQueue" pattern="message.*"/>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    <!--配置监听器-->
    <rabbit:listener-container connection-factory="connectionFactory">
        <rabbit:listener ref="myMessageListener1" queue-names="myQueue"/>
        <rabbit:listener ref="myMessageListener2" queue-names="myQueue"/>
    </rabbit:listener-container>
</beans>

消息pojo对象:

package com.youzi.rabbitMQ.spring;

public class Message {
    private int id;
    private String content;
	//getter、setter、toString
}

消息生产者:

package com.youzi.rabbitMQ.spring;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Producer {
    public static void main(String[] args) throws InterruptedException {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        RabbitTemplate template = ctx.getBean(RabbitTemplate.class);
        Message message = new Message();
        for(int i=1;i<=50;i++){
            message.setId(i);
            message.setContent("这是消息"+i);
            template.convertAndSend(message);
            Thread.sleep(1000);
        }
        ctx.close();
    }
}

两个消息消费者:

package com.youzi.rabbitMQ.spring;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;

public class MyMessageListener1 implements MessageListener {
    @Override
    public void onMessage(Message message) {
        String body = new String(message.getBody());
        System.out.println("接收者1接收到消息:"+body);
    }
}
package com.youzi.rabbitMQ.spring;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;

public class MyMessageListener2 implements MessageListener {
    @Override
    public void onMessage(Message message) {
        String body = new String(message.getBody());
        System.out.println("接受者2接收到消息:"+body);
    }
}

启动Producer,两个消费者监听器监听到队列中的消息,50条消息被均匀地分发到两个消费者:
在这里插入图片描述

总结:
RabbitMQ最大的优势就是灵活的路由策略,高可用,可靠性,适用于金融等高可用、可靠性需求大的领域,不过由于AMQP协议,导致RabbitMQ比较重量,吞吐量不及Kafka优秀。

标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差方差,增强整体预测的稳定性准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值