SpringCloud微服务进阶-Nacos更加全能的注册中心

微服务进阶

由于之前的微服务解决方案中的很多框架已经停止维护了(Ribbon、Hystrix、Zuul已停止更新,并被Spring Cloud彻底移除),超过半数的组件都处于不可用状态,因此我们需要使用另外一套更好的解决方案 Spring Cloud Alibaba

Spring Cloud Alibaba提供的功能有:

  1. 服务限流降级:支持WebServlet、WebFlux、OpenFeign、RestTemplate、Dubbo 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则、还支持查看限流降级Metrics监控。

  2. 服务注册于发现:适配Spring Cloud服务注册于发现标准,默认集成了Ribbon的支持。

  3. 分布式配置管理:支持分布式系统中的外部化配置,配置更改自动刷新。

  4. Rpc服务:扩展Spring Cloud客户端Rest Template和OpenFeign,支持调用Dubbo RPC服务。

  5. 消息驱动能力:基于Spring Cloud Stream为微服务应用构建消息驱动能力。

  6. 分布式事务:使用@GlobalTransactional注解,高效并且对业务零侵入的解决分布式事务问题。

  7. 阿里云对象存储:提供海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。

  8. 分布式任务调度:提供秒级、精准、高可靠、高可用的定时任务调度服务。同时提供分布式的任务执行模型,如网格任务。网络任务支持海里子任务均匀分配到所有Worker(schedulerx-client)上执行。

  9. 阿里云短信服务:覆盖全球的短信服务。

    nacos 更加全能的注册中心

    nacos是一款阿里巴巴开源的服务注册与发现、配置管理的组件,相当于Eureka+Config的组合。

    安装与部署

    1. 到官网下载nacos,解压后进入bin目录 修改并启动startup.cmd文件(修改bin/startup.cmd文件内容,将启动模式改为单机启动:set MODE="standalone")
    2. 启动后访问nacos web网页http://localhost:8848/nacos/,用户名和密码都是nacos

    服务注册与发现

    1. 先导入Spring Cloud Alibaba依赖,在父工程进行依赖管理:

      <dependencyManagement>
          <dependencies>
             <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.3.2</version>
             </dependency>
             <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.1</version>
                <type>pom</type>
                <scope>import</scope>
             </dependency>
             <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.0.1.0</version>
                <type>pom</type>
                <scope>import</scope>
             </dependency>
          </dependencies>
      </dependencyManagement>
      
      1. 在子项目(微服务)中添加服务发现依赖:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        
        1. 编辑配置文件:

          server:
            port: 8201
          spring:
            datasource:
              username: root
              driver-class-name: com.mysql.cj.jdbc.Driver
              url: jdbc:mysql://localhost:3306/springboot
              password: root
            main:
              allow-bean-definition-overriding: true
            application:
              name: book-service
            cloud:
              nacos:
                discovery:
                # 配置nacos注册中心地址,默认就是localhost:8848,所以不写也行
                  server-addr: localhost:8848
          
          1. 然后启动服务,就可以在nacos中找到

无标题

  1. 使用Open Feign实现服务发现远程调用以及负载均衡,导入依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    

    这里,nacos区分了临时实例和非临时实例,那么他们有什么区别呢?

无1标题

  • 临时实例(服务下线后在服务列表消失):和Eureka一样,采用心跳机制向nacos发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息。

  • 非临时实例(服务下线后依然在服务列表中):由nacos主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为false,相当于会对某个实例状态持续地进行监控。

    那怎么把临时实例修改成非临时实例呢?

    在配置文件中进行修改:

    spring:
      cloud:
        nacos:
          discovery:
            # 配置nacos注册中心地址,默认就是localhost:8848,所以不写也行
            server-addr: localhost:8848
            # false 表示非临时实例
            ephemeral: false
    

    集群分区

在一个分布式应用中,相同服务得实例可能会在不同得机器、位置上启动,比如用户管理服务,可能在成都部署一个,在重庆部署一个,而这时秒如果在成都得服务器上启动了借阅服务,借阅服务需要调用用户服务,就应该优先选择同一个区域得用户服务进行调用,这样会响应更快!

无2标题

可以在配置文件内进行设置:

spring:
  cloud:
    nacos:
      discovery:
        # 配置nacos注册中心地址,默认就是localhost:8848,所以不写也行
        server-addr: localhost:8848
        # false 表示非临时实例
        ephemeral: false
        # 修改为重庆地区集群
        cluster-name: chongqing

无3标题

此时负载均衡依然采用得轮询的方式进行调用,而没有使用区域优先的调用机制(优先调用同一集群的服务)。还需要进行配置设置:

spring:
  cloud:
    # 将 locadbalancer的nacos支持开启,集成nacos负载均衡
    loadbalancer:
      nacos:
        enabled: true
    nacos:
      discovery:
        # 配置nacos注册中心地址,默认就是localhost:8848,所以不写也行
        server-addr: localhost:8848

此时就实现了区域优先的负载均衡调用机制(优先调用同一集群的服务)!

除了区域优先调用之外,同一个区域内的实例也可以单独设置权重,nacos会优先选择权重更大的实例(也许这个实例部署的服务器性能更强,所以权重大)进行调用,我们可以在管理页面中进行配置:

无4标题

也可以在配置文件中进行设置:

spring:
  cloud:
    nacos:
      discovery:
        # 配置nacos注册中心地址,默认就是localhost:8848,所以不写也行
        server-addr: localhost:8848
        # false 表示非临时实例
        ephemeral: false
        # 修改为重庆地区集群
        #cluster-name: chongqing
        # 权重大小,值越大越优先调用,默认是1
        weight: 2

配置中心

前面我们使用Spring Cloud Config来加载远程配置,这样就可以在远端集中管理配置文件。

实际上就是在bootstrap.yml中配置远程配置文件获取,然后再进入到配置文件那你加载环节,而nacos也支持这样的操作。哭啼配置步骤如下:

  1. 在nacos页面中,找到《配置列表》页面,在里面新增配置:

    注意DataID的格式《应用名称-环境.yml》。如果只编写应用名称。表示此配置文件在任何环境下都会使用

无5标题

  1. 在项目中添加以下依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    
  2. 添加bootstrap.yml文件,配置内容如下:

    spring:
      application:
        name: user-service
      profiles:
        # 环境和配置文件保持一致
        active: dev
      cloud:
        nacos:
          config:
            file-extension: yml
            # 配置中心服务器地址
            server-addr: localhost:8848
    

此时启动服务即可生效。

要获取nacos配置中的信息可以用@value注解获取。

此时,如果在nacos配置中心里面修改了某个配置,如果直接引用@value注解获取,结果还是原来的值。

这里就需要使用@RefreshScope注解来实现配置热更新。

@RestController
@RefreshScope
public class UserController {

    @Value("{test.txt}")
    String test;

    @Autowired
    private UserService userService;

    @RequestMapping("/user/{uid}")
    public User findUserById(@PathVariable("uid") int uid){
        return userService.getUserById(uid);
    }
}

命名空间

我们可以将配置文件或者服务实例划分到不同的命名空间中,其实就是区分开发、生产环境或者引用归属之类的。

不用的命名空间下,实例和配置都是相互之间隔离的,我们也可以在配置文件中指定当前的命名空间:

  1. 先在nacos页面创建一个新的命名空间

  2. 在配置文件中配置命名空间

    spring:
      cloud:
        nacos:
          discovery:
          # 这里填命名空间的id
            namespace: 890a61c4-dcde-458f-84e8-fed71ac0cf35
    

不在同一命名空间下,服务之间不能相互调用!

实现高可用

通过搭建Nacos集群来实现高可用。Nacos集群架构图如下:

无标6题

我们在所有的nacos服务端之前建立一个负载均衡(SLB),通过SLB间接的访问到Nacos服务器。

比如有三个nacos服务端做集群,不可能把每个nacos都访问一次进行注册。实际上只需要在任意一台nacos服务器上注册即可,nacos服务器会自动同步信息。但是,如果我们注册的那台nacos服务器刚好挂了,其他nacos服务器正常,这样也没法完成注册,但是整个集群还是可用状态!

为了解决这个问题,就需要一个SLB(服务器服务器负载均衡),这样就能避免以上问题。注册请求通过dns解析到SLB(因为SLB是裸IP的,如果SLB的IP地址修改了,那么注册地址就得修改,所以使用域名来进行注册,就不用频繁修改注册记录,只修改域名解析记录即可,域名地址不会变化)。由SLB指定一个可用的nacos服务器进行注册。在这里实现负载均衡可以使用更加方便的工具:Nginx

nacos的数据存储模式

  1. 单节点模式下。nacos将数据存放在一个嵌入式数据库中

这种模式只适合单节点,在多节点集群模式下肯定不行。

所以naocs提供了MySQL统一存储,只需要让所有的nacos服务器连接MySQL进行数据存储即可。官方提供了sql文件。文件在conf文件夹中。nacos-mysql.sql

  1. 先将数据库文件导入数据库。注意添加nacos用户并授予权限!

  2. 对nacos进行配置(conf/application.properties):

    ### 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:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=nacos
    db.password.0=nacos
    
    1. 修改集群配置(conf/cluster.conf.example)

      修改文件名为:cluster.conf(就是去掉原来的.example)

​ 然后编辑内容:

#example
127.0.0.1:8848
127.0.0.1:8847
  1. 修改启动文件以集群模式启动,然后启动。

无7标题

可以看到集群已部署成功!

  1. 开始部署SLB(负载均衡服务器),下载并安装nginx,将nginx加入到系统环境变量path中,然后启动nginx

  2. 修改nginx的配置 文件(conf/nginx.conf),添加如下内容:

    在http{}里面添加如下内容:

    upstream nacos-server {
    server 127.0.0.1:8848;
    server 127.0.0.1:8847;
    }
    server {
    listen 80;
    server_name localhost;
    location /nacos {
    proxy_pass http://nacos-server;
    }
    }

    然后重启nginx,可以使用localhost/nacos 访问nacos了

    1. 将服务的注册中心地址改为localhost:80

      到此为止就将nacos集权搭建完毕了。

posted @ 2026-03-23 11:02  NE_STOP  阅读(115)  评论(0)    收藏  举报