SpringCloud
微服务框架(其实由很多公司开源出来的组件收录整合而成),基于SpringBoot自动装配的特性,SpringBoot也实现了微服务的整合,如此才容易得到推广。

组件
版本兼容问题
SpringCloud要使用必须保证有与之匹配的SpringBoot版本(官网查阅)
像Hoxton.SR10大于SR5,则Hoxton对应SpringBoot版本2.3.X。否则不兼容报错

微服务治理的服务拆分包括注册发现、远程调用、配置管理



声明式的http请求调用客户端,而且内部实现了负载均衡

声明式:只需要一个注解声明就能实现功能,类比注解开启事务
引入依赖

添加@EnableFeignClients注解

编写FeignClient接口

使用FeignClient中定义的方法代替RestTemplate

SpringBoot能够自动装配,但是呢也能允许我们覆盖重写一些“对象”的配置。
对于Feign来说可以修改的配置主要是以下内容:
一般是配置日志,其他的没啥必要,而且记录日志也是要消耗性能的,所以一般都是将日志等级设置为basic或者null
修改配置的方法有两种:

①为什么需要性能优化
Feign底层发送http请求的客户端实现:
URLConnection:默认实现(jdk),不支持连接池.
Apache HttpClient:支持连接池(Spring的默认实现)
OKHttp:支持连接池
因此优化Feign的性能主要包括:
完成性能优化一般修改配置后需要进行压测来确定具体的数值设定
②案例:Feign添加HttpClient的支持

所谓最佳实践就是大量公司企业在不断踩坑的情形下经验积累出使用Feign的最佳开发方案
【继承】让controller和FeignClient继承同一接口

【抽取/封装】将FeignClient、POJO、Feign的默认配置都定义到一个项目中,供所有消费者使用
冗余度高,如果抽取东西过多,其它一个小业务模块就会引入很多不相关的东西。但更为规范。

流程总结
实现最佳实践方式二的步骤如下:
1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖
2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
3.在order-service中引入feign-api的依赖
4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
5.重启测试
步骤实现
1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖
2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中

3.在order-service中引入feign-api的依赖

4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
5、注意事项,指定扫描
当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用。 即SpringBoot默认只在自己的应用范围内扫描包(只有扫描到而且扫描到类上有交付处理的注解才会被SpringBoot当成Bean进行管理,这样才能在调用处正确自动装配)
有两种方式解决:
方式一:指定Feignclient所在包
方式二:指定FeignClient字节码(用到才导(数组)指定加载的客户端无需扩大包扫描的范围) ✔️

方式二案例:

在Eureka架构中,微服务角色有两类:
架构图:


在客户端(相对)
IDEA模拟多实例注册:右键选择复制一份配置然后并在窗口中选择命令行添加
-DServer.port=未被使用的端口来启动。-D表示添加命令行参数。
服务拉取是基于服务名称获取服务列表,然后再对服务器列表做负载均衡


主要由IRule接口定义负载均衡的选择(内含随机等各种算法)

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则
默认选择实现的是zoneAvoidanceRule这个类——>通过配置类修改选择均衡的策略

策略含义

有两种

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。
而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过修改配置文件ribbon-eager-load-enabled:true设置为开启饥饿加载


阿里巴巴提供的,比Eureka更为丰富(多出了集群概念),它并没有内嵌到SpringCloud中,需要单独安装和启动
Nacos遵循SpringCloud接口的开发规范——>服务注册和Eureka类似——>只需改依赖就行(区分服务端和客户端依赖)
startup.cmd -m standalone
因为Nacos默认是集群启动,所以如果想要单个启动需要加上其余参数,如上

分三级
模型抽象图
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高本地集群不可访问时,再去访问其它集群

配置集群
在配置文件中添加spring.cloud.nacos.discovery.cluster-name属性

和Eureka一样基于IRule接口实现负载均衡策略,设置均衡策略方式一样是通过修改配置属性

和Eureka不一样的是Eureka有一个专门的策略NacosRule负载均衡策略

NacaosRule默认就是按集群选择实例列表然后随机选择,但是如果一个集群里边的实例有些老机器和新机器,自然希望老机器的访问量少一点新机器访问量多一点来分担压力——>解决方案:权重设置
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离——>将业务相关的服务和数据至于同一个Group里边。【非必须】

在控制台创建一个新的namespace(自动生成唯一id)



在IDEA项目配置文件中添加新的属性字段通过唯一id进行环境隔离

之后Nacos控制台就会显示新创建的namespace,默认都属于public空间

且不同命名空间的实例将不能相互访问。
Nacos与eureka的共同点
Nacos与Eureka的区别
Nacos更加细节
也可以更加主动,不过一般是临时实例来减轻服务器的负担

临时实例和非临时实例的设置(配置文件spring-cloud-nacos-discovery-ephemeral:false 设置为非临时实例)

微服务成百上千之后我们不可能单独去修改一个配置文件,不仅修改麻烦更新也麻烦——>所以我们将配置交由配置中心进行统一管理就像注册中心一样,而恰巧,Nacos不仅能作为注册中心同时也能充当配置中心完成配置管理服务
我们只是把一些重要的信息配置到Nacos中以便“热更新”而不是把微服务的所有配置都交由Nacos进行管理
反之,注册中心和配置管理也是可以单独出来进行管理

直接在控制台创建即可

设置配置内容时只需要把部分“热更新”相关的配置写进去

配置获取的逻辑设计

代码实现

Nacos配置更改后,微服务可以实现热更新,方式有二:
例子: 通过@ConfigurationProperties注入,自动刷新
Nacos统一管理配置

配置类封装映射配置属性

程序调用读取配置

微服务启动时会从nacos读取多个配置文件:【微服务启动时的加载顺序】
[spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml[spring.application.name].yaml,例如: userservice.yaml无论profile如何变化,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件

小结
微服务会从nacos读取的配置文件:
[服务名]-[spring.profile.active].yaml,环境配置[服务名].yaml,默认配置,多环境共享但是要注意配置文件的优先级,优先级高的将覆盖优先级低的配置
优先级:[服务名]-[环境].yaml>[服务名].yaml>本地配置
大公司肯定不会只有一个Nacos服务器,为保证高可用他们会购置多台服务器来搭建Nacaos集群

详细步骤:
小结:
搭建MySQL集群并初始化数据库表
Nacos官方提供了标准的SQL创建,用来记录数据库信息
下载解压nacos
修改集群配置(节点信息)、数据库配置

数据库配置:修改application.properties文件,添加数据库配置。【告知:指定mysql集群,数据库数量、数据库连接配置】
构建数据库集群保证数据库读写都在集群中完成保证数据共享一致性。

分别启动多个nacos节点
我们可以直接拷贝之前创建的nacos文件夹,然后依次修改application.properties文件的nacos对外服务端口Service.port,然后分别启动模拟不同主机启动了nacos服务。直接在bin目录下执行startup.cmd即可,默认是集群启动。

nginx反向代理
作为gateway用来实现对Nacos的负载均衡。以下配置都要在config目录中的http作用域中配置生效。

之后就可以通过网关Nginx访问我们的集群
之后的配置管理都将持久化到数据库中

微服务治理还有一个重要事项就是统一网关
身份认证和权限校验
服务路由、负载均衡
请求限流

在SpringCloud中网关的实现包括两种:
gateway
zuul
Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。
网关是一个独立的服务,所以需要新建模块,引入相关依赖,配置文件设置相关配置,再启动类启动网关服务。
搭建网关服务的步骤:
1.创建项目(模块),引入nacos服务发现和gateway依赖

2.配置application.yml,包括服务基本信息、nacos地址、路由
路由配置包括:
路由id:路由的唯一标示
路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
路由断言(predicates) :判断路由的规则,
路由过滤器((filters) :对请求或响应做处理
3.通过启动类启动网关服务
抽象图

网关路由可以配置的内容包括:

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
例如Path=/user/**是按照路径匹配,这个规则是由
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的
像这样的断言工厂在SpringCloudGateway还有十几个,主要用的是Path,具体情况分析官方文档现查。

问答
PredicateFactory的作用是什么?
读取用户定义的断言条件,对请求做出判断
Path=/user/**是什么含义?
路径是以/user开头的就认为是符合的
Spring提供了31种不同的路由过滤器工厂,都有不同的过滤规则,具体参见官方文档。

分为当前过滤器和全局过滤器,在配置文件中根据层级的不同,作用范围也就不同。
配置当前过滤器

配置默认过滤器【全局】

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
区别在于GatewayFilter通过配置定义,处理逻辑是固定的。
而GlobalFilter的逻辑需要自己写代码实现。定义方式是实现GlobalFilter接口。
实现全局过滤器的步骤
示例:

Tip:
按照orderId从小到大的顺序执行,当大小相同则按优先级来:默认过滤器——路由过滤器——全局过滤器
分析:

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器
网关中提供了一个过滤器适配器,有一个GatewayFilterAdapter类实现了GatewayFilter接口,它可以将全局过滤器类型转换成GatewayFilter类型,当前过滤器和默认过滤器在底层其实也相似,他们最终都会转换成GatewayFilter类型,所以他们可以放到一个集合
每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
当过滤器的order值一样时,会按照defaultFilter >路由过滤器>GlobalFilter的顺序执行。

首先微服务内部是不会产生跨域问题的,所以只需要对网关进行跨域处理。
跨域:域名不一致就是跨域,主要包括:
跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题解决方案: CORS

网关封装好的处理方案,只需进行配置皆可

关于CORS跨域要配置的参数包括哪几个?会CV就行。