1、SpringCloud Alibaba
1.1、SpringCloud Alibaba 简介
1.1.1、简介
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用 微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布 式应用服务。 依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用 接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
1.2使用SpringCloud的原因
1.2.1SpringCloud 的几大痛点
- SpringCloud 部分组件停止维护和更新,给开发带来不便;
- SpringCloud 部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
- SpringCloud 配置复杂,难以上手,部分配置差别难以区分和合理应用
1.2.2SpringCloud Alibaba 的优势:
- 阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用
- 成套的产品搭配完善的可视化界面给开发运维带来极大的便利
- 搭建简单,学习曲线低。
1.2.3结合 SpringCloud Alibaba 我们最终的技术搭配方案:
- SpringCloud Alibaba - Nacos:注册中心(服务发现/注册)
- SpringCloud Alibaba - Nacos:配置中心(动态配置管理)
- SpringCloud - Ribbon:负载均衡
- SpringCloud - Feign:声明式 HTTP 客户端(调用远程服务)
- SpringCloud Alibaba - Sentinel:服务容错(限流、降级、熔断)
- SpringCloud - Gateway:API 网关(webflux 编程模式)
- SpringCloud - Sleuth:调用链监控
- SpringCloud Alibaba - Seata:原 Fescar,即分布式事务解决方案
1.2.3、版本选择
由于 Spring Boot 1 和 Spring Boot 2 在 Actuator 模块的接口和注解有很大的变更,且 spring-cloud-commons 从 1.x.x 版本升级到 2.0.0 版本也有较大的变更,因此我们采取跟 SpringBoot 版本号一致的版本:
- 1.5.x 版本适用于 Spring Boot 1.5.x
- 2.0.x 版本适用于 Spring Boot 2.0.x
- 2.1.x 版本适用于 Spring Boot 2.1.x
1.2.4 项目中的依赖
在 common 项目中引入如下。进行统一管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、SpringCloud Alibaba-Nacos[作为注册中心]
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。他是使用 java 编写。需要依赖 java 环境 Nacos 文档地址: https://nacos.io/zh-cn/docs/quick-start.html
2.1、下载 nacos-server
下载地址:https://github.com/alibaba/nacos/releases
2.2、启动 nacos-server
- 双击 bin 中的 startup.cmd 文件
- 访问 http://localhost:8848/nacos/
- 使用默认的 nacos/nacos 进行登录
2.3 将微服务注册到 nacos 中
- 首先,修改 pom.xml 文件,在common模块中引入nacos注册中心的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 在配置文件中配置 Nacos Server 地址,这里以gulimall-coupon服务为例
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
- 使用@EnableDiscoveryClient 开启服务注册发现功能
@MapperScan("com.atguigu.gulimall.coupon.dao")
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallCouponApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallCouponApplication.class, args);
}
}
- 启动应用,观察 nacos 服务列表是否已经注册上服务
注意:每一个应用都应该有名字,这样才能注册上去。修改 application.yml 文件
spring:
application:
name: gulimall-coupon
2.4 OpenFeign远程调用的步骤
2.4.1 将服务注册进nacos
Nacos 使用三步
- 导包 nacos-discovery
- 写配置,指定 nacos 地址,指定应用的名字
- 开启服务注册发现功能@EnableDiscoveryClient
2.4.2 OpenFeign的使用
2.4.2.1. 导入open-feign依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.4.2.2. 编写一个接口,告诉spring-cloud这个接口需要调用远程服务
比例在gulimall-member下面编写一个远程调用接口 声明接口的每一个方法都是调用哪个远程服务的哪个请求例如:如果调用了CouponFeignService就会去nacos中寻找gulimall-coupon这个微服务,调用/coupon/coupon/member/list接口
package com.atguigu.gulimall.member.feign;
import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
@GetMapping("/coupon/coupon/member/list")
public R memberCoupons();
}
2.4.2.3. 开启远程调用功能
- 声明OpenFeign所在的包
@EnableFeignClients(basePackages = "com.atguigu.gulimall.member.feign")
public class GulimallMemberApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallMemberApplication.class, args);
}
}
- 编写接口尝试远程调用
@RestController
@RequestMapping("member/memberlevel")
public class MemberLevelController {
@Autowired
private CouponFeignService couponFeignService;
@RequestMapping("/test")
public R test(){
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("张三");
R r = couponFeignService.memberCoupons();
return R.ok().put("member",memberEntity).put("coupons",r.get("coupons"));
}
- 效果展示
在gulimall-member微服务中国成功调用了gulimall-coupon的微服务
3、SpringCloud Alibaba-Nacos[作为配置中心]
使用spring-cloud-alibaba作为配置中心的好处:可以进行统一管理配置
- gulimall-common的pom.xml 引入 Nacos Config Starter依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 创建一个bootstrap.properties并进行相关的配置
bootstrap.properties的优先级高于application.properties和application.yml
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
- 在application.yml中进行配置
name: smile
age: 18
-
给配置中心默认添加一个叫 数据集(Data-Id)gulimall-coupon.properties。默认规则 应用名.properties -
给应用名.properties添加任何配置 可以进行值的添加或修改,点击发布 -
动态获取配置 @RefreshScope,动态获取并刷新配置 @Value(“${配置项的名}”) 获取到配置 gulimall-coupon模块下
@RestController
@RequestMapping("/test")
@RefreshScope
public class TestController {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
@GetMapping("/one")
public R one(){
return R.ok().put("age",age).put("name",name);
}
}
如果配置中心和当前应用的配置文件都配置了相同的项,默认有限使用配置中心的配置,修改配置后,获取的配置项的值也会发生改变
3.1 核心概念
3.1.1 命名空间(配置隔离)
默认:public(保留空间),默认新增的所有配置都在public空间
- 开发、测试、生产用命名空间来做环境隔离
注意需要在bootstrap.properties中配置需要使用那个命名空间的配置,默认使用的是public名称空间 例如使用test命名空间
spring.cloud.nacos.config.namespace=baeb40f9-3404-415a-93b9-b0f7bf5747d5
- 每一个微服务之间相互配置隔离,每一个微服务都创建自己的名称空间,只加载自己命名空间下的所有配置
3.1.2 配置集(所有配置的集合)
一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配 置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级 别等配置项。
3.1.3 配置集 ID(类似文件名)
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有 意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名 规则保证全局唯一性。此命名规则非强制。
3.1.4 配置分组
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个 配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置 分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。 默认所有的配置集都属于:DEFAULT_GROUP 每个微服务创建自己的命名空间,使用配置分组区分环境:dev,test,prod 可以在bootstrap.properties中进行配置
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.cloud.nacos.config.namespace=baeb40f9-3404-415a-93b9-b0f7bf5747d5
3.1.5 同时加载多个配置集
- 微服务加载任何配置信息,任何配置文件都可以放在配置中心
- 在需要在bootstrap.properties说明加载配置中心哪些配置文件即可
- 以前springboot任何方法从配置文件中获取值都可以使用
配置中心优先使用配置中心中的配置
4. Gateway
4.1、简介
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而 springcloud gateway 作为 SpringCloud 官方推出的第二代网关框架,取代了 Zuul 网关。 网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的 API,以降低管理 成本和安全风险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。 Spring Cloud Gateway 旨在提供一种简单而有效的方式来对 API 进行路由,并为他们提供切 面,例如:安全性,监控/指标 和弹性等。
4.2Spring Cloud Gateway 特点:
- 基于 Spring5,支持响应式编程和 SpringBoot2.0
- 支持使用任何请求属性进行路由匹配
- 特定于路由的断言和过滤器
- 集成 Hystrix 进行断路保护
- 集成服务发现功能
- 易于编写 Predicates 和 Filters
- 支持请求速率限制 ? 支持路径重写
API 网关是介于客户端和服务器端之间的中间层, 所有的外部请求都会先经过 API 网关这一层。也就是说,API 的实现方面更多的考虑业务 逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性: 使用 API 网关后的优点如下:
- 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在 每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
4.3 核心概念
4.3.1路由
路由是网关最基础的部分,路由信息有一个 ID、一个目的 URL、一组断言和一组 Filter 组成。如果断言路由为真,则说明请求的 URL 和配置匹配
4.3.2 断言
Java8 中的断言函数。Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框 架中的 ServerWebExchange。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配 来自于 http request 中的任何信息,比如请求头和参数等。
4.3.3过滤器。
一个标准的 Spring webFilter。Spring cloud gateway 中的 filter 分为两种类型的 Filter,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理
4.4工作原理
客户端发送请求给网关,弯管 HandlerMapping 判断是否请求满足某个路由,满足就发给网 关的 WebHandler。这个 WebHandler 将请求交给一个过滤器链,请求到达目标服务之前,会执行所有过滤器的 pre 方法。请求到达目标服务处理之后再依次执行所有过滤器的post方法。 一句话:满足某些断言(predicates)就路由到指定的地址(uri),使用指定的过滤器(filter)
4.4.1断言的规则
4.5 实例演示
- 创建一个gulimall-gateway的项目
- 添加相关的依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-getway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gulimall-getway</name>
<description>Api网关</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.atguigu.gulimall</groupId>
<artifactId>gulimall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- 在yml中编写网关的配置文件
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url,qq
说明:当路径url=baidu是跳转到www.baidu.com,当url=qq是跳转到www.qq.cocm 4. 测试 注意:各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路 由匹配。 ? 一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
|