目录
前情提要:
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,强烈建议你的版本和笔者一模一样,不然后面会启动不了项目!!!!!
springboot版本2.6.13 所对应的springcloudalibaba的版本为:2021.0.1.0
pom.xml依赖配置
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.0.1.0
pom
import
Nacos(NAming COnfiguration Service):服务注册和配置中心
下载地址:
https://github.com/alibaba/nacos/releases/download/2.0.4/nacos-server-2.0.4.zip
地域 物理的数据中心,资源创建成功后不能更换。
可用区 同一地域内,电力和网络互相独立的物理区域。同一可用区内,实例的网络延迟较低。
接入点 地域的某个服务的入口域名。
命名空间 用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 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) 能正常工作。
服务注册与服务框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|---|---|---|
Eureka | AP高可用 | 支持 | 低(2.x版本闭源) |
Zookeeper | CP一致 | 支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP+CP | 支持 | 高 |
并在此文件夹下执行命令
.\startup.cmd -m standalone
http://localhost:8848/nacos/index.html
接着登陆即可用户名和密码都是nacos
不用看上图直接复制下面的代码就不会出错!!!
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
新建配置文件并加入以下的内容
server:
port: 8000
spring:
application:
name: nacos-provider
cloud:
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;
}
}
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
新建配置文件并加入以下的内容
server:
port: 8001
spring:
application:
name: nacos-provider
cloud:
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;
}
}
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
org.springframework.cloud
spring-cloud-starter-loadbalancer
3.1.1
启动类
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 {
@Autowired
RestTemplate 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);
}
}
然后再次打开
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作为配置中心的微服务工程中,通过nacos提供的公共open api,可以看官方的
Open API 指南 (nacos.io),对已经有的配置文件的内容进行修改,或者使用可视化的nacos页面对配置文件进行修改。
还是刚刚的那个工程父项目,我们新建模块
依赖引入
org.springframework.cloud
spring-cloud-starter-bootstrap
3.0.2
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-netflix-ribbon
控制器
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-client
cloud:
nacos:
discovery:
# Nacos服务注册中心地址
server-addr: localhost:8848
enabled: true
config:
# 指定Nacos配置中心的地址
server-addr: localhost:8848
file-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 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
把它放到一个地方然后直接
java -jar sentinel-dashboard-2.0.0-alpha-preview.jar就可以运行了
浏览器访问 localhost:8080
用户名密码都是 sentinel
在springcloud的中使用sentinel
新建项目选择如下的依赖项
删除掉示例文件
完整的pom.xml文件
4.0.0
com.sentinel
SprngCloudSentinel
0.0.1-SNAPSHOT
SprngCloudSentinel
SprngCloudSentinel
1.8
UTF-8
UTF-8
2.6.13
2021.0.5.0
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-alibaba-sentinel-datasource
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
${spring-cloud-alibaba.version}
pom
import
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
UTF-8
org.springframework.boot
spring-boot-maven-plugin
${spring-boot.version}
com.sentinel.sprngcloudsentinel.SprngCloudSentinelApplication
repackage
repackage
修改配置文件,只保留这个
# 应用服务 WEB 访问端口
server.port=8090
新建application.yml文件
spring:
application:
name: my-sentinel-client
cloud:
nacos:
discovery:
enabled: true
server-addr: localhost:8848
sentinel:
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可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
阈值类型/单机值:
QPS(每秒钟的请求数量):当调用该api就QPS达到阈值的时候,进行限流
线程数.当调用该api的线程数达到阈值的时候,进行限流
是否集群:不需要集群
流控模式:
流控效果:
常用策略组合
鼠标快速点击刷新多次
回到我们的控制器改代码
@GetMapping("/testA")
public String testA() {
try {
// 让当前线程停留2秒方便测试开多个线程
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "----testA";
}
同样的步骤新建流控
启动后打开两个不同浏览器的窗口,注意一定要不同!!,不能是同一个浏览器的2个窗口!!!!!!!!!!!!!!!!
快速刷新2个 即可看到效果!
删除上次的策略
修改控制器
@GetMapping("/testA")
public String testA() {
return "----testA";
}
新建策略
好像演示不出来,鹅鹅鹅额,反正是那个意思,就是如果超出A的阈值的一瞬间,B也会失败,注意是一瞬间
未完待续.....