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

news2024/12/23 20:09:20

目录

    • 黑马旅游案例
      • 分页查询
      • 自动补全
        • 安装依赖
        • 自定义分词器
        • 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 {
    @Autowired
    private IHotelService hotelService;

    @PostMapping("/list")
    PageResult search(@RequestBody RequestParams params) {
        return hotelService.search(params);
    }
}

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

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    @Autowired
    private RestHighLevelClient client;

    @Override
    public 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.coloradmin.cn/o/1083463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制造业单项冠军(国家级、广东省、深圳市)奖励政策及申报对比

制造业单项冠军的头衔含金量极高&#xff0c;是某一细分领域的“领头雁”。下面深科信对“制造业单项冠军”&#xff08;国家级、广东省级、深圳市级&#xff09;的认定标准、奖励政策进行梳理 。 2023年9月25日&#xff0c;工信部办公厅正式发布《关于开展2023年制造业单项冠军…

c++视觉处理---Scharr滤波器

Scharr滤波器&#xff1a; cv::Scharr cv::Scharr 是OpenCV库中用于应用Scharr滤波器的函数。Scharr滤波器通常用于图像处理中的边缘检测和特征提取。这是 cv::Scharr 函数的基本用法&#xff1a; cv::Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType);src: 输入…

C语言为什么for不执行?

C语言为什么for不执行&#xff1f; 一个表达式为初始化 第二个表达式为判断 第三个表达式为调整 如图所示&#xff0c;这是一种最常见&#xff0c;同样的&#xff0c;在这个循环当中同样的也能使用到continue和break关键字最近很多小伙伴找我&#xff0c;说想要一些C语言学习资…

1014蓝桥算法双周赛,学习算法技巧,助力蓝桥杯

家人们&#xff0c;我来免费给大家送福利了&#xff01;&#xff01;&#xff01; 【1014蓝桥算法双周赛 】 背景 蓝桥杯全国软件和信息技术专业人才大赛是由工业和信息化部人才交流中心举办的全国性IT学科赛事。参赛高校超过1200余所&#xff0c;累计参赛人数超过40万人。该…

Java对接微信公众号事件监听回调

1. 公众号开启并配置 2. Java代码实现 1. 验证加密工具类 package cn.com.baidu.wxopen.util.wx;import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays;/*** 验证工具类* 2023年10月12日09:47:04* CBC*/ public cla…

mysql8为什么要开启mysql5中原先的表名称大小写不敏感变成大小写敏感

mysql8为什么要开启mysql5中原先的表名称大小写不敏感变成大小写敏感? MySQL 8.0 对于表名的大小写敏感性的默认设置并没有变更。在 UNIX-like 系统中&#xff0c;表名是大小写敏感的&#xff0c;而在 Windows 中&#xff0c;它们是大小写不敏感的。这与文件系统的行为有关。…

【ROS】使用vscode浏览navigation2源码时,提示:没有那个文件或目录

1、问题描述 使用vscode浏览navigation2源码时,头文件下面有波浪线,并提示:没有那个文件或目录。比如没有:geometry_msgs/msg/polygon.h 错误信息: 无法打开源文件 “geometry_msgs/msg/polygon.h” (dependency of “nav2_controller/controller_server.hpp”)C/C++(16…

40 道 Nginx 精选

什么是Nginx&#xff1f; Nginx是一个 轻量级/高性能的反向代理Web服务器&#xff0c;用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 协议。他实现非常高效的反向代理、负载平衡&#xff0c;他可以处理2-3万并发连接数&#xff0c;官方监测能支持5万并发&#xff0c;现在中国使用ngin…

ubuntu20.04安装genymotion3.5.1

下载和安装genymotion https://www.genymotion.com/download/ wget https://dl.genymotion.com/releases/genymotion-3.5.1/genymotion-3.5.1-linux_x64.bin chmod x genymotion-3.5.1-linux_x64.bin sudo ./genymotion-3.5.1-linux_x64.bin默认位置为&#xff1a;/opt/genym…

PerformanceRunner国产化性能测试工具

国产化性能测试工具PerformanceRunner&#xff08;简称PR&#xff09;通过模拟海量用户并发测试整个系统的承受能力&#xff0c;实现压力测试、性能测试、配置测试、峰值测试等。大限度地缩短测试时间&#xff0c;优化性能和加速应用系统的发布周期。 泽众PR性能测试工具是国内…

数据安全流通的未来趋势

文章目录 每日一句正能量前言01 数据价值与产业崛起02 多数据技术融合创新发展03 数字经济发展的主要动力04 市场规范化与协同繁荣05 安全产业链不断延伸覆盖推荐阅读赠书活动 每日一句正能量 时间这么快。你们很重要&#xff0c;可以走开一会&#xff0c;但是别走散了。 前言 …

身份证读卡器跟OCR有何区别?哪个好?

二代身份证读卡器&#xff08;以下简称读卡器&#xff09;和OCR&#xff08;光学字符识别&#xff09;是两种常见的身份证信息获取技术&#xff0c;它们在原理、功能和应用方面存在一些区别。下面将详细介绍二者的区别并探讨哪个更好。 1. 原理&#xff1a; - 读卡器&#xff…

【SQL】MySQL中的SQL优化、explain执行计划

查看SQL执行频率 -- 查看当前会话统计结果 show session status like Com_______; -- 查看自数据库上次启动至今统计结果 show global status like Com_______;定位低效率执行SQL 两种定位方式&#xff1a; 1.查看慢查询日志 2.通过show processlist查看所有正在运行的线程exp…

使用pymodbus进行modbus-TCP通信

模拟modbus-slave 创建slave 设置 完成 安装pymodbus pip3 install pymodbus2.5.3代码 from pymodbus.client.sync import ModbusTcpClient from pymodbus.bit_read_message import ReadCoilsResponse from pymodbus.register_read_message import ReadInputRegistersRe…

uniapp - 微信小程序新版本发布之后用户端如何手动更新

解疑&#xff1a;微信运行时&#xff0c;会定期检查最近使用的小程序是否有更新。如果有更新&#xff0c;下次小程序启动时会同步进行更新&#xff0c;更新到最新版本后再打开小程序&#xff0c;尽可能保证用户能够尽快使用小程序的最新版本。开发者在后台发布新版本之后&#…

关于Java线程池相关面试题

【更多面试资料请加微信号&#xff1a;suns45】 https://flowus.cn/share/f6cd2cbe-627a-435f-a6e5-1395333f92e8 【FlowUs 息流】&#x1f4e3;suns-Java资料 访问密码&#xff1a;【请加微信号&#xff1a;suns45】 ————线程相关的面试题———— 0&#xff1a;创建线…

如何保持前端开发者的竞争力

这两年&#xff0c;我们经常听到一种声音&#xff0c;那就是“前端已死”。然而&#xff0c;事实并非如此。前端开发者在当今的软件开发中依然扮演着至关重要的角色&#xff0c;它是构建 Web 应用程序所必需的一部分&#xff0c;能够实现动态交互、良好的用户体验和友好的界面设…

vue实现瀑布流

1、在 src 目录下创建 component文件夹&#xff0c;在文件夹中创建 vue文件。 2、在 Vue文件中写入以下内容 <div class"pubu"><div class"left"><div class"pubu-item" v-for"item in left" :key"item.id"…

2023年10月12日历史上的今天大事件早读

公元前539年10月12日波斯国王大流士的军队攻克巴比伦 1492年10月12日西班牙独立日 1492年10月12日哥伦布“发现新大陆” 1773年10月12日法国天文学家梅西叶首次发现具有螺旋结构的星系 1885年10月12日清政府改台湾府为行省 命刘铭传为台湾巡抚 1929年10月12日苏军向张学良…