微服务实用篇知识点

实用篇
SpringCloud01
1、认识微服务
SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。
SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验:

2、SpringCloud
SpringCloud与SpringBoot的版本兼容关系如下:

3、服务拆分及远程调用
服务拆分注意事项:单一职责:不同微服务,不要重复开发相同业务,数据独立:不要访问其它微服务的数据库,面向服务:将自己的业务暴露为接口,供其它微服务调用。微服务远程调用:服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务),服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)。
4、服务调用关系
服务提供者:暴露接口给其它微服务调用,服务消费者:调用其它微服务提供的接口
提供者与消费者角色其实是相对的,一个服务可以同时是服务提供者和服务消费者
5、Eureka注册中心
服务调用出现的问题:服务消费者该如何获取服务提供者的地址信息?如果有多个服务提供者,消费者该如何选择?消费者如何得知服务提供者的健康状态?eureka的作用:消费者该如何获取服务提供者具体信息?服务提供者启动时向eureka注册自己的信息,eureka保存这些信息,消费者根据服务名称向eureka拉取提供者信息,如果有多个服务提供者,消费者该如何选择?服务消费者利用负载均衡算法,从服务列表中挑选一个消费者如何感知服务提供者健康状态?服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态eureka会更新记录服务列表信息,心跳不正常会被剔除消费者就可以拉取到最新的信息
在Eureka架构中,微服务角色有两类:EurekaServer:服务端,注册中心。记录服务信息
心跳监控。EurekaClient:客户端,Provider:服务提供者,例如案例中的 user-service,注册自己的信息到EurekaServer,每隔30秒向EurekaServer发送心跳,consumer:服务消费者,例如案例中的 order-service,根据服务名称从EurekaServer拉取服务列表基于服务列表做负载均衡,选中一个微服务后发起远程调用。
6、总结
搭建EurekaServer
引入eureka-server依赖
添加@EnableEurekaServer注解
在application.yml中配置eureka地址
服务注册
引入eureka-client依赖
在application.yml中配置eureka地址
服务发现
引入eureka-client依赖
在application.yml中配置eureka地址
给RestTemplate添加@LoadBalanced注解
用服务提供者的服务名称远程调用
7、Ribbon负载均衡
负载均衡流程

8、负载均衡策略
Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则:

9、通过定义IRule实现可以修改负载均衡规则,有两种方式:
代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:
配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:
饥饿加载
Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。
而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
Ribbon负载均衡规则:
规则接口是IRule
默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询
负载均衡自定义方式:
代码方式:配置灵活,但修改时需要重新打包发布
配置方式:直观,方便,无需重新打包发布,但是无法做全局配置
饥饿加载:
开启饥饿加载
指定饥饿加载的微服务名称
10、Nacos注册中心
Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。
Nacos服务分级存储模型

服务跨集群调用问题
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高,本地集群不可访问时,再去访问其它集群
11、总结
A、Nacos服务分级存储模型
一级是服务,例如userservice
二级是集群,例如杭州或上海
三级是实例,例如杭州机房的某台部署了userservice的服务器
B、如何设置实例的集群属性
修改application.yml文件,添加spring.cloud.nacos.discovery.cluster-name属性即可
12、服务集群属性
我们修改user-service集群属性配置,达到下面的效果:

13、NacosRule负载均衡策略
优先选择同集群服务实例列表
本地集群找不到提供者,才去其它集群寻找,并且会报警告
确定了可用实例列表后,再采用随机负载均衡挑选实例
根据权重负载均衡:
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
14、实例的权重控制
Nacos控制台可以设置实例的权重值,0~1之间
同集群内的多个实例,权重越高被访问的频率越高
权重设置为0则完全不会被访问
15环境隔离 - namespace
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
Nacos环境隔离
每个namespace都有唯一id
服务设置namespace时要写id而不是名称
不同namespace下的服务互相不可见
16、nacos注册中心细节分析

17、总结
Nacos与eureka的共同点:都支持服务注册和服务拉取,都支持服务提供者心跳方式做健康检测。Nacos与Eureka的区别:Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式,临时实例心跳不正常会被剔除,非临时实例则不会被剔除,Nacos支持服务列表变更的消息推送模式,服务列表更新更及时Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式。
18、Nacos配置管理
统一配置管理:配置更改热更新

配置获取的步骤如下:

19、总结
将配置交给Nacos管理的步骤
在Nacos中添加配置文件
在微服务中引入nacos的config依赖
在微服务中添加bootstrap.yml,配置nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去nacos读取哪个文件
20、Nacos配置管理
配置自动刷新
Nacos中的配置文件变更后,微服务无需重启就可以感知。不过需要通过下面两种配置实现:
方式一:在@Value注入的变量所在类上添加注解@RefreshScope
方式二:使用@ConfigurationProperties注解
20、总结
Nacos配置更改后,微服务可以实现热更新,方式:
通过@Value注解注入,结合@RefreshScope来刷新
通过@ConfigurationProperties注入,自动刷新
注意事项:
不是所有的配置都适合放到配置中心,维护起来比较麻烦
建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置
21、多环境配置共享
微服务启动时会从nacos读取多个配置文件:
[spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml
[spring.application.name].yaml,例如:userservice.yaml
无论profile如何变化,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文

22、微服务会从nacos读取的配置文件:
[服务名]-[spring.profile.active].yaml,环境配置
[服务名].yaml,默认配置,多环境共享
优先级:
[服务名]-[环境].yaml >[服务名].yaml > 本地配置
23、多服务共享配置
不同微服务之间可以共享配置文件,通过下面的两种方式来指定:

多种配置的优先级:

24、总结
微服务默认读取的配置文件:
[服务名]-[spring.profile.active].yaml,默认配置
[服务名].yaml,多环境共享
不同微服务共享的配置文件:
通过shared-configs指定
通过extension-configs指定
优先级:
环境配置 >服务名.yaml > extension-config > extension-configs > shared-configs > 本地配置
25、http客户端Feign
RestTemplate方式调用存在的问题,先来看我们以前利用RestTemplate发起远程调用的代码:
String url = “http://userservice/user/” + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
存在下面的问题:代码可读性差,编程体验不统一,参数复杂URL难以维护
Feign的介绍:Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign,其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
26、使用Feign的步骤如下:
引入依赖:

org.springframework.cloud
spring-cloud-starter-openfeign

在order-service的启动类添加注解开启Feign的功能:

使用Feign的步骤如下:
主要是基于SpringMVC的注解来声明远程调用的信息,比如:
服务名称:userservice
请求方式:GET
请求路径:/user/{id}
请求参数:Long id
返回值类型:User
用Feign客户端代替RestTemplate
27、自定义Feign的配置
Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:

配置Feign日志有两种方式:
方式一:配置文件方式
全局生效:

feign:
client:
config:
default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
loggerLevel: FULL # 日志级别

局部生效:
feign:
client:
config:
userservice: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
loggerLevel: FULL # 日志级别
28、Feign的性能优化
Feign底层的客户端实现:URLConnection:默认实现,不支持连接池,Apache HttpClient :支持连接池,OKHttp:支持连接池,因此优化Feign的性能主要包括:使用连接池代替默认的URLConnection,日志级别,最好用basic或none,日志级别尽量用basic,使用HttpClient或OKHttp代替URLConnection,引入feign-httpClient依赖,配置文件开启httpClient功能,设置连接池参数。
29、Feign的最佳实践
方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。服务紧耦合。父接口参数列表中的映射不会被继承。方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。抽取FeignClient,实现最佳实践方式二的步骤如下:首先创建一个module,命名为feign-api,然后引入feign的starter依赖,将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中,在order-service中引入feign-api的依赖
修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
重启测试。
30、统一网关Gateway
为什么需要网关:网关功能:身份认证和权限校验,服务路由、负载均衡,请求限流。网关的技术实现,在SpringCloud中网关的实现包括两种:gateway,zuul,Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。网关的作用:对用户请求做身份认证、权限校验将用户请求路由到微服务,并实现负载均衡对用户请求做限流。
31、搭建网关服务
搭建网关服务的步骤:
创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖:

org.springframework.cloud spring-cloud-starter-gateway com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery 编写路由配置及nacos地址 server: port: 10010 # 网关端口 spring: application: name: gateway # 服务名称 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: # 网关路由配置 - id: user-service # 路由id,自定义,只要唯一即可 # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址 uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称 predicates: # 路由断言,也就是判断请求是否符合路由规则的条件 - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求 32、路由断言工厂Route Predicate Factory 网关路由可以配置的内容包括:路由id:路由唯一标示,uri:路由目的地,支持lb和http两种,predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地,filters:路由过滤器,处理请求或响应,我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件, 例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的 像这样的断言工厂在SpringCloudGateway还有十几个 33、路由过滤器 GatewayFilter GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:Spring提供了31种不同的路由过滤器工厂。例如:全局过滤器 GlobalFilter,全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现。定义方式是实现GlobalFilter接口。过滤器执行顺序请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器 34、过滤器执行顺序 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。 35、跨域问题处理 跨域:域名不一致就是跨域,主要包括:域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com,域名相同,端口不同:localhost:8080和localhost8081,跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题,解决方案:CORS 36、限流过滤器 限流:对应用服务器的请求做限制,避免因过多请求而导致服务器过载甚至宕机。限流算法常见的包括两种:计数器算法,又包括窗口计数器算法、滑动窗口计数器算法,漏桶算法(Leaky Bucket),令牌桶算法(Token Bucket),固定窗口计数器算法概念如下:将时间划分为多个窗口;在每个窗口内每有一次请求就将计数器加一,当时间到达下一个窗口时,计数器重置。如果计数器超过了限制数量,则本窗口内所有的请求都被丢弃。限流过滤器-漏桶算法:漏桶算法说明:将每个请求视作"水滴"放入"漏桶"进行存储;"漏桶"以固定速率向外"漏"出请求来执行,如果"漏桶"空了则停止"漏水”;如果"漏桶"满了则多余的"水滴"会被直接丢弃。限流过滤器-令牌桶算法:漏桶算法说明:以固定的速率生成令牌,存入令牌桶中,如果令牌桶满了以后,多余令牌丢弃,请求进入后,必须先尝试从桶中获取令牌,获取到令牌后才可以被处理,如果令牌桶中没有令牌,则请求等待或丢弃。限流有什么作用?限流是保护服务器,避免因过多请求而导致服务器过载甚至宕机。限流算法:计数器算法,漏桶算法,令牌桶算法。 Docker 1、初识Docker 项目部署的问题:大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题:依赖关系复杂,容易出现兼容性问题。开发、测试、生产环境有差异。Docker如何解决依赖的兼容问题的?将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包,将每个应用放到一个隔离容器去运行,避免互相干扰,内核与硬件交互,提供操作硬件的指令,系统应用封装内核指令为函数,便于程序员调用用户程序基于系统函数库实现功能 2、Docker如何解决不同系统环境的问题? Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包,Docker运行到不同操作系统时,直接基于打包的库函数,借助于操作系统的Linux内核来运行,Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像,Docker应用运行在容器中,使用沙箱机制,相互隔离,Docker如何解决开发、测试、生产环境有差异的问题,Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行。 3、Docker与虚拟机 虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。镜像和容器:镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。Docker和DockerHub:DockerHub:DockerHub是一个Docker镜像的托管平台。这样的平台称为Docker Registry。国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库等。 4、docker架构 Docker是一个CS架构的程序,由两部分组成:服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器等。客户端(client):通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令 5、镜像相关命令 镜像名称一般分两部分组成:[repository]:[tag]。在没有指定tag时,默认是latest,代表最新版本的镜像。数据卷:数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。容器与数据耦合的问题,操作数据卷:数据卷操作的基本语法如下:docker volume [COMMAND] 6、自定义镜像 镜像结构:镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。入口(Entrypoint):镜像运行入口,一般是程序启动的脚本和参数。层( Layer ):在BaseImage基础上添加安装包、依赖、配置等,每次操作都形成新的一层。基础镜像(BaseImage):应用依赖的系统函数库、环境、配置、文件等。什么是Dockerfile:Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。 7、DockerCompose 什么是DockerCompose:docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。DockerCompose的详细语法参考官网:https://docs.docker.com/compose/compose-file/。 8、Docker镜像仓库 常见镜像仓库服务:镜像仓库( Docker Registry )有公共的和私有的两种形式:公共仓库:例如Docker官方的 Docker Hub,国内也有一些云服务商提供类似于 Docker Hub 的公开服务,比如 网易云镜像服务、DaoCloud 镜像服务、阿里云镜像服务等。除了使用公开仓库外,用户还可以在本地搭建私有 Docker Registry。企业自己的镜像最好是采用私有Docker Registry来实现。在私有镜像仓库推送或拉取镜像,推送镜像到私有镜像服务必须先tag,步骤如下:重新tag本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/,docker tag nginx:latest 192.168.150.101:8080/nginx:1.0 ,推送镜像:docker push 192.168.150.101:8080/nginx:1.0 ,拉取镜像:docker pull 192.168.150.101:8080/nginx:1.0 MQ 1、初识MQ 同步通讯和异步通讯

同步调用的问题
微服务间基于Feign的调用就属于同步方式,存在一些问题。

同步调用存在的问题

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

3、RabbitMQ中的几个概念:
channel:操作MQ的工具,exchange:路由消息到队列中,queue:缓存消息,virtual host:虚拟主机,是对queue、exchange等资源的逻辑分组。常见消息模型:MQ的官方文档中给出了5个MQ的Demo示例,对应了几种不同的用法:基本消息队列(BasicQueue),工作消息队列(WorkQueue),发布订阅(Publish、Subscribe),又根据交换机类型不同分为三种:Fanout Exchange:广播,Direct Exchange:路由,Topic Exchange:主题。
4、HelloWorld案例
官方的HelloWorld是基于最基础的消息队列模型来实现的,只包括三个角色:publisher:消息发布者,将消息发送到队列queue,queue:消息队列,负责接受并缓存消息,consumer:订阅队列,处理队列中的消息
5、Work模型的使用:
多个消费者绑定到一个队列,同一条消息只会被一个消费者处理,通过设置prefetch来控制消费者预取的消息数量。发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机)。常见exchange类型包括:Fanout:广播,Direct:路由,Topic:话题。发布订阅-DirectExchange:Direct Exchange 会将接收到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)。每一个Queue都与Exchange设置一个BindingKey,发布者发送消息时,指定消息的RoutingKey,Exchange将消息路由到BindingKey与消息RoutingKey一致的队列。
6、发布订阅-TopicExchange
TopicExchange与DirectExchange类似,区别在于routingKey必须是多个单词的列表,并且以 . 分割。Queue与Exchange指定BindingKey时可以使用通配符:#:代指0个或多个单词。*:代指一个单词,消息转换器,Spring的对消息对象的处理是由org.springframework.amqp.support.converter.MessageConverter来处理的。而默认实现是SimpleMessageConverter,基于JDK的ObjectOutputStream完成序列化。如果要修改只需要定义一个MessageConverter 类型的Bean即可。推荐用JSON方式序列化,步骤如下:我们在publisher服务引入依赖,我们在publisher服务声明MessageConverter。

分布式搜索引擎elasticsearch基础
1、什么是elasticsearch
elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域。elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。
2、正向索引和倒排索引
传统数据库(如MySQL)采用正向索引,例如给下表(tb_goods)中的id创建索引:
elasticsearch采用倒排索引:文档(document):每条数据就是一个文档,词条(term):文档按照语义分成的词语,倒排索引中包含两部分内容:词条词典(Term Dictionary):记录所有词条,以及词条与倒排列表(Posting List)之间的关系,会给词条创建索引,提高查询和插入效率。倒排列表(Posting List):记录词条所在的文档id、词条出现频率 、词条在文档中的位置等信息。文档id:用于快速获取文档,词条频率(TF):文档在词条出现的次数,用于评分。
3、文档
elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中。索引(index):相同类型的文档的集合,映射(mapping):索引中文档的字段约束信息,类似表的结构约束。
4、架构
分词器:es在创建倒排索引时需要对文档分词;在搜索时,需要对用户输入内容分词。但默认的分词规则对中文处理并不友好。处理中文分词,一般会使用IK分词器。https://github.com/medcl/elasticsearch-analysis-ik,安装IK分词器,参考课前资料《安装elasticsearch.md》:ik分词器包含两种模式:ik_smart:最少切分,粗粒度,ik_max_word:最细切分,细粒度,ik分词器-拓展词库,要拓展ik分词器的词库,只需要修改一个ik分词器目录中的config目录中的IkAnalyzer.cfg.xml文件:然后在名为ext.dic的文件中,添加想要拓展的词语即可:ik分词器-停用词库:要禁用某些敏感词条,只需要修改一个ik分词器目录中的config目录中的IkAnalyzer.cfg.xml文件:然后在名为stopword.dic的文件中,添加想要拓展的词语即可:
5、索引库操作
mapping属性:mapping是对索引库中文档的约束,常见的mapping属性包括:type:字段数据类型,常见的简单类型有:字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址),数值:long、integer、short、byte、double、float、,布尔:boolean。日期:date,对象:object,index:是否创建索引,默认为true,analyzer:使用哪种分词器properties:该字段的子字段。创建索引库:ES中通过Restful请求操作索引库、文档。请求内容用DSL语句来表示。
分布式搜索引擎elasticsearch搜索功能
1、DSL查询语法
DSL Query的分类:Elasticsearch提供了基于JSON的DSL(Domain Specific  Language)来定义查询。常见的查询类型包括:查询所有:查询出所有数据,一般测试用。例如:match_all,全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:match_query,multi_match_query,精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:ids,range,term,地理(geo)查询:根据经纬度查询。例如:geo_distance,geo_bounding_box,复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:bool,function_score。
2、精确查询
精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:term:根据词条精确值查询,range:根据值的范围查询。地理查询:根据经纬度查询。常见的使用场景包括:携程:搜索我附近的酒店,滴滴:搜索我附近的出租车,微信:搜索我附近的人。复合查询:复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如:fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价。相关性算分:当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。
3、复合查询 Boolean Query
布尔查询是一个或多个查询子句的组合。子查询的组合方式有:must:必须匹配每个子查询,类似“与”,should:选择性匹配子查询,类似“或”,must_not:必须不匹配,不参与算分,类似“非”,filter:必须匹配,不参与算分,排序elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。分页:elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。elasticsearch中通过修改from、size参数来控制要返回的分页结果:
4、高亮
高亮:就是在搜索结果中把搜索关键字突出显示。原理是这样的:将搜索结果中的关键字用标签标记出来,在页面中给标签添加css样式
分布式搜索引擎深入elasticsearch
1、聚合的分类
聚合(aggregations)可以实现对文档数据的统计、分析、运算。聚合常见的有三类:桶(Bucket)聚合:用来对文档做分组,TermAggregation:按照文档字段值分组,Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组,度量(Metric)聚合:用以计算一些值,比如:最大值、最小值、平均值等,Avg:求平均值,Max:求最大值,Min:求最小值,Stats:同时求max、min、avg、sum等,管道(pipeline)聚合:其它聚合的结果为基础做聚合
2、自动补全
自动补全需求说明:当用户在搜索框输入字符时,我们应该提示出与该字符有关的搜索项使用拼音分词,要实现根据字母做补全,就必须对文档按照拼音分词。在GitHub上恰好有elasticsearch的拼音分词插件。地址:https://github.com/medcl/elasticsearch-analysis-pinyin
安装方式与IK分词器一样,分三步:解压,上传到虚拟机中,elasticsearch的plugin目录
重启elasticsearch,测试。自定义分词器:elasticsearch中分词器(analyzer)的组成包含三部分:character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符,tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart,tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等。
3、总结
如何使用拼音分词器?下载pinyin分词器,解压并放到elasticsearch的plugin目录重启即可,如何自定义分词器?创建索引库时,在settings中配置,可以包含三部分:character filter,tokenizer,filter,拼音分词器注意事项?为了避免搜索到同音字,搜索时不要使用拼音分词器
4、数据同步
数据同步问题分析:elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。方式一:同步调用。优点:实现简单,粗暴,缺点:业务耦合度高,方式二:异步通知,优点:低耦合,实现难度一般,缺点:依赖mq的可靠性。方式三:监听binlog,优点:完全解除服务间耦合,缺点:开启binlog增加数据库负担、实现复杂度高
5、ES集群
ES集群结构
单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点;单点故障问题:将分片数据在不同节点备份(replica ),搭建ES集群,每个索引库的分片数量、副本数量都是在创建索引库时指定的,并且分片数量一旦设置以后无法修改。语法如下:PUT /itcast
{
  “settings”: {
    “number_of_shards”: 3, // 分片数量
    “number_of_replicas”: 1 // 副本数量
  },
  “mappings”: {
    “properties”: {
      // mapping映射定义 …
    }
  }
}

ES集群的分布式查询:elasticsearch中的每个节点角色都有自己不同的职责,因此建议集群部署时,每个节点都有独立的角色。ES集群的脑裂:默认情况下,每个节点都是master eligible节点,因此一旦master节点宕机,其它候选节点会选举一个成为主节点。当主节点与其他节点网络故障时,可能发生脑裂问题。为了避免脑裂,需要要求选票超过 ( eligible节点数量 + 1 )/ 2 才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题。ES集群的分布式存储:当新增文档时,应该保存到不同分片,保证数据均衡,那么coordinating node如何确定数据该存储到哪个分片呢?elasticsearch会通过hash算法来计算文档应该存储到哪个分片。ES集群的分布式查询。elasticsearch的查询分成两个阶段:
scatter phase:分散阶段,coordinating node会把请求分发到每一个分片,gather phase:聚集阶段,coordinating node汇总data node的搜索结果,并处理为最终结果集返回给用户。ES集群的故障转移。集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。

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