部署 Nacos Server

安装和配置好Nacos后,在nacosbin目录中使用脚本启动:

  • Windows:

    单机启动:

    startup.cmd -m standalone
    
  • Linux:

    单机启动:

    sh startup.sh -m standalone
    

在浏览器中使用对应的IP和端口访问,如http://localhost:8848/nacos

默认账号和密码均为nacos

更多Nacos的部署方式:Nacos 部署


服务注册中心

Nacos 客户端依赖

  • 父工程:

    <!--
        Spring Cloud Alibaba
        包含了Nacos的版本管理
     -->
    <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>
    
  • 客户端:

    <!-- Nacos 客户端 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  • 配置Nacos(application.yml):

    spring:
      cloud:
        nacos: # Nacos配置
          server-addr: localhost:8848 # Nacos服务地址
    

服务器集群

在Nacos中配置服务器集群,需要在application.yml使用来配置spring.cloud.nacos.discovery.cluster-name客户端服务器的集群名称:

spring:
  cloud:
    nacos: # Nacos配置
      server-addr: localhost:8848 # Nacos服务地址
      discovery:
        cluster-name: HZ  # 集群名称

使用Nacos提供的集群配置,就可以将同一机房内的实例划分为一个集群。

服务器集群

负载均衡策略

Nacos提供了一个负载均衡策略NacosRule配置它和配置其它的Ribbon负载均衡策略相同。在application.yml中:

service-name: # 服务名称
  ribbon:
    # 负载均衡规则
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    # Nacos提供的负载均衡策略
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

当然也可以使用Bean的方式配置全局的负载均衡策略:

@Bean
public IRule getLoadBalancerRule() {
    return new NacosRule();
}

NacosRule会根据当前服务所在的集群,优先挑选与当前服务相同的集群。因为在同一机房同一集群的配置下,访问本地的集群(即相同的集群)速度将会更快。如果相同的集群下无可用实例,才会选择其它示例,并且控制台会给出警告。如果在相同集群的情况下,则使用随机轮询,随机选择一个实例。

访问权重

默认情况下使用NacosRule是在同集群内随机挑选,并不会考虑机器的性能问题。

为了让性能更快的服务可以被分配到更多的请求,Nacos提供了权重配置来控制访问频率。使用访问权重,可以调节服务被访问到的概率。访问权重的取值为0~1默认值是1权重越高,被访问到的概率就越大。如果将访问权重修改为0,那么该实例将永远不会被访问

将访问权重修改为0并不意味着服务器停机,只是后续的请求不会使用到这个服务器,而当前该服务器所处理的请求还会继续。

修改访问权重可以在Nacos控制台中修改:

例如,修改user-service的权重,找到user-service的实例列表,点击编辑,即可修改权重:

在弹出的编辑窗口,修改权重:

非临时实例

Nacos的服务实例(服务提供者)分为两种类型:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,是所有实例默认的类型。
  • 非临时实例(永久实例):如果实例宕机,不会将其从服务列表剔除。
spring:
  cloud:
    nacos: # Nacos配置
      server-addr: localhost:8848 # Nacos服务地址
      discovery:
        ephemeral: false  # 注册为非临时实例

环境隔离

Nacos提供了namespace(命名空间)来实现环境隔离功能。默认情况下,所有servicedatagroup都在同一个名为publicnamespace。每个namespace都有一个唯一的ID,并且不同namespace下的服务之间互不可见。namespace可以在Nacos控制台中创建。

为服务设置namespace,需要在application.yml中配置spring.cloud.nacos.discovery.namespace,它的值为对应命名空间的ID:

spring:
  cloud:
    nacos: # Nacos配置
      server-addr: localhost:8848 # Nacos服务地址
      discovery:
        # 命名空间,值为对应命名空间的ID
        namespace: df79820e-775d-4787-b0a8-0b6e5fabeb13

Nacos 与 Eureka 的区别

Nacos远程调用流程

Nacos和Eureka整体结构类似,都有服务注册、服务拉取、心跳等待等,但是也存在一些差异:

  • 共同点:
    • 都支持服务注册和服务拉取。
    • 都支持服务提供者心跳方式做健康检测。
  • 不同点:
    • Nacos支持服务端主动检测提供者状态:

      • 临时实例采用心跳模式;
      • 非临时实例采用主动检测模式。

      主动检测的弊端:会给服务器造成一定的压力。一般情况下使用临时实例的心跳模式即可。

    • 在Nacos中,临时实例心跳不正常会被剔除,非临时实例则不会被剔除。

    • Nacos支持服务列表变更的消息推送模式,服务列表更新更加及时。

    • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式。


配置管理

Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。

在Nacos中,配置获取的步骤如下:

  1. 项目启动。
  2. 读取Nacos中的给服务定义的配置文件。
  3. 读取本地配置文件application.yml。与上一步在Nacos中读取到的配置相合并。
  4. 创建Spring容器。
  5. 加载Bean

依赖pom.xml

<!-- Nacos配置管理依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

新建配置文件bootstrap.yml,进行如下配置:

spring:
  application:
    name: service-name # 服务名
  profiles:
    active: env-name # 环境名称
  cloud:
    nacos: # Nacos 配置
      server-addr: localhost:8848
      config:
        file-extension: yml # 配置文件后缀名

依赖和配置在需要配置管理的服务中添加和修改。

bootstrap.yml中已经配置过的配置,在application.yml中可以不用重复配置。

在Nacos控制台中添加配置文件:

对新添加的配置文件进行编辑,编辑完成好后点击发布进行提交:

多环境配置共享

微服务启动时会从Nacos中读取多个配置文件:

  • [service-name]-[env-name].[file-extension]当前环境配置。只能在对应环境的情况下进行读取。
  • [service-name].[file-extension]共享环境配置。无论当前实例处于什么环境下,该文件一定会被加载。所以多环境共享配置可以写在这个文件中。

[file-extension]为配置中对应的文件扩展名。

读取配置

  • 使用@RefreshScope注解进行配置自动刷新:

    @RestController
    @RefreshScope   // 配置自动刷新
    public class TestController {
    
        @Value("${pattern.dateformat}")
        private String dateformat;
    
        /**
         * 返回当前按照规定格式进行格式化的时间
         */
        @GetMapping("/now")
        public String now() {
            return LocalDateTime.now().format(
                    DateTimeFormatter.ofPattern(dateformat));
        }
    }
    
  • 使用@ConfigurationProperties注解:

    @Data
    @Component
    // 读取以pattern为开头的配置
    @ConfigurationProperties(prefix = "pattern")
    public class PatternProperties {
        private String dateformat;  // 相当于 pattern.dateformat
    }
    
    @RestController
    public class TestController {
    
        @Autowired
        private PatternProperties properties;
    
        @GetMapping("/now")
        public String now() {
            return LocalDateTime.now().format(
                    DateTimeFormatter.ofPattern(properties.getDateformat()));
        }
    }
    

    使用@ConfigurationProperties注解将配置读取到类中,在配置更改的时候,类将会自动更新,而无需使用@RefreshScope注解。

配置文件优先级

Nacos中多种配置文件的优先级从高到低的顺序如下:

  1. [service-name]-[env-name].yml
  2. [service-name].yml
  3. 本地配置文件(如application.yml,本地配置文件也有自己的优先级)