Spring Cloud Alibaba 之 服务注册和配置中心 Nacos

296 阅读4分钟

一、概述

  • Nacos,即前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service。
  • 可知,Nacos就是做服务注册和配置的。配置的修改还可以动态通知客户端。因此Nacos=Eureka+Config+Bus。
  • github官方文档官方文档

二、安装

  • Nacos底层就是Java代码,而这个服务器已经被包装好了,可以直接下载下来运行,下载地址
  • 下载下来之后,可以直接进入bin目录,通过脚本运行。(windows用bat脚本,linux用shell脚本)
  • 执行单机版startup.cmd -m standalone
  • 运行成功之后,可以打开网页监控页面。http://localhost:8848/nacos image.png

三、Nacos作为服务注册中心

1. 导包

  • 首先,可以在父pom中导入Spring Cloud Alibaba的包,里面包含了Spring Cloud Alibaba生态的所有包
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.1.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
  • 把注册的包导入。服务调用和服务提供的包都是一样的。
<dependencies>
    <!--nacos-discovery-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--web + actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--一般基础配置-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 服务提供的配置文件

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'

3. 服务提供的主启动类

  • @EnableDiscoveryClient开启注册
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain9001 {
    public static void main(String[] args) {
            SpringApplication.run(PaymentMain9001.class, args);
    }
}

4. 服务提供的业务类

@RestController
@Slf4j
public class PaymentController {
  @Value("${server.port}")
  private String serverPort;

  @GetMapping(value = "/payment/nacos/{id}")
  public String getPayment(@PathVariable("id") Integer id) {
    String result = "nacos registry, serverPort: " + serverPort + "\t id" + id;
    log.info(result);
    return result;
  }
}

5. 服务调用的配置文件

  • 与服务提供方的配置文件基本无异。最下面的那个配置,是自己定义的调用url,将自己要调用的服务作为url
server:
  port: 83


spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848


#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider 

6. 服务调用的主启动类

@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain83
{
    public static void main(String[] args)
    {
        SpringApplication.run(OrderNacosMain83.class,args);
    }
} 

7. 服务调用的业务类

  • 值得说明的是,在nacos的包里面,包含了Ribbon,因此服务调用的时候,可以和之前调用的方式一致。
@Configuration
public class Config {
  @Bean
  @LoadBalanced
  public RestTemplate getRestTemplate() {
    return new RestTemplate();
  }
}
@RestController
@Slf4j
public class OrderNacosController {
  @Autowired
  private RestTemplate restTemplate;
  @Value("${service-url.nacos-user-service}")
  private String serverURL;

  @GetMapping("/consumer/payment/nacos/{id}")
  public String paymentInfo(@PathVariable("id") Long id) {
    return restTemplate.getForObject(serverURL + "/payment/nacos/" + id, String.class);
  }
}

8. 测试

  • 像往常一样调用服务调用方,服务调用方会调用服务提供方。
  • 可以将服务提供者进行复制,用于测试负载均衡。测试可见,默认使用了轮询的负载均衡策略。
  • 在监视界面也可以看到注册的服务。 image.png

9. 各种注册中心对比

image.png

  • 但事实上,Nacos支持AP和CP之间的切换。
  • 如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如 Spring cloud 和 Dubbo 服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性,因此AP模式下只支持注册临时实例。
  • 如果需要在服务级别编辑或者存储配置信息,那么 CP 是必须,K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
  • 切换命令curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

四、Nacos作为服务配置中心

1. 导包

  • 导入nacos-config的包,顺便把服务发现的包也导进来。
<dependencies>
    <!--nacos-config-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!--nacos-discovery-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--web + actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--一般基础配置-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2. 配置文件

  • 在Spring Cloud Config中已经说过,bootstrap.yml的优先级高于application.yml,因此导入配置中心的配置内容时,一般都放在bootstrap.yml文件中。
# nacos配置
server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
      config:
        server-addr: localhost:8848 #Nacos作为配置中心地址
        file-extension: yaml #指定yaml格式的配置

# 这是DataId的命名规则,与配置文件中的内容呈映射关系,从而在配置中心中选出真正的配置文件。
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
  • application.yml中,选择开发环境。
spring:
  profiles:
    active: dev # 表示开发环境

3. 主启动类

@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
    public static void main(String[] args) {
            SpringApplication.run(NacosConfigClientMain3377.class, args);
    }
}

4. 业务类

  • 可见,与之前Spring Cloud Config的调用没有差别。需要在类上面写一个@RefreshScope注解,用于表明当前的配置可以动态刷新。
@RestController
@RefreshScope //在控制器类加入@RefreshScope注解使当前类下的配置支持Nacos的动态刷新功能。
public class ConfigClientController {
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }
}

5. 配置中心

  • 配置中心保存配置信息,提供修改功能,并且在修改之后,还可以主动提供所有的客户端。非常方便,解决了需要消息总线、git仓库的问题,直接一站式解决。官网
  • 在网页上面选择配置新增 image.png
  • 然后就可以在上面写配置文件的内容了。允许多种格式。 image.png
  • 值得一提的是,DataID的命名有讲究。一般格式为${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}和本地的配置文件一一对应。 image.png
  • Nacos配置中心还有回滚功能,可以翻看30天内的配置文件历史记录,一键回滚。(不过本人测试过,貌似有点小bug,不太建议使用) image.png

6. 配置中心的分类

  • 配置文件可以通过命名空间Namespace、Group、DataID进行区分。 image.png
  • 通过以下方法,可以在定义配置文件的时候,指定分组Group。在yaml文件中,指定该Group即可使用。 image.png image.png
  • 通过以下方法,可以通过命名空间进行分组。 image.png image.png image.png

五、持久化配置

  • 官网
  • 官方自带持久化的数据库,用的是嵌入式数据库derby
  • 我们可以修改,使用mysql作为持久化的数据库。

1. 建库建表

  • 首先,在conf文件夹中找到mysql脚本nacos-mysql.sql,并且在数据库上面运行。(值得一说的是,脚本没有建库命令,最好自己添加一句)

2. 修改配置文件

  • 在conf文件夹中找到application.properties文件,并在末尾添加数据库连接方面的配置。
spring.datasource.platform=mysql
 
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root  # 有可能是db.user.0,看情况吧
db.password=123456 # 有可能是db.password.0,看情况吧

3. 启动

  • 启动Nacos,会发现之前的东西都没有了,因为现在已经进入了一个新的数据库。
  • 添加配置文件,如果发现数据库上面也有数据跟着增加,说明修改成功了。
  • 数据库版本的问题,可能会导致报错,最好查一下当前使用的数据库连接驱动版本,如果不对,可以尝试修改一下。加油...

六、集群配置

image.png image.png

  • 架构如上。通过Nginx实现负载均衡,指向Nacos集群。

1. 修改配置文件

  • 在conf下面,有一个cluster.conf.example文件,将其复制一份命名为cluster.conf,并对其进行修改。将集群的ip和端口号放进去。 image.png

2. 开启

  • 然后就可以尝试开启了。