前面一些架构演进知识,总是老生常谈,在此就不多做赘述了,具体可看我未完结的博客SpringCloud(遗憾的未完结系列…)和Dubbo(超级无敌认真好用,万字收藏篇!!!)这篇文章
文章目录
SpringCloudAlibaba上(Nacos,Ribbon,Fegin,Nacos-config)
前言
spring-cloud-alibaba:目前 Spring Cloud 生态中最活跃、开发体验最好的实现。
springcloud生态对比
1 Springcloud环境搭建(创建父项目spring-cloud-alibaba)
本demo用的
springboot版本:2.3.12.RELEASE
,
springcloud版本:Hoxton.SR12
,
springcloud-alibaba版本:2.2.9.RELEASE
引入依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jiazhong.springcloudalibaba</groupId>
<artifactId>spring-cloud-alibabba</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>Order</module>
<module>stock</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>2.3.12.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.9.RELEASE</spring.cloud.alibaba.version>
</properties>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- spring-cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring-boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring-cloud-alibaba-->
<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.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2 Nacos(对标注册中心和配置中心)
内扣死
-
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台
Nacos 的关键特性包括:
① 服务发现和服务健康监测
② 动态配置服务
③ 动态DNS服务
④ 服务及其元数据管理
2.1 Nacos discovery(服务注册发现)
Nacos Discovery Starter 可以帮助您将服务自动注册到 Nacos 服务端并且能够动态感知和刷新某个服务实例的服务列表。除此之外,Nacos Discovery Starter 也将服务实例自身的一些元数据信息-例如 host,port,健康检查URL,主页等-注册到 Nacos
2.1.1 Nacos Service 部署(Windows)
- 下载对应版本安装包,这里是2.1.0Windos版本的
https://github.com/alibaba/nacos/releases
- 解压
-
因为默认是集群的,新手学习改成单机的
set MODE="standalone"
- 修改配置文件
conf/application.properties
里面可以配,上下文路径,端口号,数据源存储
-
单机startup.cmd启动nacos
启动成功进入nacos页面:http://169.254.182.169:8848/nacos/index.html
默认账号密码都i为: nacos
2.1.2 Nacos client 搭建
① 创建三个服务生产者-stock_8001(stock_8003,stock_8002)
此处仅为stock_8002,其他两个同
-
引入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--nacos 服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
-
配置
server: port: 8002 #应用名称,(服务名称) spring: application: name: stock-service cloud: #配置nacos nacos: server-addr: 169.254.182.169:8848 discovery: #配置用户名和密码 username: nacos password: nacos namespace: public
-
Controller
@RestController @RequestMapping("/stock") public class StockController { @Value("${server.port}") private String port; @RequestMapping("/del") public String del() { System.out.println("库存减少!!!"); return port+"库存减少!!!"; } }
-
启动类
@SpringBootApplication @EnableDiscoveryClient public class Stock_8001 { public static void main(String[] args) { SpringApplication.run(Stock_8001.class); } }
② 创建服务消费者-order_7001
-
引入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--nacos 服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
-
配置
server: port: 7001 #应用名称,(服务名称) spring: application: name: order-service cloud: #配置nacos nacos: server-addr: 169.254.182.169:8848 discovery: #配置用户名和密码 username: nacos password: nacos namespace: public
-
Controller
@RestController @RequestMapping("/order") public class OrderController { @Resource private RestTemplate restTemplate; private static final String STOCK_URL ="http://stock-service"; @RequestMapping("/add") public String add(){ String message = restTemplate.getForObject(STOCK_URL + "/stock/del", String.class); System.out.println("下单成功!!!"); return "下单成功!!!"+message; } }
-
启动类
@SpringBootApplication @EnableDiscoveryClient public class Order_7001 { public static void main(String[] args) { SpringApplication.run(Order_7001.class); } @Bean @LoadBalanced//必须配置负载均衡 public RestTemplate restTemplate(){ return new RestTemplate(); } }
-
雪崩保护
- 保护阈值:设置0-1之间的值;
- 临时实例:
spring.cloud.nacos.discovery.ephemeral=fasle
当为永久实例,服务宕机,也不会从服务列表剔除; - 健康实例/总实例<保护阈值,依然会将不健康实例拿给服务消费者用
2.1.3 注册中心配置项详解
配置项 | Key | 默认值 | 说明 |
---|---|---|---|
服务端地址 |
spring.cloud.nacos.discovery .server-addr |
无 |
Nacos Server 启动监听的ip地址和端口 |
服务名 |
spring.cloud.nacos.discovery .service |
spring.app lication.name |
给当前的服务命名 |
服务分组 |
spring.cloud.nacos.discovery .group |
DEFAULT_GROUP |
设置服务所处的分组,做更细致的分割管理 |
权重 |
spring.cloud.nacos.discovery .weight |
1 |
取值范围 1 到 100,数值越大,权重越大 |
网卡名 |
spring.cloud.nacos.discovery .network-interface |
无 |
当IP未配置时,注册的IP为此网卡所对应的IP地址,如果此项也未配置,则默认取第一块网卡的地址 |
注册的IP地址 |
spring.cloud.nacos.discovery .ip |
无 |
优先级最高 |
注册的端口 |
spring.cloud.nacos.discovery .port |
-1 |
默认情况下不用配置,会自动探测 |
命名空间 |
spring.cloud.nacos.discovery .namespace |
无 |
常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。 |
AccessKey |
spring.cloud.nacos.discovery .access-key |
无 |
当要上阿里云时,阿里云上面的一个云账号名 |
SecretKey |
spring.cloud.nacos.discovery .secret-key |
无 |
当要上阿里云时,阿里云上面的一个云账号密码 |
Metadata |
spring.cloud.nacos.discovery .metadata |
无 |
使用Map格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息 |
日志文件名 |
spring.cloud.nacos.discovery .log-name |
无 |
|
集群 |
spring.cloud.nacos.discovery .cluster-name |
DEFAULT |
配置成Nacos集群名称 |
接入点 |
spring.cloud.nacos.discovery .enpoint |
UTF-8 |
地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址 |
是否集成Ribbon |
ribbon.nacos.enabled |
true |
一般都设置成true即可 |
是否开启Nacos Watch |
spring.cloud.nacos.discovery .watch.enabled |
true |
可以设置成false来关闭 watch |
注册的IP地址类型 |
spring.cloud.nacos.discovery .ip-type |
IPv4 |
可以配置IPv4和IPv6两种类型 |
设置永久实例 |
spring.cloud.nacos.discovery .ephemeral |
false |
是否开启永久实例,宕机后,超过心跳,Nacos不会剔除 |
2.2 Nacos集群(Linux)
2.2.1 安装nacos
- 下载对应版本安装包,这里是2.1.0Linux版本的
- 解压三份Nocas
分别为 nocas8849,nocas8850,nocas8851
- 删除压缩包
2.2.2 配置nacos
此处仅为8849,其他两个同
①修改application.properties
,将nacos-mysql.sql
导入自己的数据源
修改端口号,数据源
②将cluster.conf.example
改为cluster.conf
,添加节点配置
拷贝
cluster.conf.example
将其改为cluster.conf
③ 如果出现内存不足,修改startup.sh
2.2.3 启动测试
bin目录下执行
./startup.sh
浏览器输入:
http://192.168.198.129:8849/nacos/index.html
-------------成功---------------------
登陆其他端口nacos
此时报端口被占用,是因为
Nacos2.0版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行—定偏移量自动生成。
解决方法,修改端口号即可,我们这里将8850和8851改为了8859和8869
再次运行其他端口,成功…
2.2.4 使用nginx
进行负载均衡
① 下载nginx
#下载nginx安装包
wget -c http://nginx.org/download/nginx-1.24.0.tar.gz
② 解压
③ 进入目录
cd /usr/local/nginx
④ 修改配置文件
upstream nacoscluster {
server 127.0.0.1:8849;
server 127.0.0.1:8859;
server 127.0.0.1:8869;
}
server {
listen 8001;
server_name localhost;
location /nacos {
proxy_pass http://nacoscluster;
}
}
⑤ 其他命令
./nginx -s reload
:重启nginx
ps -ef | grep nginx
:根据进程号关闭nginx
⑥ 测试
------------------------------------------成功-------------------------------------
-
分别修改三个nacos客户端的注册地址
此处注册地址开始用nginx的路径报错,
com.alibaba.nacos.api.exception.NacosException: Request nacos server failed
,修改为nacos中随便一个地址发现注册进来了(登陆其他端口也是注册进来的,且点击服务详情也在集群里面,因此可以判定为注册在集群里面)。。。
- 具体原因我也不知道,可能是设置集群时,三个nacos相互关联起来了
spring:
cloud:
#配置nacos
nacos:
server-addr: 192.168.198.129:8849
#集群名称
clusterName : nginx01
2.2.5 补充
在三个nacos的父文件夹下,自动生成了logs和work目录
3 Ribbon(负载均衡)
瑞本
目前主流负载均衡主要有两种:
- 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,例如nginx
- 客户端根据自己的请求做负载均衡,Ribbon就属于客户端自己做负载均衡
3.1 Ribbon的使用
spring-cloud-starter-alibaba-nacos-discovery
依赖中包含ribbon依赖,可不用重复导入
IRule:所有负载均衡策略父接口
AbstractLoadBalancerRule:抽象类,里面主要定义一个LoadBlancer
策略 | 解释 |
---|---|
RoundRobinRule | 轮询策略 |
RandomRule | 随机策略 |
AvailabilityFilteringRule | 先过滤出问题的服务,对剩下的轮询访问 |
RetryRule | 如果服务获取失败则会在指定时间内重试 |
BestAvailableRule | 过滤出故障服务器后,选择一个并发量最小的 |
ZoneAvoidanceRule | 默认的,单体架构没有区域一说都是轮询,但是部署在微服务中就是从最佳区域实例集合中选择一个最优性能的服务实例 |
WeightedResponseTimeRule | 针对响应时间加权轮询 |
利用@LoadBalanced
,实现负载均衡
3.1.1 通过配置类使用负载均衡策略
-
坑:配置类不能放在
@SpringBootApplication
中@ComponentScan
能扫描到的地方 -
创建配置类在
@SpringBootApplication
中@ComponentScan
不能扫描到的地方@Configuration public class LBConfig { @Bean //方法名必须为iRule public IRule iRule(){ //可以换成其他负载均衡策略 return new RandomRule(); } }
-
启动类
@RibbonClients( value = { /** * 参数1:访问服务名 * 参数2:配置类 */ @RibbonClient(value = "stock-service",configuration = LBConfig.class ) } )
@SpringBootApplication //@EnableDiscoveryClient @RibbonClients( value = { /** * 参数1:访问服务名 * 参数2:配置类 */ @RibbonClient(value = "stock-service",configuration = LBConfig.class ) } ) public class Order_ribbon_7002 { public static void main(String[] args) { SpringApplication.run(Order_ribbon_7002.class); } @Bean @LoadBalanced//必须配置负载均衡 public RestTemplate restTemplate(){ return new RestTemplate(); } }
3.1.2 通过配置文件使用负载均衡策略
-
修改配置文件application.yml
#被调用微服务名 stock-service: ribbon: #使用指定负载均衡策略 NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
3.1.3 自定义负载均衡策略
-
实现
IRule
接口或者,继承AbstractLoadBalancerRule
public class MyRule extends AbstractLoadBalancerRule { @Override public Server choose(Object o) { ILoadBalancer loadBalancer = this.getLoadBalancer(); //获得当前请求服务的实例 List<Server> reachableServers = loadBalancer.getReachableServers(); //获得随机数 int random = ThreadLocalRandom.current().nextInt(reachableServers.size()); Server server = reachableServers.get(random); // if (server.isAlive()){ // return null; // } return server; } //初始化一些配置 @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } }
-
ribbon负载均衡默认是懒加载模式
开启饥饿加载
ribbon: eager-load: #开启饥饿加载 enabled: true #配置客户端使用饿加载 clients: stock-service
3.2 使用Spring Cloud LoadBalancer负载均衡替代ribbon
RestTemplate
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Htp服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTempate默认依赖jdk的HTTP连接工具。
WebClient
WebCient是从Sprng WebFlux5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请的客户端工具。它的响成式编程的基于Reactor的 ,WebCient中提供了标推Http请求方式对应的get ,post put delete方法,可以用来发起相应的请求。
①移除ribbon支持
- 在pom.xml
<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>
- 配置文件禁用springcloud中不使用ribbon
spring:
cloud:
#不使用ribbon
loadbalancer:
ribbon:
enabled: false
② 添加loadbalancer依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
-
添加后自动使用负载均衡
默认为:
RoundRobinLoadBalancer
:轮询使用负载均衡
4 Fegin(远程服务调用,对标RestTemplate)
奋
与RestTemplate不同的是Fegin是面向对象式的,声明式的, 我们只需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可。)
- 具体使用哪种看个人习惯和公司要求
Spring Cloud openfeign对Netflix Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便
4.1 OpenFegin的简单使用
①引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
② 添加调用对象对应的fegin接口
/**
* 参数1:指定调用服务名
* 参数2:指定调用路径,路径为@RequestMapping指定路径,若没有@RequestMapping则不需指定路径
*/
@FeignClient(name = "stock-service", path = "/stock ")
public interface StockFeginService {
//声明需要调用的方法
@RequestMapping("/del")
String del();
}
③ 消费者Controller层调用
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private StockFeginService stockFeginService;
@RequestMapping("/add")
public String add(){
String message =stockFeginService.del();
System.out.println("下单成功!!!");
return "下单成功!!!"+message;
}
}
④ 启动类
@SpringBootApplication
//@EnableDiscoveryClient
@EnableFeignClients//启动fegin
public class Order_openfegin_7004 {
public static void main(String[] args) {
SpringApplication.run(Order_openfegin_7004.class);
}
}
4.2 OpenFegin自定义配置
4.2.1 OpenFegin日志配置
-
全局配置: 当使用@Configuration,会将配置作用于服务提供方
-
局部配置:
①如果只想针对某一个(几个)服务进行配置就不要加@Configuration
②使用配置文件配置
日志等级有4中,分别是:
- NONE[性能最佳,适用于生产]不记录任何日志(默认值)。
- BASIC[适用于生产环境追踪问题]: 仅记录请求方法、URL、响应状态代码以及执行时间.
- HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
- FULL[比较适用于开发及测试环境定位问题]: 记录请求和响应的header、 body和元数据
① 自定义配置类,指定日志级别,使用@Configuration进行全局配置
/**
* 全局配置: 当使用@Configuration,会将配置作用于服务提供方
* 局部配置: 如果只想针对某一个(几个)服务进行配置就不要加@Configuration
*/
@Configuration
public class FeginConfig {
@Bean
/**
* fegin下的Logger.Level
**/
Logger.Level feginLoggerLevel() {
return Logger.Level.FULL;
}
}
springboot默认的日志级别是info ,feign的dubug日志级别就不会输出,需要在
application.yml
中配置
# springboot默认的日志级别是info ,feign的dubug日志级别就不会输出
logging:
level:
com.jiazhong.order.fegin: debug
② 局部配置
- 通过配置类
-
不使用注解
@Configuration
-
在Fegin接口中使用注解
@FeginClient配置
@FeignClient(name = "product-service",path = "/product",configuration = FeginConfig.class)
-
配置文件局部配置
#fegin局部配置 feign: client: config: #要进行局部配置的服务名 product-service: loggerLevel: BASIC
4.2.2 OpenFegin契约配置
Spring Cloud 1 早期版本使用的原生Fegin,随着netflix的停更替换成了Open feign,
- 两者注解例如
@RequestLine
和@RequestMapper
,@PathVariable
和@Param
不相同,当使用早期SpringCloud的项目需要升级时,可使用契约配置,来避免修改原生注解的风险性
① 在配置类中配置
/**
* 修改契约配置,支持原生注解
*/
@Bean
Contract feginContract() {
return new Contract.Default();
}
② 配置文件中配置
#fegin局部配置
feign:
client:
config:
#要进行局部配置的服务名
product-service:
loggerLevel: BASIC
#还原成原生注解
contract: fegin.Contract.Default
4.2.3 超时时间配置
原生RestTemplateBuilder可以通过
builder.setConnectTimeout();
来设置超时时间,Fegin中没有RestTemplateBuilder,但是有相应配置
① 在配置类中配置
/**
* 配置超时时间
*/
Request.Options options(){
return new Request.Options(5000,10000);
}
② 配置文件中配置
#fegin局部配置
feign:
client:
config:
#要进行局部配置的服务名
product-service:
loggerLevel: BASIC
#连接超时时间,默认2s
connectTimeout: 5000
#请求超时时间,默认为5s
readTimeout: 3000
4.2.3 自定义拦截器
①自定义拦截器继承RequestInterceptor接口
public class MyFeginInterceptor implements RequestInterceptor {
Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 可以做一些拦截
* @param requestTemplate
*/
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("xxx", "xxxx");
requestTemplate.query("id", "111");
requestTemplate.uri("/9");
logger.info("一些日志信息");
}
}
② 配置自定义拦截器
-
配置类实现
/** * 自定义拦截器 */ @Bean public MyFeginInterceptor myFeginInterceptor(){ return new MyFeginInterceptor(); }
-
配置文件实现
#fegin局部配置 feign: client: config: #要进行局部配置的服务名 product-service: #配置拦截器 requestInterceptors[0]: com.jiazhong.order.interceptor.fegin.MyFeginInterceptor loggerLevel: BASIC #连接超时时间,默认2s connectTimeout: 5000 #请求超时时间,默认为5s readTimeout: 3000
5 Nacos-config(配置中心)
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
5.1 什么是配置中心
随着服务的越来越多,每个服务都有自己的配置,但会有许多配置都冗余了,冗余配置一旦一个服务修改,其他服务都要修改,维护起来非常麻烦。。。
-
原始配置缺点:
① 维护性
② 时效性:修改完配置文件,服务都需要进行重启
③ 安全性: ip,端口等都会暴露在配置文件中
-
配置中心解决了上述问题
市面上三大配置中心对比
- springcloud config大部分场景结合git 使用,动态变更还需要依赖Spring Cloud Bus 消息总线来通过所有的客户端变化
- springcloud config不提供可视化界面
- nacos config使用长轮询更新配置,一旦配置有变动后,通知Provider的过程非常的迅速,从速度上秒杀springcloud原来的config几条街,
主流配置中心对比
对比项目 | Spring Cloud Config | Apollo | Nacos |
---|---|---|---|
配置实时推送 | 支持(Spring Cloud Bus) | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
版本管理 | 支持(Git) | 支持 | 支持 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 不支持 |
权限管理 | 支持(依赖Git) | 支持 | 不支持 |
多集群 | 支持 | 支持 | 支持 |
多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持Java | 主流语言,提供了Open API | 主流语言,提供了Open API |
配置格式校验 | 不支持 | 支持 | 支持 |
单机读(QPS) | 7(限流所致) | 9000 | 15000 |
单机写(QPS) | 5(限流所致) | 1100 | 1800 |
3节点读(QPS) | 21(限流所致) | 27000 | 45000 |
3节点写(QPS) | 5(限流所致) | 3300 | 5600 |
5.2 配置管理界面
①配置列表:
维护配置中心所有配置文件
- 可以快速克隆到其他命名空间里
② 新建配置
下图各项分别对应
- Data ID:配置集ID,Data ID 通常采用类Java包(如com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
- Group:配置集所属组,对应一个项目
- 配置格式:支持如下图几种
- 点击发布,发布的数据文件在对应nacos数据库中的config的Info表里
③历史版本
历史版本里面有修改之前版本的配置内容
- 修改后,如果出现某些错误可以回滚到之前版本
④ 监听查询
监听配置文件正确性
- 例如:查询配置文件有没有正确推送到客户端。。。
⑤ 权限管理
- *前提:
-
将nocas的conf文件夹下的application.properties开启权限管理
nacos.core.auth.enabled=true
注意 阿里 Nacos 惊爆,安全漏洞以绕过身份验证(附修复建议)通过查看该功能,需要在application.properties添加配置
nacos.core.auth.enable.userAgentAuthWhite:false
,才能避免User-Agent: Nacos-Server绕过鉴权的安全问题。
- 权限管理可以针对不同角色进行读写权限的管理
5.3 Nocas-config Client 读取配置文件
① 在Nacos添加如下的配置
Data ID: com.jiazhong.order
Group : DEFAULT_GROUP
配置格式: Properties
配置内容: user.name=Huozhexiao
user.age=18
② 客户端使用方式
- 如果要在您的项目中使用 Nacos 来实现应用的外部化配置,使用 group ID 为
com.alibaba.cloud
和 artifact ID 为spring-cloud-starter-alibaba-nacos-config
的 starter。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 现在就可以创建一个标准的 Spring Boot 应用。
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
// 加载时自动调用所有配置文件
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :"+userName+"; age: "+userAge);
}
}
- 在运行此 Example 之前, 必须使用 bootstrap.properties/yml 配置文件来配置Nacos Server 地址,例如:
bootstrap.yml
spring:
application:
#会自动识别dataid与服务名一致的配置文件,若不一致需要手动指定dataid
name: com.jiazhong.order
cloud:
nacos:
server-addr: 192.168.198.129:8849
username: nacos
password: nacos
namespace: public
-
注意当你使用域名的方式来访问 Nacos 时,
spring.cloud.nacos.config.server-addr
配置的方式为域名:port
。 例如 Nacos 的域名为abc.com.nacos,监听的端口为 80,则spring.cloud.nacos.config.server-addr=abc.com.nacos:80
。 注意 80 端口不能省略。 -
启动,控制台输出
user name :Huozhexiao; age: 18
5.4 其他扩展配置
① Nacos默认为properties文件扩展名,使用其他扩展名需要配置
spring:
cloud:
nacos:
config:
file-extension: yaml
②配置动态更新
@SpringBootApplication
public class ConfigApplication_7005 {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication_7005.class, args);
while (true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 你可以通过配置
spring.cloud.nacos.config.refresh.enabled=false
来关闭动态刷新
③ 可支持profile粒度的配置
在配置中心:可以通过profile进行设置粒度,根据不同开发环境指定配置文件
只有默认配置文件,才能结合profile使用(dataid跟服务名相同的配置文件为默认配置文件)
对应Dataid:
${spring.application.name}-${profile}.${file-extension:properties}
除了默认配置文件,其他配置文件必须写上后缀,profile的配置文件必须根据默认配置文件格式来
-
profile优先级>默认配置文件
大的优先级会覆盖小的优先级
spring:
profiles:
active: dev
④ 支持自定义 namespace 的配置
根据不同开发环境设置namespace
spring:
cloud:
nacos:
config:
namespace: dev
⑤ 支持自定义 Group 的配置
根据不同项目设置Group
spring:
cloud:
nacos:
config:
group: DEVELOP_GROUP
⑥ 支持自定义扩展的 Data Id 配置
多个应用之间配置共享的DataId
shared-configs优先级小于默认配置,shared-configs下标越大会覆盖下标小的配置
spring:
cloud:
nacos:
config:
shared-configs:
#- 表示集合多个
- data-id: com.order.common.properties
refresh: true #配置动态更新
#group: 默认为DEFAULT_GROUP
extension-configs优先级>shared-configs,shared-configs下标越大会覆盖下标小的配置
spring:
cloud:
nacos:
config:
extension-configs[0]:
data-id: com.order.common02.properties
refresh: true
#group: 默认为DEFAULT_GROUP
⑦ 配置文件优先级
profile
>默认配置文件>extension-configs
>shared-configs
5.6 @RefreshScope
@Value
注解可以获取到配置中心的值,但是无法动态感知修改后的值,需要利用@RefreshScope
注解
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${user.name}")
private String username;
@RequestMapping("/show")
public String show(){
return username;
}
}
- 学习来自于b站图灵