• SpringCloud Alibaba入门之Nacos(SCA)


    SpringCloud Alibaba

    Spring Cloud Alibaba 致力于提供微服务开发 的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里 微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

    SpringCloud Alibaba官方文档

    1.SpringCloud Alibaba 之 Nacos

    ①Nacos 主要功能

    • 服务发现和服务健康监测
    • 动态配置服务
    • 动态DNS服务
    • 服务及其元数据管理
      Nacos 可以说就是 注册中心+配置中心 的组合,等价于:Nacos = Eureka+Config+Bus

    ②Nacos这么强大,那具体怎么使用呢?下面我们就一起探索

    2.Nacos作为注册中心

    安装Nacos方式一(windows):

    1.下载:「nacos-server-1.1.4」https://www.aliyundrive.com/s/owtAZ27gNNd
    点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
    我把安装包放在了阿里云盘大家可以自行下载,也可以去GitHub下载:https://github.com/alibaba/nacos/archive/1.1.4.tar.gz
    2.解压
    3.启动命令: cmd startup.cmd 或者双击 startup.cmd 运行文件。

    image

    安装Nacos方式二(linux):使用Docker的方式

    1.拉取需要的nacos镜像

    docker pull nacos/nacos-server:【指定版本号】

    image

    2.在宿主机创建个docker文件夹专门来放docker容器相关的挂载数据

    3.vim custom.properties编辑custom.properties文件,加上以下内容

    【management.endpoints.web.exposure.include=*】

    4.启动nacos容器:

    docker run -d -p 8848:8848 -e MODE=standalone -v /docker/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /docker/nacos/logs:/home/nacos/logs --restart always --name nacos nacos/nacos-server

    image

    注册中心已经准备完毕,我们再基于 Nacos 注册中心创建服务提供者和消费者。

    这里还是使用之前SpringCloud第一版一样的案例,用户微服务和电影微服务,查询用户信息可以查询电影信息(远程调用)

    服务提供方

    1.创建一个服务提供方电影微服务模块nacos-provider-movie6600

    image

    2.修改pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.qbb</groupId>
        <artifactId>nacos-provider-movie6600</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>nacos-provider-movie6600</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
            <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>com.qbb</groupId>
                <artifactId>cloud-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </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>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </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>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>2.3.7.RELEASE</version>
                    <configuration>
                        <mainClass>com.qbb.cloud2022.NacosProviderMovie6600Application</mainClass>
                    </configuration>
                    <executions>
                        <execution>
                            <id>repackage</id>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    3.写yml文件

    server:
      port: 6600
    
    spring:
      application:
        name: nacos-provider-movie
    
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.137.72:8848 #nacos服务端地址
      # 数据源
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/qbbit3?serverTimezone=UTC
        username: root
        password: root

    4.主启动类

    package com.qbb.cloud2022;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @MapperScan("com.qbb.cloud2022.mapper")
    @EnableDiscoveryClient // 开启Nacos客户端服务
    @SpringBootApplication
    public class NacosProviderMovie6600Application {
    
        public static void main(String[] args) {
            SpringApplication.run(NacosProviderMovie6600Application.class, args);
        }
    
    }

    5.业务

    controller

    package com.qbb.cloud2022.controller;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
    import com.qbb.cloud2022.service.MovieService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-02  22:42
     * @Description:
     */
    @RestController
    @RequestMapping("/movie")
    @Slf4j
    public class MovieController {
    
        @Autowired
        private MovieService movieService;
    
        @Value("${server.port}")
        private String port;
    
        @GetMapping("/findById/{id}")
        public Movie findById(@PathVariable("id") Integer id) {
            log.info("port:{}", port);
            return movieService.findById(id);
        }
    }
    

    service

    package com.qbb.cloud2022.service.impl;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
    import com.qbb.cloud2022.mapper.MovieMapper;
    import com.qbb.cloud2022.service.MovieService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-02  22:45
     * @Description:
     */
    @Service
    public class MovieServiceImpl implements MovieService  {
    
        @Autowired
        private MovieMapper movieMapper;
    
        @Override
        public Movie findById(Integer id) {
            return movieMapper.findById(id);
        }
    }
    

    mapper

    package com.qbb.cloud2022.mapper;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
    import org.apache.ibatis.annotations.Select;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-02  22:46
     * @Description:
     */
    public interface MovieMapper {
        @Select("select * from movie where id=#{id}")
        Movie findById(Integer id);
    }
    

    测试一下:
    image

    服务消费方

    1.创建一个服务消费方电影微服务模块nacos-provider-movie6600

    2.修改pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.qbb</groupId>
        <artifactId>nacos-consumer-user6700</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>nacos-consumer-user6700</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
            <spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>com.qbb</groupId>
                <artifactId>cloud-common</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </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>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </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>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>2.3.7.RELEASE</version>
                    <configuration>
                        <mainClass>com.qbb.cloud2022.NacosConsumerUser6700Application</mainClass>
                    </configuration>
                    <executions>
                        <execution>
                            <id>repackage</id>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>

    3.写yml文件

    server:
      port: 6700
    
    spring:
      application:
        name: nacos-consumer-user
    
      cloud:
        nacos:
          discovery:
            server-addr: 192.168.137.72:8848
      # 数据源
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/qbbit3?serverTimezone=UTC
        username: root
        password: root

    4.主启动类

    package com.qbb.cloud2022;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @MapperScan("com.qbb.cloud2022.mapper")
    @EnableDiscoveryClient // 开启nacos注册中心支持
    @SpringBootApplication
    public class NacosConsumerUser6700Application {
    
        public static void main(String[] args) {
            SpringApplication.run(NacosConsumerUser6700Application.class, args);
        }
    
    }
    

    5.业务

    controller

    package com.qbb.cloud2022.controller;
    
    import com.qbb.cloud2022.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.Map;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  13:31
     * @Description:
     */
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/findUserAndMovie/{id}")
        public Map findUserAndMovie(@PathVariable("id") Integer id) {
            Map<String, Object> map = userService.findUserAndMovie(id);
            return map;
        }
    
    }
    

    service

    package com.qbb.cloud2022.service.impl;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.User;
    import com.qbb.cloud2022.mapper.UserMapper;
    import com.qbb.cloud2022.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  13:32
     * @Description:
     */
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public Map<String, Object> findUserAndMovie(Integer id) {
            User user = userMapper.findById(id);
            Map<String, Object> map = new HashMap<>();
            map.put("user", user);
            map.put("movie", null);
            return map;
        }
    }
    

    mapper

    package com.qbb.cloud2022.mapper;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.User;
    import org.apache.ibatis.annotations.Select;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  13:48
     * @Description:
     */
    public interface UserMapper {
        @Select("select * from user where id=#{id}")
        User findById(Integer id);
    }
    

    测试一下:
    image

    Nacos注册中心的服务信息:
    image

    上面我们是没有进行远程调用查询电影信息的,那么接下来我们可以使用OpenFeign实现远程的调用

    1.导入OpenFeign的依赖

     <dependency>
    	 <groupId>org.springframework.cloud</groupId>
    	 <artifactId>spring-cloud-starter-openfeign</artifactId>
    	 <version>2.2.2.RELEASE</version>
    </dependency>

    2.主启动类上加注解

    @EnableFeignClients // 开启Feign远程调用支持

    3.创建远程调用的接口FeignMovieService

    package com.qbb.cloud2022.feign;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  19:56
     * @Description:
     */
    @FeignClient(value = "nacos-provider-movie") // value属性指定被调用服务的在注册中心的服务名
    public interface FeignMovieService {
    
        @GetMapping("/movie/findById/{id}")
        public Movie findById(@PathVariable("id") Integer id);
    }
    

    测试一下:
    image

    我们查看Nacos的依赖会发现导入Nacos依赖也会同时导入Ribbon的依赖,所以可以说Nacos天生就自带负载均衡策略

    image

    我们将电影微服务copy两份,测试一下负载均衡效果,Ribbon默认是轮训的策略进,看看Nacos中是否也是

    右键电影微服务,选择Copy Configuration

    image

    修改相关参数

    image

    运行相关的四个微服务
    image

    远程调用测试一下
    image

    可以看出的确是轮训的方式,那么我想修改负载均衡策略该怎么办呢?

    Nacos为我们提供了两种凡是实现负载均衡策略

    方式一:和原来一样,整一个配置类提供相应的IRule实现类对象

    package com.qbb.cloud2022.config;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  20:22
     * @Description:
     */
    @Configuration
    public class IRuleConfig {
        
        @Bean
        public IRule iRule(){
            return new RandomRule(); // 使用随机的负载均衡策略
        }
    }

    方式二:yml配置文件方式(当然也可以自定义的)

    stock-service:
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  #指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
        eager-load:
          enabled: true #开启ribbon饥饿加载
          clients: stock-service  #配置stock-service使用ribbon饥饿加载,多个使用逗号分隔

    接下来我们使用Nacos整合一下Hystrix,实现服务熔断,降级,限流

    导入Hystrix依赖

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    	<version>2.2.2.RELEASE</version>
    </dependency>

    主启动上加入注解

    @EnableCircuitBreaker // 开启Hystrix

    创建一个兜底的处理器,实现远程调用的方法进行兜底

    package com.qbb.cloud2022.handler;
    
    import com.qbb.cloud2022.com.qbb.springcloud.entity.Movie;
    import com.qbb.cloud2022.feign.FeignMovieService;
    import org.springframework.stereotype.Component;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-03  20:42
     * @Description:
     */
    @Component
    public class FeignMovieServiceExceptionHandler implements FeignMovieService {
    
    
        @Override
        public Movie findById(Integer id) {
            Movie movie = new Movie();
            movie.setId(-1);
            movie.setName("网络故障,请稍后再试");
            return movie;
        }
    }
    

    注意别忘记在yml文件中配置

    feign:
      hystrix:
        enabled: true # 开启feign对hystrix的支持

    修改服务端代码,关闭所有的服务端和重启消费端,测试一下
    image

    image

    image

    Nacos 与其他服务注册中心对比

    image

    3.Nacos中的数据模型

    Namespace 命名空间、Group 分组、集群这些都是为了进⾏归类管理,把服务和配置⽂件进⾏归类,归类之后就可以实 现⼀定的效果, ⽐如,对于服务来说,不同命名空间中的服务不能够互相访问调⽤。

    image

    • Namespace:命名空间,对不同的环境进⾏隔离,⽐如隔离开发环境、测试环境和⽣产环境
    • Group:分组,将若⼲个服务或者若⼲个配置集归为⼀组,通常习惯⼀个系统归为⼀个组
    • Service:某⼀个服务,⽐如简历微服务
    • DataId:配置集或者可以认为是⼀个配置⽂件

    推荐用法:
    image

    服务的分级存储模型

    image

    每个服务也可以组成多个集群,多个集群又包含了多个实例.并且微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。

    如何给服务分配集群呢?
    image

    重启微服务:
    image

    访问:http://localhost:6700/user/findUserAndMovie/1 发现,默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡, 因此 Nacos 中提供了一个 NacosRule的实现,可以优先从同集群中挑选实例。

    nacos-provider-movie: #被调用方在nacos注册中心的服务名
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

    权重配置:
    image

    如果权重修改为 0,则该实例永远不会被访问,可以实现无缝上线应用

    环境隔离

    同一个命名空间下的服务是可以相互调用的,反之则不能

    我现在修改nacos-provider-movie6600的namespace

    namespace: 3ad61d82-3435-4729-86e2-57f828280e9f # 修改namespace环境

    重启测试:
    image

    注意在Nacos分为两种实例,临时实例和永久实例(eureka只有临时实例),临时实例采用心跳模式,非临时实例采用主动检测模式

    修改yml配置文件可以将实例设置为永久实例.这样即使实例宕机了,Nacos服务端也不会将其剔除,等宕机的服务重新启动了,又会自动注册进注册中心

    ephemeral: true # 将此服务设置为永久实例

    Nacos没有永久实例时,遵循AP(可用性,分区容错性!eureka也是如此),有永久实例时,遵循CP(强一致性,分区容错性)

    image

    当我把服务nacos-provider-movie6600关掉,会发现Nacos并不会将服务剔除掉

    4.Nacos作为配置中心

    Nacos 除了可以做注册中心,同样可以做配置管理来使用。nacos 作为配置中心可以做到系统配置的集中管理(编辑、 存储、分发)、动态更新不重启、回滚配置(变更管理、历史版本管理、变更审计)等所有与配置相关的活动。有 Nacos 之后,分布式配置就简单很多 Github 不需要了(配置信息直接配置在 Nacos server 中),Bus 也不需要了(依然可 以完成配置文件的热更新, 及时通知微服务)。如果微服务架构中没有使用统一配置中心时,所存在的问题:

    • 配置文件分散在各个项目⾥,微服务实例的数量达到上百个的时候,实在是不方便维护
    • 配置内容安全与权限
    • 更新配置后,项目需要重启,即使不需要重启也需要运维人员使用curl发送请求执行更新

    image

    添加配置文件

    image

    注意dataId格式
    image

    1.prefix 默认为所属工程配置spring.application.name 的值(nacos-provider-movie*),也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
    2.spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为 空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
    3.file-exetension 为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

    上面我们在Nacos中创建了一个配置文件,接下来我们怎么在微服务中使用呢?

    1.导入Nacos作为配置中心的依赖
    <dependency>
    	<groupId>com.alibaba.cloud</groupId>
    	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    2.在bootstrap.yml文件中添加如下配置

    spring:
      cloud:
        nacos:
          server-addr: 192.168.137.72:8848
          config:
            file-extension: yml # 配置文件默认的后缀是properties文件,如果是yml,必须指定
      profiles:
        active: dev

    3.编写测试代码

    package com.qbb.cloud2022.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-06  18:49
     * @Description:
     */
    @RestController
    public class HelloController {
        @Value("${user.age}")
        private Integer age;
    
        @GetMapping("/hello")
        public Integer hello() {
            return age;
        }
    }
    

    4.结果

    image

    5.那如何实现修改配置中心的文件实现热加载呢?

    只需要在指定位置加上注解@RefreshScope 实现自动更新

    @RefreshScope

    名称空间切换环境

    创建两个环境分别为dev和test

    image

    将public中的配置文件clone到dev和test环境

    image

    修改dev和test环境配置文件的内容

    image

    配置namespace

    namespace: c6ab48bd-2159-450e-aef8-65095e015036 # 指定环境变量的唯一标识

    image

    测试一下

    image

    配置文件回滚到某个历史版本

    image

    image

    加载多配置文件

    在dev命名空间下创建mysql.yml,redis.yml
    image

    image

    修改bootstrap.yml

     extension-configs:
              - dataId: mysql.yml
                refresh: true
              - dataId: redis.yml
                refresh: true

    修改controller层代码

    package com.qbb.cloud2022.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
     * @version 1.0
     * @date 2022-04-06  18:49
     * @Description:
     */
    @RestController
    @RefreshScope
    public class HelloController {
    
    
        @Value("${user.age}")
        private Integer age;
    
        @Value("${mysql.port}")
        private Integer mysqlPort;
    
        @Value("${redis.port}")
        private Integer redisPort;
    
        @GetMapping("/hello1")
        public String hello1() {
            return "age:" + age + "=mysql:" + mysqlPort + "=redis:" + redisPort;
        }
    
        @GetMapping("/hello")
        public Integer hello() {
            return age;
        }
    }
    

    测试一下:
    image

    我们还可以给配置文件添加group

    group: order # 用于区分业务

    由于我们nacos配置中心并没有order这个组,所以启动报错了
    image

    我们添加一个order组试试
    image

    修改两个order组的配置文件内容,具体内容大家自行修改就好了,直接测试
    image


    __EOF__

  • 本文作者: QIUQIU&LL
  • 本文链接: https://www.cnblogs.com/qbbit/p/16094988.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    HJ65 查找两个字符串a,b中的最长公共子串
    解决Spring Boot启动错误的技术指南
    【Elasticsearch教程16】Mapping字段类型之join
    Ubuntu 22.04 MySQL安装并设置远程访问
    java并发编程学习一——Thread
    深入理解Linux网络内 幕(七)——组件初始化的内核基础架构
    STM32-I2C硬件外设
    【CSS】你还记得组合选择器怎么用吗?
    python基于PHP+MySQL的投资理财网站的设计与实现
    Docker的应用
  • 原文地址:https://www.cnblogs.com/qbbit/p/16094988.html