目录
1.系统架构的演变
系统架构的演变过程(单体应用架构、垂直应用架构、分布式SOA架构、微服务架构)_程序猿洞晓的博客-优快云博客_架构演变过程 单体 垂直 soa 微服务
详细架构体系,如连接所讲
1.1单体应用架构
将业务的所有功能集中到一个项目中开发,打包部署,网站流量很小时使用
优点: 架构简单 部署成本低
缺点:耦合度高 后期升级,维护困难
1.2 分布式架构
这里没有提到垂直架构,因为垂直架构没有真正应用(只是一种单体过度到分布式架构)
分布式架构:根据业务功能对系统做拆分,每个业务功能模块作为独立项目开发,称为一个服务。
优点:降低业务之间的耦合 有利于业务的升级和拓展
缺点:服务调用关系复杂 服务容错差 运维难度变大
2.微服务简介
1.什么是微服务?
分布式:指“拆”,把一个完整的系统拆分成多个子系统,每个子系统提供不同的功能
微服务是一种经过良好设计的分布式架构
特征:
服务单一:一个服务只做一件事
服务自治:每个服务都可以有独立的团队,独立数据库,独立技术栈
服务通信:服务之间必须要有统一的协议
dubbo框架:默认 基于TCP的dubbo协议(远程调用性能强)
SpringCloud,默认使用http协议 (远程调用性能弱)
服务容错:能够容忍服务错误,避免出现服务雪崩
2.实现微服务的技术方案有哪些?
目前流行的有两套方案:
- SpringCloud技术体系
- dubbo架构体系
dubbo + zookeeper | SpringCloud |
---|---|
专注于服务治理与RPC调用 需要自己集成第三方组件、组装微服务方案 | 一整套微服务技术体系,生态强大 是微服务的一站式解决方案 |
原生的RPC,基于TCP协议 不灵活但性能强 | 使用rest api,基于HTTP协议。 性能稍弱但非常灵活 |
服务调用者和提供者依赖性太强,开发难度大 | 不存在代码级别的强依赖,开发难度低 |
Alibaba,商业公司,开源了很多技术产品 | Spring家族,专注于企业级开源框架的研发 |
国内互联网公司使用广泛 曾经是最火热的RPC框架 | 世界范围内都非常知名 Java程序员终究会成为Spring程序员 |
dubbo曾长期停更过 | 从出现到现在一直不断发展,活跃度很高 |
3.什么是SpringCloud?
SpringCloud是Spring团队(Pivotal)开源的一套微服务技术标准,目前广泛应用于微服务项目的开发中
SpringCloud不是一个框架,而是一套技术体系,它包含二十多个子框架,还在不断增加中
SpringCloud 于SpringBoot开箱即用的、一站式微服务解决方案的框架体系。目前已成为国内外使用最广泛的微服务框架。
常见的组件
SpringCloud的版本号:
-
早期的版本号:是以伦敦地铁站的名称作为版本号,比如:Hoxton、Greenwich等等,以首字母进行排序
-
从2020年开始:以
年.月.日
作为版本号
4.微服务技术点【重点】
4.1服务治理、服务注册、服务发现
1.服务治理:
服务治理:是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现。
2.服务注册:
在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中心登记自己提供服务的详情信息,并在注册中心中形成一个服务清单,服务注册中心需要以心跳的方式去检测清单中的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。
3.服务发现:
服务调用方向服务注册中心咨询服务,并获取所有服务的实例清单,实现对具体服务实例的访问。
4.2 Eureka注册中心
4.2.1 Eureka介绍
了解内容,后边有nacos注册中心替代,nacos注册中心比eureka注册中心更好用,更详细
Eureka是SpringCloud技术栈中提供的注册中心组件,他可以实现服务的自动注册,发现,状态监控
Eureka-Service就是服务注册中心,(可以是集群),对外暴露自己的地址
Eureka-Client:要把自己注册到注册中心的服务,是eureka服务的客户端
提供者:它启动后向Eureka注册自己信息(地址,服务名称等),并且定期进行服务续约(提供者定期通过http方式向Eureka刷新自己的状态)
消费者:它会定期去Eureka拉取服务列表,然后使用负载均衡算法选出一个服务进行调用。
4.2.2 Eureka 使用入门
搭建 Eureka-Service(搭建Eureka 服务端)
1.依赖
在父工程里,对SpringCloud进行版本锁定
<!-- springCloud版本锁定,使用Hoxton.SR10 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
在eureka-server模块里,添加eureka-server的坐标
<!--euraka服务端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.配置
server:
port: 8761 #Eureka服务的默认端口就是8761
spring:
application:
name: eureka-server #只要是微服务,就必须有应用名称
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka #自己的地址
fetch-registry: false #不从注册中心里拉取地址列表
register-with-eureka: false #不把自己注册到注册中心
3.引导类上添加 在引导类上要添加注解@EnableEurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
4.启动注册中心即可
打开浏览器 http://localhost:8761 可以查看eureka注册中心的控制台界面
整合Eureka-client (整合eureka客户端)
1.依赖
在微服务里添加eureka-client依赖坐标
<!-- Eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.配置
修改配置文件,添加eureka-service的地址
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka #注册中心的地址
3.引导类
在引导类上添加注解@EnableDiscoveryClient
,适合任意类型的注册中心,无论是Eureka还是Nacos
早期添加的是@EnableEurekaClient
,现在基本不用这个了,因为这个注解仅适用于Eureka
4.2.3 Eureka的运行原理【重点】
#还有一些参数配置信息
比如:修改续约时间 拉取时间等
4.2.4 Eureka集群【了解】
Eureka集群很简单 就是将多个Eureka服务器放在一起,并且互相同步数据
作为客户端,需要把信息注册到每个Eureka中。
3.修改引导类,添加注解@EnableDiscoveryClient
4.3 负载均衡Ribbon
4.3.1 什么是负载均衡
负载均衡指的是服务压力的平均分摊,避免某些服务超负荷运转,而其它服务空转
1.提供者负载均衡:主要指Nginx方向代理,在客户端发送请求时,对客户端请求的负载均衡处理
2.消费者负载均衡:主要Ribbon ,在服务之间调用时,实现负载均衡
4.3.2 Ribbon的使用
如果不做任何设置,默认就有负载均衡效果了:使用的是轮询策略
如果要修改负载均衡策略:
-
不需要导依赖,微服务的很多组件都内置了Ribbon
-
只要直接修改调用者一方的配置文件,设置负载均衡策略即可
#表示:在调用user-service服务时,使用RandomRule随机策略。如果不设置,默认使用的是轮询策略
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
4.3.3 开启负载均衡
负载均衡流程
4.3.4 负载均衡策略
Ribbon内置了多种负载均衡策略,内部负责复杂均衡的顶级 接口com.netflix.loadbalancer.IRule
内置负载均衡规则类 | 规则描述 |
---|---|
RoundRobinRule | 简单轮巡服务列表来选择服务器。它是Ribbon默认的负载均衡规则。 |
AvailabilityFilteringRule | 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的ActiveConnectionsLimit属性进行配置。 |
WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
ZoneAvoidanceRule | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 |
BestAvailableRule | 忽略哪些短路的服务器,并选择并发数较低的服务器。 |
RandomRule | 随机选择一个可用的服务器。 |
RetryRule | 重试机制的选择逻辑 |
4.3.5 饥饿加载和懒加载
懒加载:即第一次访问目标服务时,才会去创建LoadBalanceClient对象,会导致第一次请求时间比较长【Ribbon采用】
饥饿加载:当服务启动时,就立即拉取服务列表,并创建好LoadBalancerClient对象;这样的话,即使第一次远程调用时也不会花费很长时间
ribbon:
eager-load:
enabled: true #开启饥饿加载
clients: #要饥饿加载的服务列表
- user-service
4.4 Nacos 注册中心【重点】
4.4.1 Nacos 介绍
Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件,相比Eureka功能更加丰富,
Nacos =( Spring Cloud注册中心 + Spring Cloud配置中心) 【这里先注册中心】
4.4.2 Nacos 入门
启动Nacos
-
打开cmd,切换到Nacos的bin目录里
-
在cmd里输入命令
startup.cmd -d standalone
-
打开浏览器 输入 http://localhost:8848/nacos,打开nacos的控制台界面,输入帐号 nacos,密码nacos
微服务整合Nacos
1.依赖
在微服务父工程里锁定SpringCloudAlibaba的依赖版本。在dependencyManagement标签里加的
<!--SpringCloudAlibaba版本锁定-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springCloud版本锁定,使用Hoxton.SR10 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
在微服务里添加nacos-discovery的依赖坐标
<!--nacos-discovery依赖坐标-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.配置
在微服务的配置文件 application.yml 里添加
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos注册中心的地址
3.引导类
在引导类上添加注解@EnableDiscoveryClient
4.启动微服务
4.4.3 分级(区域) 存储
实际项目中,往往根据地域部署多套环境
-
服务调用尽可能选择本区域集群的服务,跨区域集群调用延迟较高
-
本区域集群不可访问时,再去访问其它区域集群
设置服务集群
(1)修改user-service的application.yml,添加如下内容:
设置服务区域集群名称
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
cluster-name: HZ #配置集群名称,也就是机房位置,例如:HZ,杭州 BJ SH
区域集群调用
(1)修改order-service中的application.yml,设置集群为HZ:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
cluster-name: HZ #配置集群名称,也就是机房位置,例如:HZ,杭州
(2)指定负载均衡策略
在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
4.4.4 Nacos的环境隔离
不同namespace的服务,是完全隔离的,不能互相访问
如何实现环境隔离:
-
在Nacos里创建命名空间
-
修改微服务的配置文件,设置微服务所属的namespace。注意设置的值是命名空间的id,而不是名称
4.4.5 Nacos 的运行原理【重点】{面试}
Nacos的服务实例分为两种类型
临时实例:如果服务实例不可用超过一定时间,注册中心会把服务地址剔除掉
永久实例(非临时实例):如果服务实例不可用,也不会从注册中心里剔除掉,而是标记为不健康
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
Nacos和Eureka的区别【面试】
1.相同:
Nacos 和 Eureka都可以作为 注册中心,都是用于进行服务治理的
都有服务注册,心跳续约,服务拉取等
2.不同:
Nacos支持服务端主动检测状态【非临时实例采用主动模式 20秒】,而Eureka不支持
Nacos支持服务列表变更的消息推送模式,服务列表更新更及时;Eureka不支持,服务列表更新不及时
Nacos集群支持AP和CP,而Eureka仅支持AP【后边】
4.5 远程调用 Feign
Feign是NetFlix提供的远程调用组件,因为使用比较麻烦,所以SpringCloud对Feign做了再封装,提供了open-feign
目的是为了实现优雅的远程调用,它可以使用SpringMVC的注解来实现远程调用
4.5.1 Feign 的使用
1.依赖(消费者)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.添加注解 在order-service的启动类添加注解开启Feign的功能:
@EnableFeignClients
在引导类上添加
@EnableFeignClients("包名")
,必须要能够扫描到Feign的接口
3.在order-service中新建一个接口
接口的命名通常是:XxxClient。比如是调用用户服务的接口,就可以叫UserClient
接口上加注解
@FeignClient("目标服务名称")
,表示这个接口里所有的方法,都是调用这个服务的接口里添加方法:要和被调用的目标方法完全相同
目标方法是@GetMapping,所以这个方法上也加@GetMapping
目标方法的路径是/user/{id},所以这个方法路径也设置为/user/{id}
目标方法的返回值是User,所以这个方法返回值也是User
目标方法的参数是
@PathVariable("id") Long id
,所以这个方法参数也写相同的最终在方法上配置完整:
发请求 GET http://user-service/user/{id}
得到结果封装成User对象
package cn.itcast.order.feign;
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("userservice")
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryById(@PathVariable("id") Long id);
}
Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。
4.5.2 Feign的日志
为了方便排查问题,可以让Feign输出日志
-
设置全局的日志级别为debug
-
设置Feign的日志级别。
Feign的四种日志级别:
-
NONE:不输出日志
-
BASIC:输出请求行和响应行信息
-
HEADERS:输出行和头信息
-
FULL:输出行、头和体信息
-
可以通过配置文件的方式
feign:
client:
config:
default:
loggerLevel: FULL #全局的Feign日志级别。FULL,HEADERS,BASIC,NONE
可以通过配置类 的方式
@Configuration
public class FeignConfig{
@Bean
public Logger.Level feignLogger(){
return Logger.Level.FULL;
}
}
4.5.3 Feign 的优化
Feign底层没有进行任何优化,使用JDK的URLConnection对象建立HTTP连接。每次远程调用都要创建连接,操作完成再关闭连接,非常消耗资源
如果想要提升性能,可以使用池化思想--http连接池
优化的步骤:
1.添加Apache的httpclient依赖坐标
<!--httpClient的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2.修改配置文件,在Feign远程调用时,启动httpclient的连接池支持
feign:
httpclient:
enabled: true #给Feign启动httpclient连接池的支持
max-connections: 200 #连接池的最大容量200个http连接
max-connections-per-route: 50 #每个功能路径最多同时占用50个连接
4.5.4 Feign负载均衡
什么都不做,使用Feign远程调用时默认就有负载均衡(默认内置了Ribbon),使用轮询策略
如果想要修改负载均衡策略,可以修改配置文件
ribbon:
ReadTimeout: 2500 # 数据通信超时时长 默认为1000
ConnectTimeout: 1500 # 连接超时时长 默认为1000
OkToRetryOnAllOperations: false # 是否对所有的异常请求(连接异常和请求异常)都重试 默认为false
MaxAutoRetriesNextServer: 1 # 重试多少次服务(实例)默认为1
MaxAutoRetries: 0 # 当前服务实例的重试次数 默认为0
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
4.6 网关 Gateway
网关是整个微服务的最前沿,是微服务的统一入口。客户端的请求必须经过网关的统一处理,由网关进行:
-
路由:把客户端请求,根据请求路径,分发到目标微服务上
-
过滤:对客户端的请求和响应进行处理,决定放行或者拦截不放行
4.6.1 Gateway使用入门
网关也是一个微服务,所以需要创建一个模块,准备好依赖、配置、引导类
1.依赖 在网关服务的pom.xml里添加nacos-discovery和gateway的依赖坐标
<dependencies>
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos-discovery依赖坐标-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2.配置
在网关服务里准备配置文件
server:
port: 10000
spring:
application:
name: app-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
- id: user #路由的唯一标识,可以不提供
uri: lb://user-service #路由的目的地。 lb表示负载均衡 lb://目标服务名称
predicates:
- Path=/user/** #什么样的请求,会被路径的uri目的地
- id: order
uri: lb://order-service
predicates:
- Path=/order/**
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/开头就符合要求
3.引导类 中添加 @EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
4.客户端访问
浏览器发请求,要请求到网关,由网关帮我们把请求路由到目标服务
http://localhost:10000/order/101
4.6.2 Gateway 断言工厂【了解】
我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
例如Path=/user/**是按照路径匹配,这个规则是由
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory
类来
处理的,像这样的断言工厂在SpringCloudGateway还有十几个:
名称 | 说明 | 示例 |
---|---|---|
After | 是某个时间点后的请求 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | 是某个时间点之前的请求 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | 是某两个时间点之前的请求 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | 请求必须包含某些cookie | - Cookie=chocolate, ch.p |
Header | 请求必须包含某些header | - Header=X-Request-Id, \d+ |
Host | 请求必须是访问某个host(域名) | - Host=.somehost.org,.anotherhost.org |
Method | 请求方式必须是指定方式 | - Method=GET,POST |
Path | 请求路径必须符合指定规则 | - Path=/red/{segment},/blue/** |
Query | 请求参数必须包含指定参数 | - Query=name, Jack或者- Query=name |
RemoteAddr | 请求者的ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
Weight | 权重处理 |
4.6.3 Gateway 过滤器工厂
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:
网关Gateway提供了两类过滤器:
-
局部过滤器(网关过滤器GatewayFilter):由网关Gateway提供好了一批局部过滤器,我们需要使用哪个,直接配置就可以使用了
-
全局过滤器(GlobalFilter):让我们自定义实现过滤器的
局部过滤器
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters: # 过滤器
- AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
过滤器工厂 | 作用 | 参数 |
---|---|---|
AddRequestHeader | 为原始请求添加Header | Header的名称及值 |
AddRequestParameter | 为原始请求添加请求参数 | 参数名称及值 |
AddResponseHeader | 为原始响应添加Header | Header的名称及值 |
DedupeResponseHeader | 剔除响应头中重复的值 | 需要去重的Header名称及去重策略 |
Hystrix | 为路由引入Hystrix的断路器保护 | HystrixCommand 的名称 |
FallbackHeaders | 为fallbackUri的请求头中添加具体的异常信息 | Header的名称 |
PrefixPath | 为原始请求路径添加前缀 | 前缀路径 |
PreserveHostHeader | 为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host | 无 |
RequestRateLimiter | 用于对请求限流,限9流算法为令牌桶 | keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus |
RedirectTo | 将原始请求重定向到指定的URL | http状态码及重定向的url |
RemoveHopByHopHeadersFilter | 为原始请求删除IETF组织规定的一系列Header | 默认就会启用,可以通过配置指定仅删除哪些Header |
RemoveRequestHeader | 为原始请求删除某个Header | Header名称 |
RemoveResponseHeader | 为原始响应删除某个Header | Header名称 |
RewritePath | 重写原始的请求路径 | 原始路径正则表达式以及重写后路径的正则表达式 |
RewriteResponseHeader | 重写原始响应中的某个Header | Header名称,值的正则表达式,重写后的值 |
SaveSession | 在转发请求之前,强制执行WebSession::save 操作 | 无 |
secureHeaders | 为原始响应添加一系列起安全作用的响应头 | 无,支持修改这些安全响应头的值 |
SetPath | 修改原始的请求路径 | 修改后的路径 |
SetResponseHeader | 修改原始响应中某个Header的值 | Header名称,修改后的值 |
SetStatus | 修改原始响应的状态码 | HTTP 状态码,可以是数字,也可以是字符串 |
StripPrefix | 用于截断原始请求的路径 | 使用数字表示要截断的路径的数量 |
Retry | 针对不同的响应进行重试 | retries、statuses、methods、series |
RequestSize | 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large | 请求包大小,单位为字节,默认值为5M |
ModifyRequestBody | 在转发请求之前修改原始请求体内容 | 修改后的请求体内容 |
ModifyResponseBody | 修改原始响应体的内容 | 修改后的响应体内容 |
全局过滤器
* 如果要自定义全局过滤器,步骤:
* 1. 创建Java类,实现GlobalFilter和Ordered接口
* 2. 重写接口的方法
* GlobalFilter接口定义的方法filter:用于编写过滤的逻辑
* Ordered接口定义的方法getOrder:用于定义过滤器的执行顺序
* 3. 在类上添加注解@Component
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。
public interface GlobalFilter {
/**
* 处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
*
* @param exchange 请求上下文,里面可以获取Request、Response等信息
* @param chain 用来把请求委托给下一个过滤器
* @return {@code Mono<Void>} 返回标示当前过滤器业务结束
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
@Order(-1) 数字越小,过滤器的优先级越高,执行的越早
4.6.3 跨域问题
协议,域名,端口三者中任意一者不同即为跨域
在gateway服务的application.yml文件中,添加下面的配置:
spring:
cloud:
gateway:
# 。。。
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
4.7 配置中心 Nacos
统一配置管理
当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。我们需要一种统一配置管理方案,可以集中管理所有实例的配置。
Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
4.7.1 入门步骤:
4.7.2 从微服务拉取配置
微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。
但如果尚未读取application.yml,又如何得知nacos地址呢?
因此spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
1.导依赖
首先,在user-service服务中,引入nacos-config的客户端依赖:
<!--nacos配置管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2)添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml文件,内容如下:
spring:
application:
name: userservice # 服务名称
profiles:
active: dev #开发环境,这里是dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos地址
config:
file-extension: yaml # 文件后缀名
4.7.3 配置热更新【了解】
修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新。
要实现配置热更新,可以使用两种方式:
1.在@Value注入的变量所在类上添加注解@RefreshScope:
2.
使用@ConfigurationProperties注解代替@Value注解。
在user-service服务中,添加一个类,读取patterrn.dateformat属性:
package cn.itcast.user.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}