【SpringCloud】微服务技术栈入门8 - 黑马旅游微服务项目实战笔记

目录

    • 黑马旅游案例
      • 分页查询
      • 自动补全
        • 安装依赖
        • 自定义分词器
        • Completion Suggester
    • 聚合数据
      • 聚合的分类
      • Bucket 聚合
      • Metrix 聚合
      • RestClient 实现聚合
      • suggest 查询结果
    • 数据同步
      • 同步策略
      • mq 同步 es
      • es 搭设集群

黑马旅游案例


分页查询

前端页面以及对应请求接口已经设置完备,我们仅需据此添加对应的后端内容即可

首先设置请求接收的实体类

@Data
public class RequestParams {private String key;private Integer page;private Integer size;private String sortBy;
}

紧接着是返回给前端的响应类(字段名必须要和前端一致,否则你传递给前端的内容他不认)

@Data
public class PageResult {private Long total;private List<HotelDoc> hotels;public PageResult() {}public PageResult(Long total, List<HotelDoc> hotels) {this.total = total;this.hotels = hotels;}
}

新增查询的 controller

@RestController
@RequestMapping("/hotel")
public class HotelController {@Autowiredprivate IHotelService hotelService;@PostMapping("/list")PageResult search(@RequestBody RequestParams params) {return hotelService.search(params);}
}

在对应的 service 中实现具体操作

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {@Autowiredprivate RestHighLevelClient client;@Overridepublic PageResult search(RequestParams params) {try {SearchRequest request = new SearchRequest("hotel");// 判断请求是否包含指定params,以此来选择查询方式String key = params.getKey();if (key == null || "".equals(key)) {request.source().query(QueryBuilders.matchAllQuery());} else {request.source().query(QueryBuilders.matchQuery("all", key));}// 分页Integer page = params.getPage(), size = params.getSize();request.source().from((page - 1) * size).size(size);SearchResponse response = client.search(request, RequestOptions.DEFAULT);return logResp(response);} catch (IOException e) {throw new RuntimeException();}}// 此方法将包装从es中查询到的所有文档到对象PageResult内,然后作为响应返回前端private PageResult logResp(SearchResponse response) {SearchHits searchHits = response.getHits();SearchHit[] hits = searchHits.getHits();System.out.println(searchHits.getTotalHits().value + "条数据");List<HotelDoc> hotelDocs = new ArrayList<>();for (SearchHit hit : hits) {String source = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);hotelDocs.add(hotelDoc);}return new PageResult(searchHits.getTotalHits().value, hotelDocs);}
}

自动补全

我们在搜索东西的时候经常会看见每输入一个词就会联想出很多相关内容,我们使用 pinyin 分词器进行分词操作来实现这个功能

安装依赖

es 的分词器包括三个部分:

  • character filters 对文本简单处理,如删除替换字符
  • tokenizer 将文本按照一定规则切割为词条
  • tokenizer filter 将 tokenizer 的结果进一步细化处理,如大小写转换和同义词处理

其中,ik 分词器处理 tokenizer ,而 pinyin 分词器处理 tokenizer filter

下载 pinyin 分词器,安装步骤略:下载地址


自定义分词器

配置自定义的分词器,分词器的名称叫做 my_analyzer

PUT /test
{"settings": {"analysis": {"analyzer": {"my_analyzer": {"tokenizer": "ik_max_word","filter": "py"}},"filter": {"py": {"type": "pinyin","keep_full_pinyin": false,"keep_joined_full_pinyin": true,"keep_original": true,"limit_first_letter_length": 16,"remove_duplicated_term": true,"none_chinese_pinyin_tokenize": false}}}},"mappings": {"properties": {"name":{"type": "text","analyzer": "my_analyzer"}}}
}

然后执行测试,看看我们的分词器运作效果如何

POST /test/_analyze
{"text": ["如家酒店真不戳"],"analyzer": "my_analyzer"
}

Completion Suggester

在创建倒排索引时:使用自定义分词器,同时对汉语分词并分出拼音
用户搜索时:直接使用 ik_smart 分词器

Completion Suggester 特性:

  1. Completion Suggester 是一种用于自动补全和建议功能的高级功能。它可以根据用户输入的部分词项提供匹配的建议结果。
  2. Completion Suggester 字段类型使用特定的数据结构来存储建议的文本。它使用了倒排索引和有限状态自动机(FSA)来提供高效的建议查询。
  3. Completion Suggester 查询的结果将包含一个 suggest 部分,其中包含与查询匹配的建议结果。每个建议结果都包含一个 options 数组,其中包含建议的文本和其他相关信息。

这里提供一个示例,示例内容是:创建索引myindex,并向其中插入三个随机数据,并使用 Completion Suggester 对字段title进行查询。

  1. 创建索引myindex并定义字段映射:
    title的字段,其类型为completion是为了进行 suggester 查询所用的!
PUT /myindex
{"mappings": {"properties": {"title": {"type": "completion"}}}
}
  1. 向索引myindex插入三个随机数据:
POST /myindex/_doc/1
{"title": {"input": ["Apple", "iPhone"]}
}POST /myindex/_doc/2
{"title": {"input": ["Samsung", "Galaxy"]}
}POST /myindex/_doc/3
{"title": {"input": ["Google", "Pixel"]}
}

上述操作将三个文档插入到索引myindex中,每个文档包含一个title字段,其中input数组定义了建议的文本。

  1. 使用 Completion Suggester 进行查询:
GET /myindex/_search
{"suggest": {"suggestion": {  // Completion Suggester的名称,可以自定义"prefix": "i",  // 指定以字母"i"开头的前缀"completion": {"field": "title",  // 指定要执行建议查询的字段为"title""size": 10  // 指定返回的建议结果数量,这里设置为10}}}
}

上述查询使用 Completion Suggester 在字段title中搜索以字母"i"开头的建议文本

执行查询后,你将获得与查询匹配的建议结果,类似于以下示例响应:

{"suggest": {"suggestion": [{"text": "i","offset": 0,"length": 1,"options": [{"text": "iPhone","score": 1.0}]}]}
}

聚合数据


聚合的分类

聚合可以划分为三类

在这里插入图片描述


Bucket 聚合

使用 aggs 字段进行聚合查询,聚合查询的桶里面默认存在一个字段“_count”,用于表示寻找到的相同的数据量

// GET请求示例,执行聚合查询
GET /hotel/_search
{"size": 0, // 设置搜索结果的大小为0,只返回聚合结果"aggs": {"brandAgg": {// 聚合名称为brandAgg"terms": {"field": "brand", // 根据brand字段进行分组"order": {"_count": "asc" // 按照聚合桶中文档数量的升序排序},"size": 20 // 返回前20个分组}}}
}

同样的,额外添加一个 query 字段,让我们将待查询的索引限定到一定范围内
这样可以避免查询全部索引的内存占用问题

GET /hotel/_search
{// 只对价格200及以下的酒店进行统计"query": {"range": {"price": {"lte": 200}}},"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","order": {"_count": "asc"},"size": 20}}}
}

Metrix 聚合

聚合里面再写一个聚合,相当于子聚合,子聚合的定义方式和普通聚合一致

stats 用于统计指定字段的 min、max、avg 等基本数据

GET /hotel/_search
{"size": 0,"aggs": {"brandAgg": {"terms": {"field": "brand","size": 20},"aggs": {"scoreAgg": {"stats": {"field": "score"}}}}}
}

RestClient 实现聚合

@Test
void testAgg() throws IOException {// 这一块执行聚合查询SearchRequest request = new SearchRequest("hotel");request.source().size(0);request.source().aggregation(AggregationBuilders.terms("brandAgg").field("brand").size(10));// 这一段取出聚合查询的结果SearchResponse response = client.search(request, RequestOptions.DEFAULT);Aggregations aggregations = response.getAggregations();Terms brandAgg = aggregations.get("brandAgg");List<? extends Terms.Bucket> buckets = brandAgg.getBuckets();for (Terms.Bucket bucket : buckets) {String keyAsString = bucket.getKeyAsString();System.out.println(keyAsString);}
}

suggest 查询结果

编写查询方法 suggestion,下图对应了查询方法及其 java 写法

在这里插入图片描述

查询完了自然要解析返回的 json

在这里插入图片描述


前端实现自动补全的效果流程:

  1. 检测用户在搜索框输入内容变化,使用 get 请求发送,params 为当前输入框内容
  2. 后端接收 get 请求,解析 requestparams,获取输入框内容
  3. 将内容使用 suggestion 发给 es,es 解析返回结果后再由后端解析
  4. 查询得到的 list 返回前端,完成!

数据同步


同步策略

当修改 mysql 后,es 内容仍未变化,需使用对应同步策略使 es 同步更新数据

同步调用策略:酒店管理服务先修改 mysql,再调用接口来让酒店搜索服务修改 es(简单粗暴,耦合度较高)

异步通知策略:酒店管理服务修改 mysql 后,把修改 es 的请求发送到 mq,酒店搜索服务依次处理 mq 中的更改请求(低耦合,易实现,依赖 mq)

监听 binlog 策略:略去了酒店管理服务发送请求的过程,而是由 mq 直接监听 mysql 改变从而对应通知酒店搜索服务做出改变(完全解耦,但开启 binlog 会增加数据库负担)
在这里插入图片描述


mq 同步 es

在这里插入图片描述


es 搭设集群

在这里插入图片描述

ES 主从结构通常会发生所谓的脑裂问题:指由于网络分区或其他故障导致集群中的节点无法相互通信,从而导致集群中形成多个独立的子集群。这可能会导致数据不一致和操作冲突(说人话就是会产生多个 master)

配置文件解决法:在 Elasticsearch 的配置文件中,可以设置 discovery.zen.minimum_master_nodes 参数来指定在集群中需要的最小主节点数目。这可以帮助防止脑裂情况下的自动选举多个主节点。建议将此参数设置为集群中主节点数目的一半加一
(es7 及以上版本已经自动设置了此属性,故一般无脑裂问题发生)


在这里插入图片描述

es 分片原理

es 会通过 hash 算法决定当前的文档应该存储到哪一个分片上去
由于 hash 算法和 es 分片数量有关,所以一旦索引库创建,分片数量就不可变

shard = hash(_routing) & number_of_shards


es 分片查询流程

  1. scatter phase 分散阶段:hash 算法算出每一个文档应该去往的分片,由 coordinating node 执行分发
  2. gather phase 聚集阶段:coordinating node 汇集每一个分片返回的结果,返回给用户

es 故障转移

集群的 master 节点侦测到某个节点宕机,就会立即将其分片数据复制到其他节点,这就是故障转移技术


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/131997.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cdsn目录处理:空行替换2个```,在2个```中间添加“# 空行文本后遇到的第1行文字”?

原标题&#xff1a; python查找替换&#xff1a;查找空行&#xff0c;空行前后添加&#xff0c;中间添加 # 空格 空行后遇到的第1行文字&#xff1f;初始代码 查找空行空行前后添加 中间添加 # 空行后遇到的第1行文字txt 36 96 159 8 72可以使用Python的字符串处理函数来查找…

Vue3中使用tinymce全功能演示,包括开源功能

效果图&#xff1a; 1、下载插件: npm i tinymce npm i tinymce/tinymce-vue 2、在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中 &#xff08;可以先创建一个tinymce文件夹&#xff09;&#xff1a; 3、在tinymce官网中下载中文包&#xff0c;并放在刚…

【AntDesign】多环境配置和启动

环境分类&#xff0c;可以分为 本地环境、测试环境、生产环境等&#xff0c;通过对不同环境配置内容&#xff0c;来实现对不同环境做不同的事情。 AntDesign 项目&#xff0c;通过 config.xxx.ts 添加不同的后缀来区分配置文件&#xff0c;启动时候通过后缀启动即可。 config…

如何基于先进视频技术,构建互联网视频监控安全管理平台解决方案

一、建设思路 依托互联网&#xff0c;建设一朵云&#xff0c;实现各类二三类视频资源统一接入&#xff0c;实现天网最后100米、10米、1米的全域覆盖。 依托人工智能与互联网技术&#xff0c;拓展视频资源在政府、社会面等多领域的全面应用&#xff1b;建设与运营模式并存&…

湖州OLED透明拼接屏技术应用引领现代化旅游观光方式

湖州市位于中国浙江省北部&#xff0c;拥有悠久的历史和丰富的文化遗产。湖州市以其美丽的湖泊和秀丽的自然风光而闻名。 作为中国重要的历史文化名城之一&#xff0c;湖州市有着丰富的文化遗产和历史资源&#xff0c;如古城墙、古建筑和古镇等。 这为OLED透明拼接屏技术的应用…

【Python 零基础入门】 函数

【Python 零基础入门】第五课 函数 【Python 零基础入门】第五课 函数函数在生活中的类比函数为什么要使用函数函数的格式无参函数含参函数 参数形参实参 变量作用域局部变量全局变量 递归函数基本的递归斐波那契数列 Lambda 表达式高阶函数map 函数filter 函数reduce 函数结合…

【RabbitMQ 实战】11 队列的结构和惰性队列

一、 队列的结构 队列的组成&#xff1a; 队列由 rabbit_amgqueue_process 和 backing_queue两部分组成。rabbit_amqqueue_process负责协议相关的消息处理&#xff0c;即接收生产者发布的消息、向消费者交付消息、处理消息的确认 (包括生产端的 confirm 和消费端的 ack) 等。…

进阶JAVA篇-Object类与Objects类、包装类的常用API(一)

目录 API 1.0 API概念 2.0 Object类的常用API 2.1 Object 中的 tostring() 方法 表示返回对象的字符串表达形式 2.2 Object 中的 equals(Object o) 方法 &#xff0c;判断两个对象的是否相等 2.2.1深入了解如何重写Object 中的 equals(Object o) 方法 2.2.2 对重写Object 中的…

C++标准模板(STL)- 类型支持 (数值极限,round_style,is_iec559,is_bounded)

数值极限 定义于头文件 <limits> 定义于头文件 <limits> template< class T > class numeric_limits; numeric_limits 类模板提供查询各种算术类型属性的标准化方式&#xff08;例如 int 类型的最大可能值是 std::numeric_limits<int>::max() &…

服务器上部署python脚本

1.查看服务器上的python是否自带&#xff0c;一般都自带 2.将本地脚本上传到服务器 3.直接运行一下脚本看报什么错误 代码错误&#xff0c; 将f删除后报别的错误 上面是未安装依赖的错误。我们安装一下依赖 下面是编码的解决 #!/usr/bin/python # -*- coding: utf-8 -*- 先把…

Java项目调用Python脚本(基于idea)

前期准备 1.首先需要在本地环境中安装配置python环境 Python(含PyCharm及配置)下载安装以及简单使用(Idea) 博主本次使用python版本为py3.7.3 2.idea安装python插件 位置&#xff1a;File->Settings->Plugins->python->安装后重启即可 3.引入jython依赖 &l…

mac 版hadoop3.2.4 解决 Unable to load native-hadoop library 缺失文件

mac 版hadoop3.2.4或其他版本 Unable to load native-hadoop library 缺失文件 Native 包报错缺失&#xff1a; 1. hadoop-3.2.4/lib/native里加*.dylib 2. hadoop-3.2.4/etc/hadoop/hadoop-env.sh 加或修改 export HADOOP_OPTS"-Djava.library.path/Users/lvan/Documen…