谷粒商城20-27 Nacos&Gateway网关
为什么使用SpringCloudAlibaba?
SpringCloud
部分组件停止维护和更新,给开发带来不便
SpringCloud
部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
SpringCloud
配置复杂,难以上手,部分配置差别难以区分和合理应用
SpringCloudAlibaba的优势?
阿里使用过的组件经历了考验,性能强悍,设计合理,给开发带来了极大的便利
搭建简单,学习成本低,可视化界面好
结合SpringCloudAlibaba的最终技术搭配方案
SpringCloudAlibaba-Nacos
:注册中心(服务发现/注册)
SpringCloudAlibaba-Nacos
:配置中心(动态配置管理)
SpringCloud-Ribbon
:负载均衡
SpringCloud-Feign
:声明式HTTP客户端(调用远程服务)
SpringCloudAlibaba-Sentinel
:服务容错(限流、降级、熔断)
SpringCloud-Gateway
:API网关(webflux
编程模式)
SpringCloud-Sleuth
:调用链监控
SpringCloudAlibaba-Seata
:原Fescar
,即分布式事务解决方案
SpringCloudAlibaba源码地址
如何整合Nacos?
学习最快的方式就是看官方文档啦😊
首先我们需要统一下
SpringBoot&SpringCloud&SpringCloudAlibaba
版本号,防止出现一些不合常规的问题,以下配置是建立在SpringBoot 2.3.10.RELEASE
版本基础上
1 | <properties> |
Nacos官方文档地址:
1、将spring-cloud-starter-alibaba-nacos-discovery
添加到pom.xml中
1 | <dependency> |
需要注意的是,如果你使用的是
SpringBoot2.4.x
版本,因为负载均衡不再是使用ribbon
而是使用spring-cloud-loadbalancer
,所以我们需要排除ribbon
并引入loadbalancer
,如果使用的跟我一样是SpringBoot2.3.x
版本,则无需这一步
1 | <dependency> |
2、在application.yml
中配置Nacos
的服务地址,也就是Nacos
注册中心的地址,这里我是在windows中直接通过客户端启动,所以地址为127.0.0.1:8848
1 | spring: |
这里我们需要先获取到一个Nacos Server
注册中心的服务地址
- 在
github
中下载Nacos Server
,建议选择Latest release稳定版 - 下载后解压,双击
Nacos\bin\startup.bat
,就开启了一个Nacos Server
,默认端口是在我们本机的8848
端口
这里需要注意:
如果你使用的是1.4.1或更高版本,则默认模式为集群模式
我们需要打开
nacos\bin\startup.bat
文件,将如下内容
1 set MODE="cluster"修改为单机模式
1 set MODE="standalone"
3、在启动类上使用@EnableDiscoveryClient
注解,开启服务注册与发现功能,开启后才能将服务注册到Nacos
中,其他服务才能通过接口调用到你提供的服务
1 |
|
4、在application.yml
中添加spring.application.name
名字,该名字会作为服务名在nacos
中显示,例如:
1 | spring: |
运行SpringBoot
启动类,我们可以在http://localhost:8848/nacos查看服务是否注册成功,默认登录的账号密码均为`nacos`,登录成功后,在左侧`服务管理-服务列表`中可以查看到注册成功的服务
OpenFeign远程调用服务
如果我们想要远程调用服务,我们需要如下几步:
1、在pom.xml
中添加OpenFeign
的依赖,这里我统一放到common
公共模块中统一管理
1 | <dependency> |
2、编写一个接口,告诉SpringCloud
这个接口需要调用远程服务,并声明接口的每一个方法都是调用哪个远程服务的请求
建议在
controller
包同级下创建一个feign
目录,在feign
包路径下创建Interface接口例如:我想要在
会员服务
中调用上优惠券服务
,那么我们就在会员服务中刚刚创建的fegin
目录中,创建一个OrderFeginService.java
接口(接口名字随意起 没有要求)
1 | // 给CouponController中添加一个测试接口 用于给会员服务调用获取优惠券信息 |
需要注意的是:这里通过
@FeignClient
标注你调用的是哪个服务,其中的coupon-provider
是对应服务在yml
中配置的spring.application.name
的名称同时需要注意,接口需要与服务中的接口保持一致,且调用路径需要写全路径,即如果你在
Controller
中标注了统一的路径,也需要一起加到地址中,否则会提示无法找到
3、在启动类上开启远程调用功能注解支持@EnableFeignClients
,默认扫描的是当前所在工程目录下标注了@FeginClient
的接口,也可以basePackages
标注feign
所在的包
1 |
|
4、在MemberController
中注入刚刚编写的接口CouponFeginService
,并编写测试方法调用CouponController
中的测试方法
1 |
|
5、依次启动优惠券服务
与会员服务
,浏览器调用会员服务接口地址,请换成你们自己的端口
浏览器响应结果如下:
1 | {"msg":"success","code":0,"data":{"couponName":"满100减50"}} |
到此为止,我们就成功从会员服务
调用到了订单服务
为什么要接入Nacos Config
如果我们的代码中有一部分是从配置文件中读取的,每次修改后都需要重新打包项目在进行调用接口才能看到效果,如果我们部署了很多台机器,每次这样重新修改打包后在发布调用是很繁琐的
如何接入Nacos Config作为配置中心
1、在pom.xml
中引入Nacos Config Starter
1 | <dependency> |
2、在resources
目录下,创建一个bootstrap.properties
配置文件,配置如下信息,需要注意的是,如果已经在application.yml
中配置了spring.application.name
,那么可以不配或要保持一致
1 | nacos-config-example = |
3、在调用了配置文件的Controller
类上,使用@RefreshScope
注解来动态刷新配置文件,配合@Value
来获取配置文件中的值,配置中心有的,优先使用配置中心
1 |
|
4、之后打开Nacos Server
,依次点开左侧配置管理
节点下的配置列表
,点击右上方➕添加一条配置
Data ID
:为spring.application.name
加上properties
,即xxxx.properties
如按照上方配置,则为
coupon-provider.properties
Group
:默认即可DEFAULT_GROUP
,也可以自行输入其他名字分组,例如:1111、618等节日
配置格式
:YAML配置后没获取到,可能需要手动指定YAML格式,这里我选择properties
配置内容
:根据选择的配置格式进行编写,例如:coupon.name=满100-80
5、编写完成后,点击发布即可,以后想要修改值的时候,只需要在nacos
配置中心中修改配置内容即可,而无需重新启动项目即可看到修改后的值
Nacos Config相关细节
1、命名空间:配置隔离
默认新增的所有配置都在public命名空间中
如果将来存在多个配置环境,例如:开发、测试、生产环境
那么我们就需要新建多个命名空间,推荐每一个微服务都创建一个命名空间
首先我们在Nacos左侧
命名空间
菜单中新增一个dev
环境然后在
配置列表
上方能看到新增的dev
分组,之后选择该分组进行创建配置文件,规则同public
最后在
bootstrap.properties
中配置namespace
,值为该命名空间的id
1 | e6ad418d-65b6-4a46-9d73-1ccde42240af = |
2、配置集
一组相关或不相关配置项的集合就叫配置集
3、配置集ID
类似于配置文件名,在
Nacos
中体现的是Data ID
,即应用名+properties
4、配置分组
默认所有的配置集都属于:DEFAULT_GROUP分组
如果需要修改分组,我们可以在
bootstrap.properties
中配置如下信息,值为组名
1 | 1111 = |
Nacos配置中心加载多配置集
以前我们将所有的配置文件都放到了一个配置文件中,时间久了这个配置文件就会很大且不够清晰,所以我们可能将跟数据源相关的放到datasource.yml
中,跟mybatis
相关的放到mybatis.yml
中,将一个大的配置文件拆分成多个小的配置文件
那么我们如何才能实现上述效果呢?
我们只需要在Nacos
中配置多个对应的配置文件后,在bootstrap.properties
中配置如下信息
1 | # 配置ext-config为List集合 所以依此类推[1]、[2]…… |
Spring Cloud GateWay网关
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等
SpringCloudGateWay
提供一种简单有效的方式对API
进行路由,并为他们提供切面
我们无需去关心后台的情况,哪些服务是否能正常提供服务,网关可以帮我们动态的路由到每一个服务中;同时网关可以为我们做鉴权、限流、日志等服务,我们就无需在每一个微服务中都写一部分相同的代码来进行处理了
网关由ID
、目标URI
、断言规则
、过滤器
来决定一个请求是否能路由到某个地方,只有最后断言的结果为true
时,才能将请求成功的路由到指定位置
断言为Java8中提供的断言型函数式
接口,可以根据任何请求头
或者请求参数
中的信息,来判断是否满足路由规则,判断成功那么就能路由到指定位置
过滤器与之前Spring中的过滤器功能基本一致,在请求或响应之前或之后都可以进行修改
综上我们可以明白一个完整的流程如下:
当
客户端
想要发送请求到目标服务
时,中间会经过API网关
,客户端先将请求发给API网关
,会先来到Gateway Handler Mapping
查看映射信息能否被路由或被处理,如果能被处理则会将请求转发给每一个Handler
处理器进行处理,在处理器处理前会经过大量的Filter
过滤器进行筛选,之后才能成功请求到目标服务
,当目标服务
处理完成后,在按照相同流程返回给客户端
我们可以在官方手册中找到大量的predicate
或者filter
规则,可以直接根据示例进行配置
整合Spring Cloud GateWay网关
1、新建SpringBoot
项目或Maven
项目,导入GateWay
相关starter
依赖
1 | <dependency> |
2、在启动类上使用注解@EnableDiscoveryClient
开启服务注册与发现
1 |
|
3、在application.yml
配置nacos
的服务注册地址、应用名及服务端口
1 | server: |
4、在bootstrap.properties
中配置nacos
的配置中心地址
1 | localhost:8848 = |
5、因为我们还依赖了公共模块common
,其中有对MyBatis
的引用,启动的时候会提示我们去yml
中添加数据源相关的配置,所以我们在启动类中排除对DataSource
的配置操作
1 |
|
6、现在我们的网关已经在88端口
正常启动了
Spring Cloud GateWay网关配置示例
现在我们有这样一个需求,当我发送请求的时候,会跟一个url地址,如果是baidu则跳转到www.baidu.com,如果是qq则跳转到www.qq.com
那么我们需要在yml
文件中增加如下配置
详情可参考官方手册
query-route-predicate-factory
部分讲解
1 | spring: |
Query
后第一个值表示查询参数名
,第二个值可以写字符串,且支持正则表达式匹配规则,表示对应参数的值,如果匹配到参数未url且值为指定值的时候,就会跳转到配置的uri地址
所以如上配置后,我们在浏览器发送不同的请求就会来到不同的页面
例如:
发送请求
localhost:88?url=baidu
跳转到www.baidu.com发送请求
localhost:88?url=qq
跳转到www.qq.com