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

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

  • 异步通信
    • 初识MQ
      • 同步通信与异步通信
      • 同步通信的优缺点
      • 异步通信的优缺点
      • MQ常见技术介绍
    • RabbitMQ
      • 介绍与安装
      • 消息模型介绍
      • 简单队列模型
    • SpringAMQP
      • 基本介绍
      • 入门案例的消息发送与接收
      • WorkQueue模型
      • 发布订阅模型介绍
      • FanoutExchange
      • DirectExchange
      • TopicExchange
      • 消息转换器
    • elasticsearch(ES)
      • 认识
      • 倒排索引
      • es与mysql的概念对比
      • 安装es
      • 安装kibana
      • 安装IK分词器
      • IK分词器的扩展和停用词典
      • 操作索引库 -mapping属性
      • 操作索引库 -创建索引库
      • 操作索引库 -查询、删除、修改索引库
      • 文档操作 -新增、查询、删除文档
      • 文档操作 -修改文档
    • RestClient
      • RestClient操作索引库-导入demo
      • RestClient操作索引库-hotel数据结构分析
      • RestClient操作索引库-初始化RestClient
      • RestClient操作索引库-创建索引库
      • RestClient操作索引库-删除和判断索引库
      • RestClient操作文档-新增文档
      • RestClient操作文档-查询文档
      • RestClient操作文档-更新文档
      • RestClient操作文档-删除文档
      • RestClient操作文档-批量导入文档
  • SpringCloud微服务技术栈(下)-分布式搜索

异步通信

初识MQ

同步通信与异步通信

【SpringCloud微服务技术栈(中)-异步通信】_第1张图片

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

同步通信的优缺点

[同步通信的优点]:即上面的时效通信
[同步通信的缺点]:
【SpringCloud微服务技术栈(中)-异步通信】_第2张图片

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

异步通信的优缺点

[异步通信的优点]:
【SpringCloud微服务技术栈(中)-异步通信】_第3张图片

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

【SpringCloud微服务技术栈(中)-异步通信】_第4张图片

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

【SpringCloud微服务技术栈(中)-异步通信】_第5张图片

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

【SpringCloud微服务技术栈(中)-异步通信】_第6张图片

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

[异步通信的缺点]:

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

MQ常见技术介绍

MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列.也就是事件驱动架构中的Broker
【SpringCloud微服务技术栈(中)-异步通信】_第7张图片

RabbitMQ

介绍与安装

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

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

  • 将已有的安装包上传(拖到)到虚拟机后,使用命令加载镜像即可:
    在这里插入图片描述
  • 安装MQ,执行下面的命令来运行MQ容器:
    【SpringCloud微服务技术栈(中)-异步通信】_第8张图片

界面:
【SpringCloud微服务技术栈(中)-异步通信】_第9张图片
【SpringCloud微服务技术栈(中)-异步通信】_第10张图片

[RabbitMQ的结构概述]:
【SpringCloud微服务技术栈(中)-异步通信】_第11张图片

消息模型介绍

【SpringCloud微服务技术栈(中)-异步通信】_第12张图片

简单队列模型

[案例]:HelloWorld案例
【SpringCloud微服务技术栈(中)-异步通信】_第13张图片

[实现]:
导入项目工程mq-demo
【SpringCloud微服务技术栈(中)-异步通信】_第14张图片

代码说明:
PublicerTest代码:可以看到Consumer发送完消息后就把连接和通道关闭了,这充分说明解耦合
【SpringCloud微服务技术栈(中)-异步通信】_第15张图片在这里插入图片描述【SpringCloud微服务技术栈(中)-异步通信】_第16张图片

PublicerTest代码执行后RabbitMQ界面会发生变化:
【SpringCloud微服务技术栈(中)-异步通信】_第17张图片
【SpringCloud微服务技术栈(中)-异步通信】_第18张图片
【SpringCloud微服务技术栈(中)-异步通信】_第19张图片
【SpringCloud微服务技术栈(中)-异步通信】_第20张图片

ConsumerTest代码说明:
【SpringCloud微服务技术栈(中)-异步通信】_第21张图片在这里插入图片描述【SpringCloud微服务技术栈(中)-异步通信】_第22张图片

RibbitMQ界面
【SpringCloud微服务技术栈(中)-异步通信】_第23张图片

SpringAMQP

基本介绍

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

[AMQP与Spring AMQP]:
【SpringCloud微服务技术栈(中)-异步通信】_第24张图片
【SpringCloud微服务技术栈(中)-异步通信】_第25张图片
Spring AMQP的官方网站:https://spring.io/projects/spring-amqp

[Spring AMQP的特征]:

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

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

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

[消息发送步骤实现]:

  • 在父工程中引入spring-amqp的依赖
    【SpringCloud微服务技术栈(中)-异步通信】_第26张图片
  • 在publisher服务中利用RabbitTemplate发送消息到simple-queue这个队列(向消息队列发送完消息后,RabbitMQP相应界面会有记录)
    【SpringCloud微服务技术栈(中)-异步通信】_第27张图片

[消息接收步骤实现]:

  • 在consumer服务中编写消费逻辑,绑定simple.queue这个队列
    【SpringCloud微服务技术栈(中)-异步通信】_第28张图片
    【SpringCloud微服务技术栈(中)-异步通信】_第29张图片

WorkQueue模型

[工作模型]:
【SpringCloud微服务技术栈(中)-异步通信】_第30张图片

[案例]:模拟WorkQueue,实现一个队列绑定多个消费者
【SpringCloud微服务技术栈(中)-异步通信】_第31张图片

[实现步骤]:
Publicer实现一秒循环发送五十条消息的代码:
【SpringCloud微服务技术栈(中)-异步通信】_第32张图片

Consunmer中实现两个消费者共同接收消息(消费者1每秒接收50条,消费者2每秒处理10条)
【SpringCloud微服务技术栈(中)-异步通信】_第33张图片
发现两个消费者处理的消息条数是一样的,只是处理的总时间不同,并没有达到能者多劳的目的,这是因为RabbitMQP有个预取机制,消费者会提前把消息平均(你一个我一个)拿过来存着,不管我是否消费完了, 我们可以通过改配置取消这个机制,==修改Consumer的application.yml文件,设置preFetch这个值,可以通过控制预取消息的上限:
【SpringCloud微服务技术栈(中)-异步通信】_第34张图片

发布订阅模型介绍

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

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

FanoutExchange

[工作模型]:FanoutExchange会将接收到的消息路由到每一个跟其绑定的queue
【SpringCloud微服务技术栈(中)-异步通信】_第36张图片

[案例]:利用SpringAMQP演示FanoutExchange的使用
【SpringCloud微服务技术栈(中)-异步通信】_第37张图片

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

SpringAMQP提供了声明交换机、队列、绑定关系的API,例如:
【SpringCloud微服务技术栈(中)-异步通信】_第38张图片

在consumer服务创建一个类,添加@Configuration注解,并声明FanoutExchange、Queue和绑定关系对象Binding,目录和代码如下:
【SpringCloud微服务技术栈(中)-异步通信】_第39张图片
【SpringCloud微服务技术栈(中)-异步通信】_第40张图片

RabbitMQP记录图:
【SpringCloud微服务技术栈(中)-异步通信】_第41张图片
【SpringCloud微服务技术栈(中)-异步通信】_第42张图片

步骤二:
编写消费者consumer接收代码:
【SpringCloud微服务技术栈(中)-异步通信】_第43张图片

步骤三:
编写提供者publicer发送代码:
【SpringCloud微服务技术栈(中)-异步通信】_第44张图片

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

DirectExchange

[工作模型]:DirectExchange会将接收到的消息根据规则路由到指定的queue,因此称为路由模式(routes)
【SpringCloud微服务技术栈(中)-异步通信】_第45张图片

[案例]:利用SpringAMQP演示DirectExchange的使用
【SpringCloud微服务技术栈(中)-异步通信】_第46张图片

[实现步骤]:
步骤一:在consumer服务声明Exchange、Queue和RoutingKey
【SpringCloud微服务技术栈(中)-异步通信】_第47张图片

步骤二:在publicer服务中发送消息,并指定routingKey
【SpringCloud微服务技术栈(中)-异步通信】_第48张图片

TopicExchange

[工作模型]:TopicExchange与Direct Exchange类似,区别在于routingKEY必须是多个单词的列表,并且以==.==分割
【SpringCloud微服务技术栈(中)-异步通信】_第49张图片

[案例]:利用SpringAMQP演示TopicExchange的使用
【SpringCloud微服务技术栈(中)-异步通信】_第50张图片

[实现步骤]:
consumer服务代码:
【SpringCloud微服务技术栈(中)-异步通信】_第51张图片

publicer服务代码:
【SpringCloud微服务技术栈(中)-异步通信】_第52张图片

消息转换器

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

[测试]:我们在publicer服务中发送一个Map的集合对象消息到队列
【SpringCloud微服务技术栈(中)-异步通信】_第53张图片

我们在RabbitMQP中发现队列中的Map类型的消息被序列化成了一串长字符,这样会影响消息传递的时间与效率
【SpringCloud微服务技术栈(中)-异步通信】_第54张图片

为publicer服务添加小组件"消息转换器"
【SpringCloud微服务技术栈(中)-异步通信】_第55张图片

RibbitMQP中的消息结果:
【SpringCloud微服务技术栈(中)-异步通信】_第56张图片

为consumer服务也添加小组件"消息转换器"
【SpringCloud微服务技术栈(中)-异步通信】_第57张图片

elasticsearch(ES)

认识

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

倒排索引

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

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

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

【SpringCloud微服务技术栈(中)-异步通信】_第62张图片
【SpringCloud微服务技术栈(中)-异步通信】_第63张图片

es与mysql的概念对比

[es]:

  • elasticsearch是面向文档存储的,可以是数据库中的一条商品信息,一个订单信息. 文档数据会被序列化为json格式后存储在elasticsearch中.
    【SpringCloud微服务技术栈(中)-异步通信】_第64张图片
  • 索引:相同类型的文档的集合
  • 映射:索引中文档的字段约束信息,类似表的结构约束(比如id必须使用整型)
    【SpringCloud微服务技术栈(中)-异步通信】_第65张图片

[es与mysql的概念对比]:
【SpringCloud微服务技术栈(中)-异步通信】_第66张图片

[架构]:es和mysql是互补的,整体架构如下
【SpringCloud微服务技术栈(中)-异步通信】_第67张图片

安装es

在这里插入图片描述
【SpringCloud微服务技术栈(中)-异步通信】_第68张图片
【SpringCloud微服务技术栈(中)-异步通信】_第69张图片

[安装好浏览器访问]:
【SpringCloud微服务技术栈(中)-异步通信】_第70张图片

安装kibana

[安装部署]:
【SpringCloud微服务技术栈(中)-异步通信】_第71张图片
[安装好的界面展示]:
【SpringCloud微服务技术栈(中)-异步通信】_第72张图片

[kibana为es提供的DSL编写工具Dev Tools]:
【SpringCloud微服务技术栈(中)-异步通信】_第73张图片

安装IK分词器

es在创建倒排索引时需要对文档分词;在搜索的时候,需要对用户输入内容分词.但是默认的分词规则对中文处理并不友好.我们可以在kibana的DevTools中测试:
【SpringCloud微服务技术栈(中)-异步通信】_第74张图片
【SpringCloud微服务技术栈(中)-异步通信】_第75张图片
所以我们要安装中文分词器IK分词器,官网https://github.com/medcl/elasticsearch-analysis-ik

[安装方式以及流程]:
方式一:
【SpringCloud微服务技术栈(中)-异步通信】_第76张图片

方式二:
【SpringCloud微服务技术栈(中)-异步通信】_第77张图片
【SpringCloud微服务技术栈(中)-异步通信】_第78张图片
【SpringCloud微服务技术栈(中)-异步通信】_第79张图片
【SpringCloud微服务技术栈(中)-异步通信】_第80张图片

【SpringCloud微服务技术栈(中)-异步通信】_第81张图片【SpringCloud微服务技术栈(中)-异步通信】_第82张图片

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

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

【SpringCloud微服务技术栈(中)-异步通信】_第83张图片
【SpringCloud微服务技术栈(中)-异步通信】_第84张图片

[步骤]:
【SpringCloud微服务技术栈(中)-异步通信】_第85张图片
【SpringCloud微服务技术栈(中)-异步通信】_第86张图片
【SpringCloud微服务技术栈(中)-异步通信】_第87张图片
操作索引库

操作索引库 -mapping属性

【SpringCloud微服务技术栈(中)-异步通信】_第88张图片

操作索引库 -创建索引库

【SpringCloud微服务技术栈(中)-异步通信】_第89张图片
【SpringCloud微服务技术栈(中)-异步通信】_第90张图片

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

【SpringCloud微服务技术栈(中)-异步通信】_第91张图片
【SpringCloud微服务技术栈(中)-异步通信】_第92张图片

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

[添加文档]:
【SpringCloud微服务技术栈(中)-异步通信】_第93张图片

[查询文档]:
【SpringCloud微服务技术栈(中)-异步通信】_第94张图片

[删除文档]:
【SpringCloud微服务技术栈(中)-异步通信】_第95张图片

文档操作 -修改文档

【SpringCloud微服务技术栈(中)-异步通信】_第96张图片

RestClient

RestClient操作索引库-导入demo

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

[案例]:利用JavaRestClient实现创建、删除索引库,判断索引库是否存在.
【SpringCloud微服务技术栈(中)-异步通信】_第97张图片

[步骤]:
步骤一:导入数据库tb_hotel.sql

步骤二:导入项目hotel-demo
【SpringCloud微服务技术栈(中)-异步通信】_第98张图片
【SpringCloud微服务技术栈(中)-异步通信】_第99张图片
【SpringCloud微服务技术栈(中)-异步通信】_第100张图片
【SpringCloud微服务技术栈(中)-异步通信】_第101张图片
【SpringCloud微服务技术栈(中)-异步通信】_第102张图片

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

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

【SpringCloud微服务技术栈(中)-异步通信】_第103张图片

RestClient操作索引库-初始化RestClient

[步骤]:
步骤一:在项目hotel-demo的pom.xml引入es的RestHighLevelClient依赖:
在这里插入图片描述
步骤二:因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本,在hotel-demo的pom.xml文件中加入:
在这里插入图片描述
步骤三:初始化RestHighLevelClient
在这里插入图片描述
【SpringCloud微服务技术栈(中)-异步通信】_第104张图片

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

可以在测试类中写入如下代码创建索引库,为了方便理解,这里和DSL语句进行对比,其中里面的静态常量MAPPING_TEMPLATE指的就是DSL语句,为了避免代码冗余,这里可以在另一个类中定义静态常量,并把DSL语句赋值给它,后面就可以调用了【SpringCloud微服务技术栈(中)-异步通信】_第105张图片

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

[删除索引库]:
【SpringCloud微服务技术栈(中)-异步通信】_第106张图片
[判断索引库是否存在]:
【SpringCloud微服务技术栈(中)-异步通信】_第107张图片

RestClient操作文档-新增文档

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

【SpringCloud微服务技术栈(中)-异步通信】_第109张图片【SpringCloud微服务技术栈(中)-异步通信】_第110张图片【SpringCloud微服务技术栈(中)-异步通信】_第111张图片
最终的实际代码效果:
【SpringCloud微服务技术栈(中)-异步通信】_第112张图片

RestClient操作文档-查询文档

【SpringCloud微服务技术栈(中)-异步通信】_第113张图片
【SpringCloud微服务技术栈(中)-异步通信】_第114张图片

RestClient操作文档-更新文档

修改文档数据有两种方式:
方式一:全量更新.再次写入id一样的文档,就会删除旧文档,添加新文档
方式二:局部更新.之更新部分字段,我们只演示方式二
【SpringCloud微服务技术栈(中)-异步通信】_第115张图片
【SpringCloud微服务技术栈(中)-异步通信】_第116张图片

RestClient操作文档-删除文档

在这里插入图片描述

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

【SpringCloud微服务技术栈(中)-异步通信】_第117张图片

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

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

你可能感兴趣的:(微服务,spring,cloud,java)