微服务 - Nacos
Nacos 认识和安装
Nacos 是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka 功能更加丰富,在国内受欢迎程度较高
官网:nacos.io
# 启动
.\startup.cmd -m standalone
启动成功后访问:http://192.168.222.1:8848/nacos/index.html
默认的账号密码:nacos/nacos
服务注册
1.父工程 cloud-demo 的POM 中引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2.user-service 和 order-service 中分别引入 nacos 依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
3.服务中配置服务名称和nacos 服务地址:
以user-service 为列:
spring:
application:
name: userservice # 注册到nacos 的服务名称
cloud:
nacos:
server-addr: localhost:8848 # naocs 服务地址
Nacos 服务分级存储模型
服务跨集群调用问题:
服务调用尽可能选择本地集群服务,跨集群调用延迟较高
当本地集群不可访问时,再去访问其他集群
集群配置:
spring:
application:
name: userservice #服务名称
cloud:
nacos:
server-addr: localhost:8848 # naocs 服务地址
discovery:
cluster-name: GZ # 集群名称
启动3个user-service 实例 来模拟两个集群:
user-service 配置集群为 SZ
user-service2 配置集群为 SZ
user-service3 配置集群为 GZ
NacosRule 负载均衡
需求:order-servce 优先使用同集群的服务,同集群的服务不可用时才调用其他集群的服务
-
order-service 配置集群为 SZ 与 user-service 及 user-service2同 以个集群
-
更改 user-servic的负载均衡策略
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
访问order-service 4次:
可以看到 请求user-service 都访问到了user-service 及user-service2,而没有请求到另一个集群的user-service3
如果将user-service 及user-service2 停掉后保留user-service3服务,再次访问order-service:
请求都打到user-service3 上:
并且order-service 会有以下警告日志
Nacos 服务实例的权重设置
实际部署中会出现这样的场景:
服务设备性能有差异,部分实例所在机器性能较好,另外一些较差,我们希望性能好的机器承担更多的用户请求
Nacos 提供了权重配置来控制访问频率,权重越大则访问频率越高
实验1:user-service2 的权重修改为0.1
结果: 请求10次,2次打在user-service2,8次打在user-service
实验2:user-service2 的权重修改为0
结果: 请求10次,全部打在user-service
总结:
实例的权重控制:
- Nacos 控制台可以设置实例的权重值,0-1之间
- 同集群内的多个实例,权重越高被访问的频率越高
- 权重设置为0则完全不会被访问
Nacos 环境隔离
Nacos 服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
- namespace 用来做环境隔离
- 每个namespace 都有唯一id
- 不同namespace 下的服务不可见
新建一个namespace:
1.
新建完毕后在服务列表就可以看到namespace:
新建完毕后将orderf-service 放入到dev 空间:
spring:
application:
name: orderserivce # eureka 的服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务地址
discovery:
cluster-name: SZ # 集群名称e
namespace: ee9e5ae9-4cba-4681-8107-efddf0597abe # namespace id
此时order-service 就不能在使用 user-service的服务,因为两者在不同的命名空间中,请求会报错:
Nacos 和 Eureka 的区别
共同点:
- 都支持服务注册和拉取
- 都支持服务者心跳方法做健康检测
区别:
- Nacos 支持服务端主动检测提供者装状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除(推荐使用临时实例,非临时实例需要主动询问,服务器压力大)
- Nacos 支持服务列表变更的消息推送模式,服务列表更新及时
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
案例:默认服务为临时实例,将临时实例修改为非临时实例
1.关闭order-service 后服务被剔除:
2.修改application.yml
spring:
application:
name: orderserivce # eureka 的服务名称
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务地址
discovery:
cluster-name: SZ # 集群名称e
namespace: ee9e5ae9-4cba-4681-8107-efddf0597abe # namespace id
ephemeral: false # 非临时实例
3.关闭order-service 后,服务不会被剔除:
Nacos 配置管理
Nacos 配置管理 可以实现配置热更新,将一些经常发发生变更的配置放入到Nacoos 配置管理中,不用重启服务就可以生效
最终的配置就等于: Nacos 配置 + 微服务中的application.yaml 中的配置
新建配置文件:
在这里加入一个配置作为测试使用:
新建成功
Nacos 配置拉取
SpringBoot 项目启动时读取配置文件的顺序:
热更新方式一
拉取步骤如下:
1.user-service 引入Nacos 引入配置管理依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.新建bootstrap.yml 配置Nacos地址,需要注意的是配置一定不能出错,否则读取不到配置信息
spring:
application:
name: userservice # 服务名称
profiles:
active: dev # 环境
cloud:
nacos:
server-addr: localhost:8848 # Nacos 地址
config:
file-extension: yaml # 文件后缀
配置中的:name-active.file-extension 组成了Nacos 配置管理中文件的名字
3.这里在controller 层写了一个请求现在时间的映射,而现在日期的格式化采用的是Nacos中配置的pattern
- @RefreshScope: 开启Nacos 热更新
- @Value("${pattern.dateformat}"): 注入Nacos 中配置的值
package cn.itcast.user.web;
import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RefreshScope
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@Value("${pattern.dateformat}") //注入Nacos 配置管理中的配置信息
private String dateformat;
@GetMapping("/now")
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
}
}
修改前:
修改patter 格式后请求,不用重启服务就可以使用到最新的patter:
同时控制台也有相关配置更新的日志输出:
热更新方式二
1.新建配置类
package cn.itcast.user.config;
import lombok.Data;
import org.checkerframework.checker.units.qual.C;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternConfig {
private String dateformat;
}
2.controller 直接注入使用
不用再使用 @RefreshScope 注解标记
package cn.itcast.user.web;
import cn.itcast.user.config.PatternConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private PatternConfig patternConfig;
@GetMapping("/now")
public String now(){
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternConfig.getDateformat()));
}
}
修改格式之前:
修改格式之后:
控制台收到变更通知:
Nacos 多环境配置共享
场景:开发、测试、生产环境 该配置的值都是一样,那么即可以将该值配置在共享配置文件中
微服务启动时会从nacos读取多个配置文件:
- [spring.application.name]-[spring.profiles.active].yaml, 例如:usercervice-dev.yaml
- [spring.application.name].yaml,例如:userservice.yaml
无论profile 如何变化,[spring.application.name].yaml 这个文件一定会加载,因此多环境共享配置可以写入这个文件
案例:
1.新建一个userservice.yaml:
2.配置类引入该属性:
package cn.itcast.user.config;
import lombok.Data;
import org.checkerframework.checker.units.qual.C;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternConfig {
private String dateformat;
private String envShare;
}
3.controller 映射直接返回配置类:
@GetMapping("/prop")
public PatternConfig prop(){
return patternConfig;
}
启动微服务的配置:
userservice 8081: spring.profiles.active=dev
userservice 8082: spring.profiles.active=test
结果:
userservice 8081 加载的配置文件:
userservice 8082 加载的配置文件:
多种配置的优先级:
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/17675554.html