Nacos注册中心和配置中心
Nacos服务注册
目录旁边可以查询具体的目录结构和跳转
一.快速开始
1.版本选择
Nacos 1.X 是老版本,将来会停止维护。 建议您使用2.X版本。 请移步到 Nacos2.X相关文档.
您可以在Nacos的release notes及博客中找到每个版本支持的功能的介绍,当前推荐的稳定版本为2.1.1。
1.预备环境准备
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
- 64 bit OS,支持 Linux/Unix/Mac/Windows,推荐选用 Linux/Unix/Mac。
- 64 bit JDK 1.8+;下载 & 配置。
- Maven 3.2.x+;下载 & 配置。
2.下载源码或者安装包
你可以通过源码和发行包两种方式来获取 Nacos。
从 Github 上下载源码方式
git clone https://github.com/alibaba/nacos.git
cd nacos/
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
ls -al distribution/target/
// change the $version to your actual path
cd distribution/target/nacos-server-$version/nacos/bin
下载编译后压缩包方式
您可以从 最新稳定版本 下载 nacos-server-$version.zip
包。
unzip nacos-server-$version.zip 或者 tar -xvf nacos-server-$version.tar.gz
cd nacos/bin
3.启动服务器
-
注:Nacos的运行需要以至少2C4g60g*3的机器配置下运行。
-
直接修改配置
可以编辑startup.cmd set MODE="cluster" 改为 set MODE="standalone" 然后可以直接startup.cmd启动服务
Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
Windows
启动命令(standalone代表着单机模式运行,非集群模式):
startup.cmd -m standalone
curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
4.配置外置数据库(单机版启动)
修改nacos/bin/startup.cmd
可以编辑startup.cmd set MODE="cluster" 改为 set MODE="standalone"
然后可以直接点击startup.cmd启动服务
1.在配置文件中开启mysql外置数据库和配置对应信息
1.将这一段注解解除,配置自己的mysql的 usename 和 password
2.提前在数据库中创建好nacos数据库(反正名字和自己配置中的一致就可)
### If use MySQL as datasource:
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3307/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456789
2.在数据库中执行sql,导入对应的数据存储空间(MYSQL版本大于5.5,不然报错)
二.依赖添加
1.依赖
<dependencyManagement>
<dependencies>
<!--同理也可以把springboot版本控制添加进入,parent留给公司项目父依赖继承-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<!--解决maven单继承问题 可以多继承-->
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud alibaba的版本控制没通过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>
<!--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>
</dependencies>
</dependencyManagement>
父项目中由alibab版本控制,添加在子项目中
<!--Nacos服务注册发现 集成了Ribbon-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.服务发现配置
spring:
application:
name: order-service
cloud:
nacos:
server-addr: localhost:8848
discovery:
username: nacos
password: nacos
namespace: public
#ephemeral: false #永久实例 服务宕机也不会消失
3.测试
@RequestMapping("/add")
public String add(){
System.out.println("下单成功");
String msg = restTemplate.getForObject("http://stock-service/stock/reduct", String.class);
return "hello world!" + msg;
}
配置
@Bean
@LoadBalanced //需要负载均衡注解 nacos无法解析服务名称 由负载均衡器解析
public RestTemplate restTemplate(RestTemplateBuilder builder){
RestTemplate restTemplate = builder.build();
return restTemplate;
}
idea快速复制一个项目并改变端口号
选择 VM options
-Dserver.port = xxx
三.Ribbon的使用
<!--Nacos服务注册发现 集成了Ribbon-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
1.负载均衡器
@Configuration
public void RestConfig{
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
直接使用服务名
2.修改默认负载均衡器
方法一:写配置类 通过在启动类添加注解@RibbonClient指定微服务及其负载均衡策略(也可以将Bean写在启动类中)
@Configuration
public class RibbonRandomRuleConfig {
/**
* 全局配置
* 指定负载均衡策略
* @return
*/
//方法名一定要交iRule
@Bean
public IRule iRule(){
// 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重)
return new RandomRule();
}
}
注意:此处有坑。不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的 RibbonClients共享。 不建议这么使用,推荐yml方式
局部配置不能写在启动类能扫描的zxy目录下,不然就变成了全局配置.
利用@RibbonClient指定微服务及其负载均衡策略。
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
DruidDataSourceAutoConfigure.class})
//@RibbonClient(name = "mall‐order",configuration = RibbonConfig.class)
//配置多个 RibbonConfig不能被@SpringbootApplication的@CompentScan扫描到,否则就是全局配置的效果
@RibbonClients(value = {
// 在SpringBoot主程序扫描的包外定义配置类
@RibbonClient(name = "mall‐order",configuration = RibbonConfig.class),
@RibbonClient(name = "mall‐account",configuration = RibbonConfig.class)
})
public class MallUserRibbonDemoApplication {
public static void main(String[] args) {
pringApplication.run(MallUserRibbonDemoApplication.class, args);
}
}
方法二:通过yml配置
mall‐order: # 被调用的微服务名(顶行)
ribbon:
# 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
# 找不到路径对IRule ctrl+h 看见子类
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
3.自定义负载均衡策略(最基础的)
public class CustomRule 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 server;
// }
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
NFLoadBalancerRuleClassName: com.ribbon.rule.CustomRule
4.开启饥饿加载,解决第一次调用慢的问题
ribbon:
eager‐load:
# 开启ribbon饥饿加载
enabled: true
# 配置stock-service使用ribbon饥饿加载,多个使用逗号分隔
clients: stock-service
四.将Ribbon替换为Spring Cloud LoadBalancer
1.依赖导入
<!‐‐ LoadBalancer ‐‐>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐loadbalancer</artifactId>
</dependency>
注意: nacos-discovery中引入了ribbon,需要移除ribbon的包
如果不移除,也可以在yml中配置不使用ribbon
2.关闭ribbon
方法一:(去除掉ribbon的依赖)
<!--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>
方法二:yml
server:
port: 8040
spring:
application:
name: order-service
cloud:
nacos:
server-addr: localhost:8848
discovery:
username: nacos
password: nacos
namespace: public
loadbalancer: #禁用ribbon
ribbon:
enabled: false
Nacos服务配置
一.开启权限配置
### If turn on auth system:
nacos.core.auth.enabled=true (false --> true)
二.Nacos权限管理界面
1.命名空间(可以理解为不同的环境,例如开发环境,测试环境)
2.用户管理(管理员授权的用户才能读取配置等)
3.角色管理
4.权限管理
5.Nacoa配置中心
最佳实践:
Namespace:代表不同环境,如开发、测试、生产环境。
Group:代表某项目,如XX医疗项目、XX电商项目
DataId:每个项目下往往有若干个工程(微服务),每个配置集(DataId)是一个工程(微服务)的主配置文件
三.Idea获取Nacos配置
1.添加依赖
<!-- Nacos服务配置依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.添加基础配置(bootstrap.yml)
spring:
application:
name: config-nacos #项目名和配置Data ID一样 根据服务名配置对应文件
cloud:
nacos:
server-addr: localhost:8848
server-addr: localhost:8848
username: nacos
password: nacos
3.测试
@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.out.println("common name:"+userName+",age:"+userAge);
}
}
4.扩展配置(bootstrap.yml)
4.1基础扩展配置
默认配置就是项目名和Nacos配置名一致的
#和nacos配置中心有关的写里面
spring:
cloud:
nacos:
server-addr: localhost:8848
username: nacos
password: nacos
config: #Nacos客户端默认的是Properties的文件扩展名 一旦修改必须更改格式(只针对默认配置文件)
#file-extension: yaml
#namespace: public #dev 如果是默认空间public就不需要指定空间(只针对默认配置)
#group: DEFAULT_GROUP #默认分支 默认可以不写(只针对默认配置)
application.yml
Nacos创建配置时,除了和项目名一致的默认配置,后面都需要加扩展名 例如 .yml等
server:
port: 8050
spring:
application:
name: config-nacos #项目名和配置Data ID一样 根据服务名配置对应文件
#作为精准配置,用的少一点点
# `${spring.application.name}‐${profile}.${file‐extension:properties}
#例如 nacos配置文件命名为:config-nacos-dev.properties 项目名-环境.文件后缀名
#profiles:
# active: dev #profile粒度的配置
4.2支持自定义扩展的 Data Id 配置
优先级从高到低:(优先级高的会覆盖优先级低的相同配置)
1) nacos-config-product.yaml 精准配置
2) nacos-config.yaml 同工程不同环境的通用配置
3) extension-configs: 不同工程 扩展配置(同样的下标大的优先)
4) shared-dataids 不同工程通用配置(同样的下标大的优先)
多种配置编写方式
shared-configs:
- data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
- data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
或者
shared-configsp[0]:
data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
shared-configsp[1]:
data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
shared-configs和extension-configs
config:
shared-configs:
- data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
- data-id: nacos-zxy02.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[1]
extension-configs[0]:
data-id: nacos-zxy03.yml
group: zxy_config
refresh: true
extension-configs[1]:
data-id: nacos-zxy04.yml
group: zxy_config
refresh: true
4.3@RefreshScope(对象属性的的动态更新)(其他时候也使用)
@Value注解可以获取到配置中心的值,因为Bean的作用域范围没有动态更新无法动态感知修改后的值。
@RefreshScope可以动态更新bean
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${user.name}")
public String username;
@RequestMapping("/show")
public String show(){
return username;
}
}
Nacos服务所有yml配置和依赖总合
配置
spring:
application:
name: order-service
cloud:
nacos:
server-addr: localhost:8848
discovery:
username: nacos
password: nacos
namespace: public
#ephemeral: false #永久实例 服务宕机也不会消失
config:
#file-extension: yaml 默认的是Properties的文件扩展名 一旦修改必须更改格式
#namespace: public #dev 如果是默认空间public就不需要指定空间(只针对默认配置)
#group: DEFAULT_GROUP #默认分支 默认可以不写(只针对默认配置)
shared-configs:
- data-id: nacos-zxy.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[0]
- data-id: nacos-zxy02.yml
group: zxy_config
refresh: true #动态感知配置 默认配置中默认为true #[1]
extension-configs[0]:
data-id: nacos-zxy03.yml
group: zxy_config
refresh: true
extension-configs[1]:
data-id: nacos-zxy04.yml
group: zxy_config
refresh: true
loadbalancer: #禁用ribbon 替换为Spring Cloud LoadBalancer(去除掉ribbon的依赖)
ribbon:
enabled: false
mall‐order: # 被调用的微服务名(顶行)通过yml配置
ribbon:
# 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
# 找不到路径对IRule ctrl+h 看见子类
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
ribbon: #开启饥饿加载,解决第一次调用慢的问题
eager‐load:
# 开启ribbon饥饿加载
enabled: true
# 配置stock-service使用ribbon饥饿加载,多个使用逗号分隔
clients: stock-service
依赖
父项目的父依赖
<dependencyManagement>
<dependencies>
<!--同理也可以把springboot版本控制添加进入,parent留给公司项目父依赖继承-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<!--解决maven单继承问题 可以多继承-->
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud alibaba的版本控制没通过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>
<!--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>
</dependencies>
</dependencyManagement>
#父项目中由alibab版本控制,添加在子项目中
<!--Nacos服务注册发现 集成了Ribbon-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!‐‐ LoadBalancer ‐‐>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐loadbalancer</artifactId>
</dependency>
<!-- Nacos服务配置依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>