🌻🌻 目录 🌻🌻
- [一、SpringCloud Alibaba](#一、SpringCloud Alibaba)
- [1.1、SpringCloud Alibaba 简介](#1.1、SpringCloud Alibaba 简介)
- [1.2、SpringCloud Alibaba-Nacos[作为注册中心]](#1.2、SpringCloud Alibaba-Nacos[作为注册中心])
- [1.2.1 将微服务注册到 nacos 中](#1.2.1 将微服务注册到 nacos 中)
- [1.2.2 服务注册到 nacos,远程调用](#1.2.2 服务注册到 nacos,远程调用)
- [1.3、SpringCloud Alibaba-Nacos[作为配置中心]](#1.3、SpringCloud Alibaba-Nacos[作为配置中心])
- [1.4、nacos 进阶](#1.4、nacos 进阶)
- [1.5、网关 Gateway](#1.5、网关 Gateway)
一、SpringCloud Alibaba
1.1、SpringCloud Alibaba 简介
1)、简介
Spring Cloud Alibaba
致力于提供微服务开发的一站式解决方案
。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
- 依托
Spring Cloud Alibaba
,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
- 官网:https://spring.io/projects/spring-cloud-alibaba
- 社区:https://sca.aliyun.com/
- SpringCloud Alibaba github :https://github.com/alibaba/spring-cloud-alibaba
2)、为什么使用
SpringCloud
的几大痛点
SpringCloud
部分组件停止维护和更新,给开发带来不便;
SpringCloud
部分环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制
SpringCloud
配置复杂,难以上手,部分配置差别难以区分和合理应用
SpringCloud Alibaba
的优势:阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用
成套的产品搭配完善的可视化界面给开发运维带来极大的便利,搭建简单,学习曲线低。
结合 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,即分布式事务解决方案
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
4)、项目中的依赖- 在
common
项目中引入如下。进行统一管理
xml
在 common 项目中引入如下。进行统一管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
1.2、SpringCloud Alibaba-Nacos[作为注册中心]
Nacos
是阿里巴巴开源的一个更易于构建云原生
应用的动态服务发现 、配置管理 和服务管理 平台。他是使用java
编写。需要依赖 java 环境
Nacos 文档地址: https://nacos.io/zh-cn/docs/quick-start.html
1.2.1 将微服务注册到 nacos 中
应用接入: https://github.com/alibaba/spring-cloud-alibaba/
- 1、首先,打开
gulimall-common
修改pom.xml
文件,引入 Nacos Discovery Starter。
xml
<!--服务发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 2、官网下载 nacos-server
- https://github.com/alibaba/nacos/releases 或 https://nacos.io/download
- 本地资源库获取
双击startup.cmd
直接启动 :
在浏览器访问:http://127.0.0.1:8848/nacos
用户名/密码 都是nacos
- 3、在应用的
/src/main/resources/application.yml
配置文
件中配置 Nacos Server 地址
xml
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
- 4、使用
@EnableDiscoveryClient
开启服务注册发现功能
java
@EnableDiscoveryClient //需要注册的这里都要加上去,如下的 gulimall-member,gulimall-order
@SpringBootApplication
public class GulimallCouponApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallCouponApplication.class, args);
}
}
为其余都添加上:
- 5、在应用的 /src/main/resources/application.properties 配置文
件中配置 Nacos Server 地址
xml
#注意:每一个应用都应该有名字,这样才能注册上去。修改 application.yml 文件
#需要注册的都要配置
spring:
application:
name: gulimall-coupon
- 为其余都添加上:
application.yml
- 6、在
idea
中启动应用,观察nacos
服务列表是否已经注册上服务
- 7、启动
nacos-server
- ◼ 双击
bin
中的startup.cmd
文件- ◼ 访问
http://localhost:8848/nacos/
- ◼ 使用默认的
nacos/nacos
进行登录
1.2.2 服务注册到 nacos,远程调用
注册更多的服务上去,测试使用 feign
远程调用
- Feign 使用三步
1、导包 openfeign
2、编写接口,进行远程调用
3、开启@EnableFeignClients 功能- 1、导包 openfeign(
前面已经引入了
)
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 2、编写接口,进行远程调用
java
//2.远程服务
@RequestMapping("/member/list")
public R couponmember(){
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("优惠券满减,满200减100");
return R.ok().put("coupons", Arrays.asList(couponEntity));
}
创建接口:
java
package com.gansu.gulimall.member.feign;
import com.gansu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("gulimall-coupon")
public interface CouponFeignService {
//2.远程服务
@RequestMapping("copupon/coupon/member/list")
public R couponmember();
}
- 3、开启@
EnableFeignClients
功能
java
//开启远程调用功能
@EnableFeignClients(basePackages = "com.gansu.gulimall.member.feign")
- 4、测试(启动服务,访问:
http://localhost:8000/member/member/coupons
)
java
@Autowired
private CouponFeignService couponFeignService;
@RequestMapping("/coupons")
public R test(){
MemberEntity memberEntity = new MemberEntity();
memberEntity.setNickname("张三");
R couponmember = couponFeignService.couponmember();
return R.ok().put("member",memberEntity).put("coupons",couponmember.get("coupons"));
}
- 4、测试(关闭(类似挂掉)服务
gulimall-coupon
,再次访问:http://localhost:8000/member/member/coupons
)
- 6、更多配置
1.3、SpringCloud Alibaba-Nacos[作为配置中心]
参考 官网文档:
- 1、pom.xml 引入 Nacos Config Starter。
xml
<!--服务注册-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 2、在应用的 /src/main/resources /
bootstrap.properties
配置文件中配置Nacos Config
元数据
xml
spring.application.name=nacos-config-example
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#主要配置应用名和配置中心地址
- 3.1 之前是这样配置的:
xml
coupon.user.name=Daniel
coupon.user.age=22
- 3.2 有了nacos现在就直接在界面添加了:
- ① 创建配置
- ② 发布创建修改的配置
- 测试:动态获取配置(刷新配置)
xml
@RefreshScope
/**
* 1、如何使用Nases作为配置中心统一管理配置
* 1)引入依赖,
* <!--服务注册-->
* <dependency>
* <groupId>com.alibaba.cloud</groupId>
* <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
* </dependency>
* 2)创建-个bootstrap.properties。
* spring.application.name=nacos-config-example
* spring.cloud.nacos.config.server-addr=127.0.0.1:8848
* 3)需要给配置中心默认添加一个叫 数据集(Data Id)gulimall-coupon.properties。默认规则,应用名.properti给 应用名.properties 添加任何配置
* 4)动态获取配置。
* @Refreshscope:动态获取并刷新配置@Value("${配置项的名}"):获取到配置。如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置。
*/
@Value("${coupon.user.name}")
private String name;
@Value("${coupon.user.age}")
private Integer age;
@RequestMapping("/test")
public R test(){
return R.ok().put("name",name).put("age",age);
};
5.启动服务,修改配置参数再次查看显示
http://localhost:7000/copupon/coupon/test
再次查看你:
1.4、nacos 进阶
1.4.1、核心概念
命名空间:
- 用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的
Group
或Data ID
的
配置。Namespace
的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生
产环境的资源(如配置、服务)隔离等。
*1)、命名空间:配置隔离;
*默认:public(保留空间);默认新增的所有配置都在public空间。
*1、开发,测试,生产:利用命名空间来做环境隔离。注意:在bootstrap.properties;配置上,需要使用哪个命名空间下的配置,
spring.cloud.nacos.config.namespace=df5f3ec1-ff43-4e4b-8748-89a26557dc1f
*2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名空间下的所有配置
① 查看默认的命名空间(2.4.2这里不显示默认的,建议用之前的1.1.3
)
② 添加命名空间 (dev:开发命名空间,prod:生产命名空间
)
③ 切换到命名空间 dev,并且在命名空间dev下面创建配置,如下所示:
dev:开发命名空间,prod:生产命名空间
④ 在idea中 bootstrap.properties
中添加配置
⑤ 重启服务浏览器查看
http://localhost:7000/copupon/coupon/test
配置集 ID:
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如
com.taobao.tc.refund.log.level
)的命名规则保证全局唯一性。此命名规则非强制。
2)、配置集:所有的配置的集合
3)、配置集TD:类似文件名。Data Ip:类似文件名
配置分组:
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和MQ_topic 配置。
4)、配置分组:默认所有的配置集都属于:DEFAULT_GROUP;比如双11,618,双12
每个微服务创建自己的命名空间,使用配置分组区分环境,dev,test,prod
① 创建分组及配置
xml
coupon.user.name=1111
coupon.user.age=1111
② 在idea中 bootstrap.properties
中添加配置
⑤ 重启服务浏览器查看
http://localhost:7000/copupon/coupon/test
1.4.2、加载多配置文件
详细拆分配置如下:
- ① 数据源配置
- ② mybatis-plus配置
- ③ 剩余的配置
④ 最终配置显示
⑤ 注释掉
application.properties
里面的文件,随意开启一个服务进行测试,如gulimall-product
1.5、网关 Gateway
1.5.1、简介
网关作为流量的入口,常用功能包括
路由转发
、权限校验
、限流控制
等。而springcloud gateway
作为 SpringCloud 官方推出的第二代 网关框架,取代了 Zuul 网关。
- 网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的 API,以降低管理成本和安全风险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。
Spring Cloud Gateway
旨在提供一种简单而有效的方式来对 API 进行路由,并为他们提供切面,例如:安全性,监控/指标 和弹性等。- 官方文档地址:
https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/how-it-works.html
Spring Cloud Gateway 特点:
- ⚫ 基于
Spring5
,支持响应式编程和SpringBoot2.0
- ⚫支持使用任何请求属性进行路由匹配
- ⚫特定于路由的断言和过滤器
- ⚫ 集成
Hystrix
进行断路保护- ⚫ 集成服务发现功能
- ⚫ 易于编写
Predicates
和Filters
- ⚫ 支持请求速率限制
- ⚫ 支持路径重写
思考:
为什么使用 API 网关?
- API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:
- ⚫客户端会多次请求不同的微服务,增加了客户端的复杂性。
- ⚫存在跨域请求,在一定场景下处理相对复杂。
- ⚫认证复杂,每个服务都需要独立认证。
- ⚫ 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。
- ⚫某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。
- 以上这些问题可以借助
API
网关解决。API
网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过API
网关这一层 。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做
,这样既提高业务灵活性又不缺安全性:
使用 API 网关后的优点如下:
易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
- ⚫易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
- ⚫减少了客户端与各个微服务之间的交互次数。
1.5.2、核心概念
- ⚫路由。路由是网关最基础的部分,路由信息有一个 ID、一个目的 URL、一组断言和一组Filter 组成。如果断言路由为真,则说明请求的 URL 和配置匹配
- ⚫断言 。
Java8 中的断言函数
。Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配来自于 http request 中的任何信息,比如请求头和参数等。- ⚫过滤器。一个标准的 Spring webFilter。Spring cloud gateway 中的 filter 分为两种类型的Filter,分别是 Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理
工作原理:
- 客户端发送请求给网关,网关
HandlerMapping
判断是否请求满足某个路由,满足就发给网关的WebHandler
。这个WebHandler
将请求交给一个过滤器链,请求到达目标服务之前,会执行所有过滤器的 pre
方法。请求到达目标服务处理之后再依次执行所有过滤器的 post 方法。- 一句话 :
满足某些断言(predicates)就路由到指定的地址(uri),使用指定的过滤器(filter)
1.5.3、使用
1、创建网关子模块
gulimall-gateway
,引入网关
- ① 创建 子模块
gulimall-gateway
- ② 创建 子模块
gulimall-gateway
- ③ 搜索
gateway
如下
- ④ 统一版本引入依赖如下
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- ⑤ 分别配置nacos服务发现(
application.properties
)和服务配置(bootstrap.properties
)
yml
spring:
application:
name: gulimall-gateway
- ⑥ 在
gulimall-gateway
下面创建application.properties
,application.yml
,bootstrap.properties
参考官网:https://docs.spring.io/spring-cloud-gateway
在 gulimall-gateway
下面创建 application.properties
, application.yml
,bootstrap.properties
application.properties
xml
server.port=88
spring.application.name=gulimall-gateway
spring.cloud.nacos.server-addr=127.0.0.1:8848
application.yml
xml
spring:
application:
name: gulimall-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
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
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.10.100:3306/gulimall_sms
username: root
password: root
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
bootstrap.properties
xml
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=68c8750d-50cc-4655-a8b9-bccb38ac99d4
- ⑦ 不开启数据关联
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
启动测试:
http://localhost:88/hello?url=baidu
https://qq.com/hello