文章目录
- 一、微服务
- 1. 服务注册与发现
- 1.1 什么是注册中心
- 1.2、注册中心的主要作用是什么
- 1.3 Eureka主要由哪三部分组成?
- 1.4 Eureka Server项目需要引用的关键依赖是什么?
- 1.5 Eureka Server项目主要配置项都有哪些,分别是什么作用?
- 1.6 Eureka Client项目需要引用的关键依赖是什么?
- 1.7 Eureka Client项目主要配置项都有哪些,分别是什么作用?
- 1.8 想在Eureka管理界面显示服务具体IP地址需要如何配置?
- 1.9 心跳频率如何配置?
- 1.10 客户端服务续约时间如何配置?
- 1.11 Eureka管理界面关于服务健康检查的关键参数是哪两个?
- 1.12 什么Eureka的服务保护机制?什么时候触发?如何配置开启和关闭?
- 2、服务调用
- 3.网关
- 4、服务配置
一、微服务
1. 服务注册与发现
1.1 什么是注册中心
理解注册中心:服务管理,核心是有个服务注册表,心跳机制动态维护。
服务提供者provider: 启动的时候向注册中心上报自己的网络信息。
服务消费者consumer: 启动的时候向注册中心上报自己的网络信息,拉取provider的相关网络信息
1.2、注册中心的主要作用是什么
- 服务注册与发现
服务注册是指微服务在启动时,将自己的信息注册到注册中心的过程。
服务发现是指查询可用的微服务列表及网络地址机制。
(服务注册表是注册中心的核心,它是用来记录各个微服务的信息,例如微服务的名称,IP,端口等。服务注册表提供查询API和管理API,查询API用于查询可用的微服务实例,管理API用于服务的注册与注销。)
- 服务检查
各个微服务与注册中心使用一定机制通信(例如心跳机制)。如果某个微服务与注册中心长时间无法通信,就会注销该实例。
1.3 Eureka主要由哪三部分组成?
-
Eureka Server 提供服务的注册和发现;
-
Server Provider 服务提供方,将自身服务注册到 Eureka,从而使服务消费方能够找到;
-
Service Consumer 服务消费方从 Eureka 获取注册服务列表,从而能够消费服务;
1.4 Eureka Server项目需要引用的关键依赖是什么?
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
1.5 Eureka Server项目主要配置项都有哪些,分别是什么作用?
1.6 Eureka Client项目需要引用的关键依赖是什么?
1.7 Eureka Client项目主要配置项都有哪些,分别是什么作用?
1.8 想在Eureka管理界面显示服务具体IP地址需要如何配置?
eureka:
client:
serviceUrl: #eurekaserver的请求路径
defaultZone: http://localhost:8000/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port} #作用:在EurekaServer管控台可以看到服务实例的ip:port
#spring.cloud.client.ip-address 获取ip地址
1.9 心跳频率如何配置?
eureka:
client:
#实例是否在eureka服务器上注册自己的信息以提供其他服务发现,默认为true
register-with-eureka: false
#此客户端是否获取eureka服务器注册表上的注册信息,默认为true
fetch-registry: false
server:
#开启自我保护模式(开启状态下服务停掉eureka不会立即清除掉宕掉的服务,所以false)
enable-self-preservation: false
#清理无效节点,默认60*1000毫秒,即60秒
eviction-interval-timer-in-ms: 5000
1.10 客户端服务续约时间如何配置?
#服务续约,心跳的时间间隔 单位是秒,默认就是30s
eureka.instance.lease-renewal-interval-in-seconds=30
#如果从前一次发送心跳时间起,90秒没接受到新的心跳,讲剔除服务
eureka.instance.lease-expiration-duration-in-seconds=90
#表示eureka client间隔多久去拉取服务注册信息,默认为30秒
eureka.client.registry-fetch-interval-seconds=30
1.11 Eureka管理界面关于服务健康检查的关键参数是哪两个?
1.12 什么Eureka的服务保护机制?什么时候触发?如何配置开启和关闭?
自我保护机制:当客户端发生故障后,服务端并不着急删除注册中心的客户端,期待它又会连上去
这是CAP理论中的AP原则,CAP(一致性,可用性,分区容错性)
关闭:
1.服务端
eureka:
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
2.客户端
eureka:
instance:
#客户端向服务端发送心跳的间隔时间 默认是30秒
lease-renewal-interval-in-seconds: 1
#服务端收到最后一次心跳后等待时间上限 默认90秒 将剔除服务
lease-expiration-duration-in-seconds: 2
在eureka界面中会有红色字体显示是否开启保护模式
开启(提示):
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
关闭(提示):
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
2、服务调用
2.1 、什么是ribbon?它起什么作用?
-
Ribbon是Netflix开源的一款用于客户端负载均衡的软件工具,它在集群中为各个客户端的通信提供了支持,有助于控制HTTP和TCP客户端的行为,提供了很多负载均衡的算法,例如轮询,随机等,同时也可以实现自定义的算法。
-
Ribbon是springcloud下的客户端负载均衡器,消费者在通过服务别名调用服务时,需要通过Ribbon做负载均衡获取实际的服务调用地址,然后通过httpclient的方式进行本地RPC远程调用。
2.1 如何在springboot项目中使用feign client进行服务间调用?(分为几个步骤)
应用客户端配置
1)添加pom依赖
<!-- feign和zuul默认需要依赖ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!-- 負載均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
2)配置文件-application.properties
spring.application.name=tp-cust#配置网关映射端口server.port=18702#是否显示主机ipeureka.instance.preferIpAddress=true#指定eureka服务端地址eureka.client.serviceUrl.defaultZone=http://localhost:18700/eureka/#leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率eureka.instance.leaseRenewalIntervalInSeconds=50#leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。#默认为90秒#如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。#如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。#该值至少应该大于leaseRenewalIntervalInSecondseureka.instance.leaseExpirationDurationInSeconds=30#表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒eureka.client.registryFetchIntervalSeconds=50 #feign使用ribbon所以使用feign时候需要配置ribbon#读取时间ribbon.ReadTimeout=60000#链接时间ribbon.ConnectTimeout=60000#开启ribbon使用eureka注册表功能ribbon.eureka.enable=true
3)启动类添加@EnableFeignClients注解
package com.threepicture; import org.mybatis.spring.annotation.MapperScan;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;//import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.feign.EnableFeignClients; /*** 启动加载,必须放在项目根目录* @author 杏仁拌饭**/@SpringBootApplication//eureka客户端注册(此注解属于组合注解包含@EnableDiscoveryClient)@EnableEurekaClient//开启hystrix断路功能-需要在contrller中配置HystrixCommand@EnableCircuitBreaker//Feign负载@EnableFeignClients//定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中//@ComponentScan( basePackages = "com.threepicture.frame.*")//将项目中对应的mapper类的路径加进来就可以了@MapperScan("com.threepicture.dao.mapper")public class StartApplication { private static Logger logger = LoggerFactory.getLogger(StartApplication.class); public static void main(String[] args) { logger.info("进入cust...."); SpringApplication.run(StartApplication.class, args); } }
4)创建调用接口
package com.threepicture.feignClient; import java.util.Map; import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam; /*** 请求产品工程客户端* @author 杏仁拌饭**///调用注册中心tp-product应用@FeignClient(name="tp-product")public interface ProductFeignClient { /** * 使用post方式调用带参构造方法 * @param requestMap * @param id * @return */ @RequestMapping(value="/query-product/ProductInfoById", method=RequestMethod.POST) public Object getProductInfoById(@RequestBody Map<String, Object> requestMap, @RequestParam("id") String id); /** * 使用get方式调用方法 * @return */ @RequestMapping(value="/query-product/queryAllInfo", method=RequestMethod.GET) public Object getproductAllInfo();}
5)在controller中使用
package com.threepicture.controller; import java.util.List; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; import com.threepicture.dao.model.User;import com.threepicture.feignClient.ProductFeignClient;import com.threepicture.server.impl.ProductService; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @RestController@RequestMapping("/query-cust")public class ProductController { private Logger logger = LoggerFactory.getLogger(ProductController.class); //注入服务 @Autowired private ProductService productService; //注入调用tp-product应用接口 @Autowired private ProductFeignClient productFeignClient; @RequestMapping("/queryAllUser") public List<User> queryAllUser(){ logger.info("进入controller..."); return this.productService.queryAllUser(); } //使用feign调用tp-product @RequestMapping("/queryProductAllInfo") public Object getProductAllInfo(){ return this.productFeignClient.getproductAllInfo(); } @RequestMapping("/test") @HystrixCommand(fallbackMethod = "fallBackInfo") public String getException() throws Exception{ throw new Exception("测试hystrix断路功能..."); } public String fallBackInfo(){ return "服务暂时不可用,请稍后再试"; } }
3.网关
3.1 什么是微服务网关?它解决了什么问题?它主要用能有哪些?
- 简单点说网关是一个Api服务器,是系统的唯一入口。为每个客户端提供一个定制的Restful API。同时它还需要具有一些业务之外的责任:鉴权。静态响应等处理。
- 所以网关的最主要在作用就是路由的转发 。但是 在我们平时的使用过程中,直接请求http 协议的 api 会存在很多问题。例如:安全问题,流量问题 等等。所以gateway 还需要做一些额外的 事情来保证我们的流程是安全的、可靠的。
3.2 SpringCloudGateway核心概念有哪些?
- Route(路由)
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
- Predicate(断言)
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
- Filter(过滤)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改
3.3 SpringCloudGateway路由都有哪些配置?
指定路径转发路由
即根据指定的路径,进行转发
配置如下:
spring: application: name: cloud-gateway-gateway cloud: gateway: routes: # 路由的ID,没有固定规则,但要求唯一,建议配合服务名 - id: payment_routh # 匹配后提供服务的路由地址 uri: http://localhost:8001 # 断言,路径相匹配的进行路由 predicates: - Path=/payment/get/**
通过服务名实现动态路由
默认情况下Gatway会根据注册中心注册的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
1)在前面项的基础上,新增一个支付服务模块,与已有支付模块相同,参考:【SpringCloud】服务提供者集群与服务发现Discovery(三)
2)修改Gateway网关项目(springcloud-gateway-gateway9527)配置文件application.yml,修改内容如下:
spring: application: name: cloud-gateway-gateway cloud: gateway: discovery: locator: # 开启从注册中心动态创建路由的功能,利用微服务名进行路由 enabled: true # 忽略大小写匹配,默认为 false。 # 当 eureka 自动大写 serviceId 时很有用。 所以 MYSERIVCE,会匹配 /myservice/** lowerCaseServiceId: true
3.3.1 动态路由配置?
通过服务名实现动态路由
默认情况下Gatway会根据注册中心注册的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
1)在前面项的基础上,新增一个支付服务模块,与已有支付模块相同,参考:【SpringCloud】服务提供者集群与服务发现Discovery(三)
2)修改Gateway网关项目(springcloud-gateway-gateway9527)配置文件application.yml,修改内容如下:
spring: application: name: cloud-gateway-gateway cloud: gateway: discovery: locator: # 开启从注册中心动态创建路由的功能,利用微服务名进行路由 enabled: true # 忽略大小写匹配,默认为 false。 # 当 eureka 自动大写 serviceId 时很有用。 所以 MYSERIVCE,会匹配 /myservice/** lowerCaseServiceId: true
3.3.2 重写转发路径?
通过RewritePath配置重写转发的url,将/product-service/(?.*),重写为{segment},然后转发到订单微服务。比如在网页上请求http://localhost:8080/product-service/product/1,此时会将请求转发到http://127.0.0.1:9002/product/1( 值得注意的是在yml文档中 $ 要写成 $\ )
server: port: 8080 #端口spring: application: name: api-gateway-server #服务名称 redis: host: localhost pool: 6379 database: 0 cloud: #配置SpringCloudGateway的路由 gateway: routes: - id: product-service #保持唯一 uri: lb://service-product #lb://根据微服务名称从注册中心拉取服务请求路径 predicates: - Path=/product-service/** #将当前请求转发到http://127.0.0.1:9001/product/1 filters: #配置路由过滤器,将当前请求http://127.0.0.1:9001/product-service/product/1 --》 http://127.0.0.1:9001/product/1 - RewritePath=/product-service/(?<segment>.*), /$\{segment} #路径重写的过滤器,在yml中$写为$\
3.3.3 微服务名称转发?
请求路径:http://127.0.0.1:8080/service-product/product/1
注意:service-product : 是微服务模块名称 。
当前请求会自动根据我服务模块名称路由到不同的微服务。
server: port: 8080 #端口spring: application: name: api-gateway-server #服务名称 redis: host: localhost pool: 6379 database: 0 cloud: #配置SpringCloudGateway的路由 gateway: discovery: locator: enabled: true #开启根据微服务名称自动转发 lower-case-service-id: true #微服务名称以小写形式呈现
3.4 SpringCloudGateway过滤器分类?
Spring Cloud Gateway除了具备请求路由功能之外,也支持对请求的过滤。通过Zuul网关类似,也是通
过过滤器的形式来实现的。那么接下来我们一起来研究一下Gateway中的过滤器
3.3.1 过滤器基础
(1) 过滤器的生命周期
Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 的那么丰富,它只有两个:“pre” 和 “post”。
PRE : 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择
请求的微服务、记录调试信息等。
POST :这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP
Header、收集统计信息和指标、将响应从微服务发送给客户端等。
( 2) 过滤器类型
Spring Cloud Gateway 的 Filter 从作用范围可分为另外两种GatewayFilter 与 GlobalFilter。
GatewayFilter :应用到单个路由或者一个分组的路由上。
GlobalFilter :应用到所有的路由上。
3.3.2 局部过滤器
局部过滤器(GatewayFilter),是针对单个路由的过滤器。可以对访问的URL过滤,进行切面处理。在
Spring Cloud Gateway中通过GatewayFilter的形式内置了很多不同类型的局部过滤器。这里简单将
Spring Cloud Gateway内置的所有过滤器工厂整理成了一张表格,虽然不是很详细,但能作为速览使
用。如下:
每个过滤器工厂都对应一个实现类,并且这些类的名称必须以 GatewayFilterFactory 结尾,这是
Spring Cloud Gateway的一个约定,例如 AddRequestHeader 对应的实现类为
AddRequestHeaderGatewayFilterFactory 。对于这些过滤器的使用方式可以参考官方文档
3.3.3 全局过滤器
全局过滤器(GlobalFilter)作用于所有路由,Spring Cloud Gateway 定义了Global Filter接口,用户
可以自定义实现自己的Global Filter。通过全局过滤器可以实现对权限的统一校验,安全性验证等功
能,并且全局过滤器也是程序员使用比较多的过滤器。
Spring Cloud Gateway内部也是通过一系列的内置全局过滤器对整个路由转发进行处理如下:
3.4 统一鉴权
内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己
编写过滤器来实现的,那么我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验。
3.4.1 鉴权逻辑
开发中的鉴权逻辑:
当客户端第一次请求服务时,服务端对用户进行信息认证(登录)
认证通过,将用户信息进行加密形成 token,返回给客户端,作为登录凭证
以后每次请求,客户端都携带认证的 token
服务端对 token进行解密,判断是否有效。
3.5 网关授权的基本思路?
3.6 什么是ServerWebExchange对象主要有什么作用?
1.Gateway的拦截器
我们要在项目中实现一个拦截器,需要继承两个类:GlobalFilter, Ordered
GlobalFilter:全局过滤拦截器,在gateway中已经有部分实现,具体参照:https://www.cnblogs.com/liukaifeng/p/10055862.html
Ordered:拦截器的顺序,不多说
于是一个简单的拦截器就有了
@Slf4j@Componentpublic class AuthFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {return chain.filter(exchange); } @Override public int getOrder() { return -10; }}
Gateway的核心接口:GatewayFilter,GlobalFilter,GatewayFilterChain。具体介绍:https://www.cnblogs.com/bjlhx/p/9786478.html
Gateway的路由转发规则介绍:https://segmentfault.com/a/1190000019101829
2.简介
我们在使用Spring Cloud Gateway的时候,注意到过滤器(包括GatewayFilter、GlobalFilter和过滤器链GatewayFilterChain),都依赖到ServerWebExchange。
这里的设计和Servlet中的Filter是相似的,当前过滤器可以决定是否执行下一个过滤器的逻辑,由GatewayFilterChain#filter()是否被调用来决定。而ServerWebExchange就相当于当前请求和响应的上下文。
ServerWebExchange实例不单存储了Request和Response对象,还提供了一些扩展方法,如果想实现改造请求参数或者响应参数,就必须深入了解ServerWebExchange。
3.ServerWebExchange
ServerWebExchange的注释: ServerWebExchange是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。
其实,ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等,有点像Context的角色。
3.7 网关限流算法都有哪些?分别是什么?基本原理是什么?
-常用算法有三种:计数器算法、漏斗桶算法、令牌桶算法,市面上最常用的是最后一个
第一个:计数器算法
他维护的是单位时间内的最大请求量,因此极端情况可能造成服务抖动
第二个:漏斗桶算法,这种算法保护了后端的微服务,但是会可能造成微服务网关压力激增
第三种:令牌桶算法
令牌桶算法相对于漏斗桶算法,其实就是少了一个输出速率的设置,他与漏斗桶算法相比,主要是为了保护网关自己,由于网关在实际的应用场景中会显得非常关键,因此大部分的限流算法都会选择令牌桶算法
4、服务配置
4.1 什么是配置中心?
https://www.jianshu.com/p/e0595fb407d8
4.2 SpringCloudConfig的组成和工作原理?
- Spring Cloud Config 是一个解决分布式系统的配置管理方案,它包含了 server 和 client 两个部分。
- 原理与实现:https://zhuanlan.zhihu.com/p/135887780
4.3 配置中心服务端搭建步骤?
https://blog.csdn.net/weixin_43872111/article/details/117969759