> 文章列表 > SpringCloudAliBaba学习(一)

SpringCloudAliBaba学习(一)

SpringCloudAliBaba学习(一)

目录

前情提要:

1 新建Nacos父工程

1.1 下载Nacos

1.2 Nacos的专业术语

1.3  与其他注册中心对比

2 使用Nocas

2.1 下载完成后进入bin文件夹

2.2 打开浏览器访问

2.3 构建提供者nacos-provider8000

2.4 当前的模块引入依赖nacos的依赖

2.5 再构建一个服务提供者

2.6  配置依赖

2.7 创建消费者

2.8 依赖配置

2.9 启动3个项目

Nacos配置中心

1 配置中心是什么?

2 使用场景?

3 怎么使用?

分生产环境配置

分组配置 

分命名空间配置

集群和持久化配置

持久化配置

集群部署

Sentinel实现熔断与削峰

安装使用sentinell

使用sentinel进行流量控制

1 QPS+快速+直接失败

2 并发+直接+快速失败

3  QPS+关联+快速失败


前情提要:

springboot版本为:2.6.13,强烈建议你的版本和笔者一模一样,不然后面会启动不了项目!!!!!

1 新建Nacos父工程

springboot版本2.6.13 所对应的springcloudalibaba的版本为:2021.0.1.0

pom.xml依赖配置

    <dependencyManagement><dependencies><!-- spring cloud alibaba 2021.0.1.0--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.1.0</version><type>pom</type><scope>import</scope></dependency></dependencyManagement>

1.1 下载Nacos

Nacos(NAming COnfiguration Service):服务注册和配置中心 

下载地址:
https://github.com/alibaba/nacos/releases/download/2.0.4/nacos-server-2.0.4.zip

1.2 Nacos的专业术语

  • 地域 物理的数据中心,资源创建成功后不能更换。

  • 可用区 同一地域内,电力和网络互相独立的物理区域。同一可用区内,实例的网络延迟较低。

  • 接入点 地域的某个服务的入口域名。

  • 命名空间 用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

  • 配置 在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。

  • 配置管理 系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动。

  • 配置项 一个具体的可配置的参数与其值域,通常以 param-key=param-value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。

  • 配置集 一组相关或者不相关的配置项的集合称为配置集。在系统中,一个配置文件通常就是一个配置集,包含了系统各个方面的配置。例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。

  • 配置集 ID Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。

  • 配置分组 Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。

  • 配置快照 Nacos 的客户端 SDK 会在本地生成配置的快照。当客户端无法连接到 Nacos Server 时,可以使用配置快照显示系统的整体容灾能力。配置快照类似于 Git 中的本地 commit,也类似于缓存,会在适当的时机更新,但是并没有缓存过期(expiration)的概念。

  • 服务 通过预定义接口网络访问的提供给客户端的软件功能。

  • 服务名 服务提供的标识,通过该标识可以唯一确定其指代的服务。

  • 服务注册中心 存储服务实例和服务负载均衡策略的数据库。

  • 服务发现 在计算机网络上,(通常使用服务名)对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。

  • 元信息 Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。

  • 应用 用于标识服务提供方的服务的属性。

  • 服务分组 不同的服务可以归类到同一分组。

  • 虚拟集群 同一个服务下的所有服务实例组成一个默认集群, 集群可以被进一步按需求划分,划分的单位可以是虚拟集群。

  • 实例 提供一个或多个服务的具有可访问网络地址(IP:Port)的进程。

  • 权重 实例级别的配置。权重为浮点数。权重越大,分配给该实例的流量越大。

  • 健康检查 以指定方式检查服务下挂载的实例 (Instance) 的健康度,从而确认该实例 (Instance) 是否能提供服务。根据检查结果,实例 (Instance) 会被判断为健康或不健康。对服务发起解析请求时,不健康的实例 (Instance) 不会返回给客户端。

  • 健康保护阈值 为了防止因过多实例 (Instance) 不健康导致流量全部流向健康实例 (Instance) ,继而造成流量压力把健康实例 (Instance) 压垮并形成雪崩效应,应将健康保护阈值定义为一个 0 到 1 之间的浮点数。当域名健康实例数 (Instance) 占总服务实例数 (Instance) 的比例小于该值时,无论实例 (Instance) 是否健康,都会将这个实例 (Instance) 返回给客户端。这样做虽然损失了一部分流量,但是保证了集群中剩余健康实例 (Instance) 能正常工作。

1.3  与其他注册中心对比

服务注册与服务框架 CAP模型 控制台管理 社区活跃度
Eureka AP高可用 支持 低(2.x版本闭源)
Zookeeper CP一致 支持
Consul CP 支持
Nacos AP+CP 支持

2 使用Nocas

2.1 下载完成后进入bin文件夹

并在此文件夹下执行命令

 .\\startup.cmd -m standalone

2.2 打开浏览器访问

http://localhost:8848/nacos/index.html

接着登陆即可用户名和密码都是nacos

2.3 构建提供者nacos-provider8000

在当前的目录下新建模块nacos-provider8000

2.4 当前的模块引入依赖nacos的依赖

 不用看上图直接复制下面的代码就不会出错!!!

        <!--SpringCloud Alibaba nacos 服务发现依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

新建配置文件并加入以下的内容

server:port: 8000spring:application:name: nacos-providercloud:nacos:discovery:server-addr: localhost:8848

主启动类替换这么的内容

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient
@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}}

控制器

package com.example.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Provider1Controller {//获取配置文件中的端口@Value("${server.port}")Integer port;@GetMapping("/findById/{id}")public String findById(@PathVariable("id")Integer id){//业务逻辑return "nacos provider.port:"+port+"|id:"+id;}
}

2.5 再构建一个服务提供者

2.6  配置依赖

<dependencies><!--SpringCloud Alibaba nacos 服务发现依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies>

新建配置文件并加入以下的内容

server:port: 8001
spring:application:name: nacos-providercloud:nacos:discovery:server-addr: localhost:8848

主启动类替换这么的内容

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient
@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}}

控制器

package com.example2.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Provider1Controller {//获取配置文件中的端口@Value("${server.port}")Integer port;@GetMapping("/findById/{id}")public String findById(@PathVariable("id")Integer id){//业务逻辑return "nacos provider.port:"+port+"|id:"+id;}
}

2.7 创建消费者

2.8 依赖配置

 <!--SpringCloud Alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId><version>3.1.1</version></dependency>

 启动类

package com.example2;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient
@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class, args);}}

配置类

package com.example2.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestTemplateConfig {@Bean@LoadBalanced //loadbalancer 客户端负载均衡public RestTemplate restTemplate(){return new RestTemplate();}
}

控制器

package com.example2.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
@RequestMapping("/con")
public class Consumer1Controller {@AutowiredRestTemplate restTemplate;@GetMapping("/add/{id}")public String add(@PathVariable("id")Integer id){//业务逻辑String url="http://nacos-provider/goods/findById/"+id;return restTemplate.getForObject(url, String.class);}
}

2.9 启动3个项目

然后再次打开

http://localhost:8848/nacos/index.html

 

可以看到已经出现了,两个服务者,一个消费者了

然后打开

localhost:9000/con/add/1

不停的刷新链接可以看到有时候是这样这个

有时候是这样这个

这是负载均衡的一个体现!!

Nacos的特性大全。

A:可用性 C:一致性 P:分区容错性

Nacos默认AP。

切换CP:

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

插播:分布式系统有两大主题:分区和副本。分区(Partition)是为了解决扩展性的问题——如何拆分工作负载、让多个节点分工合作。副本(Replication)则是为了解决高可用的问题,对于一个包含成百上千台节点的系统来说,宕机一台是家常便饭的事情,整个系统必须在这种情况下保持可用性。 

OK 到目前为止注册中心的内容已经入门完成了。

最终是这样的目录,下面我们 学习配置中心的内容,注意注册中心和配置中心不是一个东西

Nacos配置中心

1 配置中心是什么?

统一管理各种应用配置的基础服务组件

2 使用场景?

在使用nacos作为配置中心的微服务工程中,通过nacos提供的公共open api,可以看官方的

Open API 指南 (nacos.io),对已经有的配置文件的内容进行修改,或者使用可视化的nacos页面对配置文件进行修改。

3 怎么使用?

还是刚刚的那个工程父项目,我们新建模块

 依赖引入

<!--        bootstrap引导程序--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.0.2</version></dependency>
<!--        nacos配置中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--SpringCloud Alibaba nacos服务发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency>

控制器

package conf.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/updateConf")
public class CsController {@Value("${a}")private String configInfo;@GetMapping("/info")public String getConfigInfo() {return configInfo;}
}

启动类

package conf;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient
public class NacosClientApplication {public static void main(String[] args) {SpringApplication.run(NacosClientApplication.class, args);}
}

新建配置文件bootstrap.yml

bootstrap.yml,在存在该文件时,会优先加载改文件数据,bootstrap的意思是“引导程序”。所以不要改为其他的名字!!!!

server:port: 8082
spring:application:name: nacos-config-clientcloud:nacos:discovery:# Nacos服务注册中心地址server-addr: localhost:8848enabled: trueconfig:# 指定Nacos配置中心的地址server-addr: localhost:8848file-extension: yml # 指定yml格式的配置 默认properties

新建application.yml

spring:profiles:active: dev

回到我们的ncaosweb软件

 点击+

新建一个dataid

内容为:spring配置的名字-环境名.配置文件的扩展名

例如: 

nacos-config-client-dev.yml

你可以在下面的位置中找到他们。

 

 

 然后配置配置文件的内容,我这里测试输入

回到项目启动。

浏览器访问:localhost:8082/updateConf/info

以下为正常的结果:

分生产环境配置

使用dataid(默认就是)

通过配置配置文件中的这个,就能分成不同的环境了; 

分组配置 

使用group

在nacos的web端中新建配置文件时可以通过更改group来形成不同的分组。

配置文件

分命名空间配置

使用namespace来进行配置,通过也和配置group一起使用 

 最后3着也都是相互独立的,看场景规模的大小选择使用即可

集群和持久化配置

在nacos0.7以后就支持将nacos中的配置数据等等持久化到mysql数据库中了,主要作用是便于观察与读取修改!

持久化配置

新建数据库,注意数据库,版本要求:5.6.5+

运行SQL文件

 运行完成后大致是这么些表

 修改nacos的配置文件 

spring.datasource.platform=mysql### Count of DB:
db.num=1### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_db1?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=xxxx

然后保存重启nacos就可以了。

然后我们再运行我们的springcloud项目

我们这时候使用nacos新建一个配置文件

返回数据库发现有数据了

集群部署

没有设备略..

Sentinel实现熔断与削峰

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

安装使用sentinell

把它放到一个地方然后直接

java -jar sentinel-dashboard-2.0.0-alpha-preview.jar就可以运行了

浏览器访问 localhost:8080

用户名密码都是 sentinel

 登陆完成就是

在springcloud的中使用sentinel

新建项目选择如下的依赖项

删除掉示例文件

完整的pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.sentinel</groupId><artifactId>SprngCloudSentinel</artifactId><version>0.0.1-SNAPSHOT</version><name>SprngCloudSentinel</name><description>SprngCloudSentinel</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version><spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.sentinel.sprngcloudsentinel.SprngCloudSentinelApplication</mainClass>
<!--                    <skip>true</skip>--></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

修改配置文件,只保留这个

# 应用服务 WEB 访问端口
server.port=8090

 新建application.yml文件

spring:application:name: my-sentinel-clientcloud:nacos:discovery:enabled: trueserver-addr: localhost:8848sentinel:transport:dashboard: localhost:8080# 默认8719端口,假如被占用了会自动从8719端口+1进行扫描,直到找到未被占用的 端口port: 8719

新建控制器

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/get")
public class CSController {@GetMapping("/testA")public String testA() {return "----testA";}@GetMapping("/testB")public String testB() {return "----testB";}}

启动8090,然后刷新sentinel后台页面(因为sentinel采用懒加载策略,所以需要调用服务后才在后台显示) 在浏览器分别输入

这里可以多刷新几次(多请求几次)

,然后刷新sentinel后台页面:

使用sentinel进行流量控制

相关概念:

  • 资源名:唯一名称,默认请求路径

  • 针对来源:sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)

  • 阈值类型/单机值:

    • QPS(每秒钟的请求数量):当调用该api就QPS达到阈值的时候,进行限流

    • 线程数.当调用该api的线程数达到阈值的时候,进行限流

  • 是否集群:不需要集群

  • 流控模式:

    • 直接:api达到限流条件时,直接限流。分为QPS和线程数
    • 关联:当关联的资到阈值时,就限流自己。别人惹事,自己买单
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
  • 流控效果:

    • 快速失败:直接抛异常 Blocked by Sentinel (flow limiting)
    • warm up:根据codeFactor(冷加载因子,默认3)的值,从阈值codeFactor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以均匀的速度通过,阈值类型必须设置为QPS,否则无效

常用策略组合

1 QPS+快速+直接失败

配置如下:

鼠标快速点击刷新多次 

​ 

2 并发+直接+快速失败

 回到我们的控制器改代码

    @GetMapping("/testA")public String testA() {try {// 让当前线程停留2秒方便测试开多个线程Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}return "----testA";}

同样的步骤新建流控

​启动后打开两个不同浏览器的窗口,注意一定要不同!!,不能是同一个浏览器的2个窗口!!!!!!!!!!!!!!!!

快速刷新2个 即可看到效果!

3  QPS+关联+快速失败

删除上次的策略

修改控制器

@GetMapping("/testA")
public String testA() {return "----testA";
}

新建策略

​ 

​ 

好像演示不出来,鹅鹅鹅额,反正是那个意思,就是如果超出A的阈值的一瞬间,B也会失败,注意是一瞬间 

未完待续.....