【SpringCloud微服务技术栈(中)-异步通信】

异步通信

初识MQ

同步通信与异步通信

在这里插入图片描述

  • 同步通信相当于打电话,打电话者与接电话者只能建立一条通信连接,并且消息发送过去必须要得到对方的回应才能知道消息已经被成功接收
  • 异步通信相当于发送微信,发送者与多个接收者建立多条通信连接,发送者只需要把消息发送过去即可,=并不需要得到对方的回应

同步通信的优缺点

[同步通信的优点]:即上面的时效通信
[同步通信的缺点]:
在这里插入图片描述

耦合度高:每次加入新的需求,都要修改原来的代码
性能下降:调用者需要等待服务提供者的响应,如果调用链过长则响应时间等于每次调用的时间之和
资源浪费:调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源
级联失败:如果服务提供者出现问题,所哟调用方都会跟着出问题,如同多米诺骨牌一样,迅速导致整个微服务群故障。

异步通信的优缺点

[异步通信的优点]:
在这里插入图片描述

优势一:服务解耦
服务消费者(支付服务)只需要将请求(订单完成事件)发送给Broker即可,而Broker需要广播请求到来了(订单完成事件来了),此时服务消费者的工作就完成了,而其他服务提供者只要向Broker订阅事件就行了(获取请求),==这样做到了服务消费者与提供者解耦的操作,因此当我们想要添加或者删除一个服务时只要简单地让服务取消或加入订阅Broker即可,并不需要改代码

在这里插入图片描述

优势二:性能提升,吞吐量提高
服务提消费者不需要再等待服务提供者了,大大提高了性能

在这里插入图片描述

优势三:服务没有强依赖,不担心级联失败问题
服务消费者与提供者没有关系了,就算服务提供者出现问题了也不会影响到服务消费者

在这里插入图片描述

优势四:流量削峰
当请求量过大,Broker起到了缓冲地作用,将请求缓存起来

[异步通信的缺点]:

依赖于Broker的可靠性、安全性、吞吐能力
架构复杂了,业务没有明显的流程线了,不好追踪管理

MQ常见技术介绍

MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列.也就是事件驱动架构中的Broker
在这里插入图片描述

RabbitMQ

介绍与安装

RabbitMQ是基于Erlang语言开发的开源消息通信中间件,官网地址:https://www.rabbitmq.com/

[安装]:
方式一:在线拉取
在这里插入图片描述
方式二:从本地下载

  • 将已有的安装包上传(拖到)到虚拟机后,使用命令加载镜像即可:
    在这里插入图片描述
  • 安装MQ,执行下面的命令来运行MQ容器:
    在这里插入图片描述

界面:
在这里插入图片描述
在这里插入图片描述

[RabbitMQ的结构概述]:
在这里插入图片描述

消息模型介绍

在这里插入图片描述

简单队列模型

[案例]:HelloWorld案例
在这里插入图片描述

[实现]:
导入项目工程mq-demo
在这里插入图片描述

代码说明:
PublicerTest代码:可以看到Consumer发送完消息后就把连接和通道关闭了,这充分说明解耦合
在这里插入图片描述在这里插入图片描述在这里插入图片描述

PublicerTest代码执行后RabbitMQ界面会发生变化:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ConsumerTest代码说明:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

RibbitMQ界面
在这里插入图片描述

SpringAMQP

基本介绍

可见上面消息的发送和接收有点麻烦,而SpringAMQP大大简化了上面的开发.

[AMQP与Spring AMQP]:
在这里插入图片描述
在这里插入图片描述
Spring AMQP的官方网站:https://spring.io/projects/spring-amqp

[Spring AMQP的特征]:

  • 侦听器容器,用于异步处理入站消息
  • 用于发送和接收消息的RabbitTemplate
  • RabbitAdmin用于自动声明队列,交换和绑定

入门案例的消息发送与接收

[案例]:利用SpringAMQP实现HelloWorld中的基础消息队列功能

[消息发送步骤实现]:

  • 在父工程中引入spring-amqp的依赖
    在这里插入图片描述
  • 在publisher服务中利用RabbitTemplate发送消息到simple-queue这个队列(向消息队列发送完消息后,RabbitMQP相应界面会有记录)
    在这里插入图片描述

[消息接收步骤实现]:

  • 在consumer服务中编写消费逻辑,绑定simple.queue这个队列
    在这里插入图片描述
    在这里插入图片描述

WorkQueue模型

[工作模型]:
在这里插入图片描述

[案例]:模拟WorkQueue,实现一个队列绑定多个消费者
在这里插入图片描述

[实现步骤]:
Publicer实现一秒循环发送五十条消息的代码:
在这里插入图片描述

Consunmer中实现两个消费者共同接收消息(消费者1每秒接收50条,消费者2每秒处理10条)
在这里插入图片描述
发现两个消费者处理的消息条数是一样的,只是处理的总时间不同,并没有达到能者多劳的目的,这是因为RabbitMQP有个预取机制,消费者会提前把消息平均(你一个我一个)拿过来存着,不管我是否消费完了, 我们可以通过改配置取消这个机制,==修改Consumer的application.yml文件,设置preFetch这个值,可以通过控制预取消息的上限:
在这里插入图片描述

发布订阅模型介绍

之前的简单那模型与WorkQueue模型的特点是一个消息只能给一个消费者,消费完后这个消息就会消失;而发布订阅模式与之前的案例的区别就是允许将同一个消息发送给多个消费(比如订单消息需要发送给订单服务、仓储服务等等一起处理).实现方式就是加入了exchange(交换机,常见的类型有 广播[FanoutExchange]路由[Direct Exchange]话题[TopicExchange])
在这里插入图片描述

注意:exchange负责消息路由,而不是存储,路由失败则消息丢失

FanoutExchange

[工作模型]:FanoutExchange会将接收到的消息路由到每一个跟其绑定的queue
在这里插入图片描述

[案例]:利用SpringAMQP演示FanoutExchange的使用
在这里插入图片描述

[实现步骤]:
步骤一:
在consumer服务声明Exchange(交换机API)、Queue(消息队列API)、Binding(绑定关系API)

SpringAMQP提供了声明交换机、队列、绑定关系的API,例如:
在这里插入图片描述

在consumer服务创建一个类,添加@Configuration注解,并声明FanoutExchange、Queue和绑定关系对象Binding,目录和代码如下:
在这里插入图片描述
在这里插入图片描述

RabbitMQP记录图:
在这里插入图片描述
在这里插入图片描述

步骤二:
编写消费者consumer接收代码:
在这里插入图片描述

步骤三:
编写提供者publicer发送代码:
在这里插入图片描述

[结果]:发现消息一次发送消费者全部接收到了
在这里插入图片描述

DirectExchange

[工作模型]:DirectExchange会将接收到的消息根据规则路由到指定的queue,因此称为路由模式(routes)
在这里插入图片描述

[案例]:利用SpringAMQP演示DirectExchange的使用
在这里插入图片描述

[实现步骤]:
步骤一:在consumer服务声明Exchange、Queue和RoutingKey
在这里插入图片描述

步骤二:在publicer服务中发送消息,并指定routingKey
在这里插入图片描述

TopicExchange

[工作模型]:TopicExchange与Direct Exchange类似,区别在于routingKEY必须是多个单词的列表,并且以==.==分割
在这里插入图片描述

[案例]:利用SpringAMQP演示TopicExchange的使用
在这里插入图片描述

[实现步骤]:
consumer服务代码:
在这里插入图片描述

publicer服务代码:
在这里插入图片描述

消息转换器

[现象]:在SpringAMQP的发送方法中,发送消息的类型是Object,也就是说我们可以发送任意对象类型的消息,SpringAMQP会帮我们序列化为字节后发送.

[测试]:我们在publicer服务中发送一个Map<string,Object>的集合对象消息到队列
在这里插入图片描述

我们在RabbitMQP中发现队列中的Map类型的消息被序列化成了一串长字符,这样会影响消息传递的时间与效率
在这里插入图片描述

为publicer服务添加小组件"消息转换器"
在这里插入图片描述

RibbitMQP中的消息结果:
在这里插入图片描述

为consumer服务也添加小组件"消息转换器"
在这里插入图片描述

elasticsearch(ES)

认识

elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到所需的内容.
elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK).被广泛应用在日志数据分析、实时监控等领域.====
elasticsearch是elastic stack的核心,负责存储、搜索、分析数据,其官网地址为https://www.elastic.co/cn/.其底层实现是基于Lucene,而Lucene的核心技术是倒排索引
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

倒排索引

[正向索引]:
传统数据库(如MySQL)采用正向索引,例如给下表(tb_goods)中的id创建索引(提高查询速度而对表字段附加的一种标识),我们可以知道通过id查询数据,在id上创建的索引能帮助我们很快定位到数据,但是我们要想通过title字段中的某一部分查询(比如小米手机中的手机字段),此时索引不仅无法建立而且还得一条条数据查询,导致查询效率十分低下:
在这里插入图片描述

[倒排索引]:
elasticsearch采用倒排索引:

  • 文档:每条数据就是文档(数据中包括许多的数据元素,比如第一条数据就包括id:1、title:小米手机、price:3499)
  • 词条:文档中的数据元素按照语义分成的词语

在这里插入图片描述
在这里插入图片描述

es与mysql的概念对比

[es]:

  • elasticsearch是面向文档存储的,可以是数据库中的一条商品信息,一个订单信息. 文档数据会被序列化为json格式后存储在elasticsearch中.
    在这里插入图片描述
  • 索引:相同类型的文档的集合
  • 映射:索引中文档的字段约束信息,类似表的结构约束(比如id必须使用整型)

[es与mysql的概念对比]:
在这里插入图片描述

[架构]:es和mysql是互补的,整体架构如下
在这里插入图片描述

安装es

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[安装好浏览器访问]:
在这里插入图片描述

安装kibana

[安装部署]:
在这里插入图片描述
[安装好的界面展示]:
在这里插入图片描述

[kibana为es提供的DSL编写工具Dev Tools]:
在这里插入图片描述

安装IK分词器

es在创建倒排索引时需要对文档分词;在搜索的时候,需要对用户输入内容分词.但是默认的分词规则对中文处理并不友好.我们可以在kibana的DevTools中测试:
在这里插入图片描述
在这里插入图片描述
所以我们要安装中文分词器IK分词器,官网https://github.com/medcl/elasticsearch-analysis-ik

[安装方式以及流程]:
方式一:
在这里插入图片描述

方式二:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

IK分词器的扩展和停用词典

分词器的底层肯定有一个词典供分词的时候查询,由于我们日常使用的词语会更新或者有些词没有必要分出来,这是我们就需要为词典提供个性化设置

在这里插入图片描述
在这里插入图片描述

[步骤]:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
操作索引库

操作索引库 -mapping属性

在这里插入图片描述

操作索引库 -创建索引库

在这里插入图片描述
在这里插入图片描述

操作索引库 -查询、删除、修改索引库

在这里插入图片描述
在这里插入图片描述

文档操作 -新增、查询、删除文档

[添加文档]:
在这里插入图片描述

[查询文档]:
在这里插入图片描述

[删除文档]:
在这里插入图片描述

文档操作 -修改文档

在这里插入图片描述

RestClient

RestClient操作索引库-导入demo

ES官方提供了各种不同语言的客户端,用来操作ES.这些客户端的本质就是组装DSL语句,通过http请求发送给ES.官方文档地址为:http://www.elastic.co/guide/en/elasticsearch/client/index.html

[案例]:利用JavaRestClient实现创建、删除索引库,判断索引库是否存在.
在这里插入图片描述

[步骤]:
步骤一:导入数据库tb_hotel.sql
在这里插入图片描述

步骤二:导入项目hotel-demo
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

RestClient操作索引库-hotel数据结构分析

[数据结构分析]:
根据数据库表创建出相应的映射索引库

在这里插入图片描述

RestClient操作索引库-初始化RestClient

[步骤]:
步骤一:在项目hotel-demo的pom.xml引入es的RestHighLevelClient依赖:
在这里插入图片描述
步骤二:因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本,在hotel-demo的pom.xml文件中加入:
在这里插入图片描述
步骤三:初始化RestHighLevelClient
在这里插入图片描述
在这里插入图片描述

RestClient操作索引库-创建索引库

可以在测试类中写入如下代码创建索引库,为了方便理解,这里和DSL语句进行对比,其中里面的静态常量MAPPING_TEMPLATE指的就是DSL语句,为了避免代码冗余,这里可以在另一个类中定义静态常量,并把DSL语句赋值给它,后面就可以调用了在这里插入图片描述

RestClient操作索引库-删除和判断索引库

[删除索引库]:
在这里插入图片描述
[判断索引库是否存在]:
在这里插入图片描述

RestClient操作文档-新增文档

[案例]:从数据库中读取一条hotel数据,并将它添加到索引库,模板代码如下在这里插入图片描述
但是根据具体情况还需要更改:
由于数据库读出来的Hotel实体类的经纬度包括longitude(维度)和latitude(经度)两个属性 [见图一],但是索引库创建映射的时候只有location一个属性 [见图二],这样将Hotel实体类放入索引库显然不合适==,所以我们要创建另一个实体类HotelDoc来将Hotel来转换 [见图三]

在这里插入图片描述在这里插入图片描述在这里插入图片描述
最终的实际代码效果:
在这里插入图片描述

RestClient操作文档-查询文档

在这里插入图片描述
在这里插入图片描述

RestClient操作文档-更新文档

修改文档数据有两种方式:
方式一:全量更新.再次写入id一样的文档,就会删除旧文档,添加新文档
方式二:局部更新.之更新部分字段,我们只演示方式二
在这里插入图片描述
在这里插入图片描述

RestClient操作文档-删除文档

在这里插入图片描述

RestClient操作文档-批量导入文档

在这里插入图片描述

SpringCloud微服务技术栈(下)-分布式搜索

SpringCloud微服务技术栈(下)-分布式搜索

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值