Nacos服务注册和Nacos配置中心

1.构建Nacos服务

1.1Nacos概述

Nacos(DynamicNaming and Configuration Service)是一个应用于服务注册与发现、配置管理的平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。

1.2准备工作

1.2.1配置JDK1.8环境变量

1.2.2使用mysql5.7

1.2.3解压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_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=root

1.3服务启动与访问

1.3.1启动Nacos服务

在这里插入图片描述

1.3.2访问Nacos服务

输入http://localhost:8848/nacos地址
在这里插入图片描述
默认账号密码为nacos/nacos

1.3.3在IDEA中使用数据库

在这里插入图片描述
可以打开其他数据库:
在这里插入图片描述

2.服务注册与调用入门

2.1业务描述

创建两个项目Module分别为服务提供者和服务消费者(假如已有则无需创建),两者都要注册到NacosServer中(这个server本质上就是一个web服务,端口默认为8848),然后服务提供者可以为服务消费者提供远端调用服务(例如支付服务为服务提供方,订单服务为服务消费方),如图所示:
在这里插入图片描述

2.2生产者服务创建及注册

父级工程01-sca添加依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <groupId>com.jt</groupId>
    <artifactId>01-sca</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>sca-consumer</module>
        <module>sca-provider</module>
        <module>sca-gateway</module>
        <module>sca-common</module>
        <module>sca-ui</module>
    </modules>

    <!--统一依赖版本(spring boot,spring cloud,spring cloud alibaba)
    这里制作版本管理-->
    <dependencyManagement>
        <dependencies>
            <!--SpringBoot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.2.RELEASE</version>
                <type>pom</type><!--允许scope的值为import时,type的值必须为pom-->
                <scope>import</scope><!--这里import类似于java中的import-->
            </dependency>
            <!--SpringCloud(SpringCloud工程依赖于SpringBoot)
            Spring cloud中定义的是一些微服务规范-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SpringCloudAlibaba(这套依赖真是基于Spring cloud规范,做了具体的落地实现,)-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--定义公共依赖(lombok,test)-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions><!--排除一些不需要的依赖-->
                <!--SpringBoot2.2以后版本默认 单元测试使用的时junit5,
                所以junit4以前的引擎不再用-->
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <!--定义统一编译运行环境(jdk)-->
    <build>
        <plugins>
            <!--定义maven的编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2.1创建服务提供者工程(module名为sca-provider,假如已有则无需创建),继承parent工程(01-sca)

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>01-sca</artifactId>
        <groupId>com.jt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sca-provider</artifactId>
    <dependencies>
        <!--基于SpringBoot 工程的web服务依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--基于alibaba的nacos实现服务注册管理,当添加此依赖后,
        系统启动时向nacos服务发送心跳包,进行服务注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
</project>

2.2.2创建并修改配置文件application.yml(或者application.properties),实现服务注册

#服务的端口
server:
  port: 8081
#服务名
spring:
  application:
    name: sca-provider #进行服务注册必须配置服务名
#服务注册地址
spring:
 cloud:
  nacos:
    discovery:
      server-addr: localhost:8848

注意:服务名不要使用下划线(“_”),应使用横杠(“-”),这是规则。

2.2.3创建启动类

package com.jt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

3.消费者服务发现及调用

3.1在sca-provider项目中创建服务提供方对象,基于此对象对外提供服务

/**
 * 定义Controller对象(这个对象在spring mvc中给他的定义是handler),
 * 基于此对象处理客户端的请求
 */
@RestController
public class ProviderController {
    @Value("${server.port:8080}")
    private String server;

    //访问方式
    //1.浏览器直接输入http://localhost:8081/provider/echo/tedu
    //2.
    @GetMapping("/provider/echo/{msg}")
    public String doRestEcho1(@PathVariable("msg") String msg) {
        return server + "say Hello" + msg;
    }
}

3.2创建服务消费者工程(module名为sca-consumer,假如已有则无需创建),继承parent工程(01-sca)

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>01-sca</artifactId>
        <groupId>com.jt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sca-consumer</artifactId>
    <!--Web服务-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--服务的注册和发现(我们要讲服务注册到nacos)-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>
</project>

3.3创建sca-consumer服务中的配置文件application.yml

server:
  port: 8090
spring:
  application:
    name: sca-consumer
cloud:
  nacos:
    discovery:
      server-addr: localhost:8848

3.4创建消费端启动类并实现服务消费

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

3.5在sca-consumer启动类中添加如下方法,用于创建RestTemplate对象(模板方法

@Bean
public RestTemplate restTemplate(){//基于此对象实现远端服务调用
    return new RestTemplate();
}

3.6定义sca-consumer服务的消费端Controller,在此对象方法内部实现远端服务调用

@RestController
public class ConsumerController {
    /**
     * 由spring帮我们为RestTemplate对象注入一个值,
     * 然后通过此对象进行远端调用
     * */
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 当客户端(浏览器访问)
     * http://localhost:8090/consumer/doRestEcho1时
     * 在此方法内基于RestTemplate对象进行远端服务调用
     * */
    @GetMapping("/consumer/doRestEcho1")
    public String doRestEcho1(){
        //要调用的远端服务的url
        String url = "http://localhost:8081/provider/echo/8090";
        //执行远端服务调用
        return restTemplate.getForObject(url,String.class//远端url对应的方法的返回值类型(响应数据类型)
        );
    }
}

3.7知识点

  • 为什么要将服务注册到nacos?(为了更好的查找这些服务)
  • 在Nacos中服务提供者是如何向Nacos注册中心(Registry)续约的?(5秒心跳)
  • 对于Nacos服务来讲它是如何判定服务实例的状态?(检测心跳包,15,30)
  • 服务消费方是如何调用服务提供方的服务的?(RestTemplate)

4.服务负载均衡设计及实现(重点)

4.1修改ConsumerController类,注入LoadBalancerClient对象,并添加doRestEcho2方法,然后进行服务访问

    /**
     * 负载均衡客户端对象,基于此对象可获取nacos中服务实例
     * 通过负载均衡算法调用服务实例
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Value("${spring.application.name:sca-consumer}")
    private String appName;

    @GetMapping("/consumer/doRestEcho2")
    public String doRestEcho2() {
        //从nacos获取服务实例(choose方法内置了负载均衡算法)
        ServiceInstance instance = loadBalancerClient.choose("sca-provider");
        String ip = instance.getHost();
        int port = instance.getPort();
        //String url = "http://" + ip + ":" + port + "/provider/echo/"+ appName;
        String url = String.format("http://%s:%s/provider/echo/%s", ip, port, appName);//%s是占位符
//执行远端服务调用
        return restTemplate.getForObject(url, String.class//远端url对应的方法的返回值类型(响应数据类型)
        );
    }

4.2修改sca-provider的配置文件端口,分别以8081,8082端口方式进行启动

#服务的端口
server:
  port: 8082
#服务名
spring:
  application:
    name: sca-provider #进行服务注册必须配置服务名
#服务注册地址
cloud:
  nacos:
    discovery:
      server-addr: localhost:8848

4.3启动成功以后,访问nacos的服务列表,检测服务是否成功注册

在这里插入图片描述
在这里插入图片描述

4.4在idea启动nacos服务

在这里插入图片描述
在这里插入图片描述

5.@LoadBalanced

当使用@LoadBalanced注解描述RestTemplate对象时, 系统底层再基于RestTemplate进行远程服务调用时,会被一个拦截器(Interceptor)拦截到,然后进行功能增强,这里功能增强指的是:基于LoadBalancerClient对象进行服务实例获取,而这个服务实例获取的过程,底层会采用负载均衡。

@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){
    return new RestTemplate();
}

在需要RestTemplate实现负载均衡调用的地方进行依赖注入.例如在ConsumerController类中添加loadBalancedRestTemplate属性

@Autowired
private RestTemplate loadBalancedRestTemplate;

接下来,可以在对应的服务端调用方的方法内,基于RestTemplate借助服务名进行服务调用

@GetMapping("/consumer/doRestEcho3")
public String doRestEcho3(){
    //定义远程调用的url
    String url = String.format("http://sca-provider/provider/echo/%s",appName);
    //执行远端服务调用
    return loadBalancedRestTemplate.getForObject(url, String.class);
}

RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalancer,核心代码如下所示(了解):

public ClientHttpResponse intercept(final HttpRequest request, 
    final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
	final URI originalUri = request.getURI();
	String serviceName = originalUri.getHost();
	return this.loadBalancer.execute(serviceName, 
    requestFactory.createRequest(request, body, execution));
}

6.Ribbon负载均衡策略

基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。
在这里插入图片描述

6.1在启动类修改负载均衡策略(随机规则)

在consumer启动类添加

@Bean
public IRule rule(){
    return new RandomRule();
}

指定默认的负载均衡策略,这种方式不够灵活,项目上线后,所有类打包成一个jar包加入项目运行过程中,想调整负载均衡算法,不太方便。

6.2在配置文件修改负载均衡策略

写在consumer的配置文件里

#sca-provider服务的负载均衡配置
sca-provider:
  ribbon: #ribbon是一个负载均衡组件,是Ribbon组件中提供了IRule接口及相关实现
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

在这里插入图片描述

7.基于Feign的远程服务调用(重点)

7.1背景

服务消费方基于rest方式请求服务提供方的服务时,一种直接的方式就是自己拼接url,拼接参数然后实现服务调用,但每次服务调用都需要这样拼接,代码量复杂且不易维护,此时Feign诞生。

7.2Feign概述

Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现。
在这里插入图片描述

7.3Feign应用实践

说明:feign方式的远程服务调用,底层会自动基于ribbon组件实现负载均衡。

7.3.1在服务消费方,添加项目依赖(SpringCloud团队基于OpenFeign研发了starter)

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

7.3.2在启动类上添加@EnableFeignClients注解

@EnableFeignClients 注解用于描述一些配置类,告诉系统启动时为@FeignClient 注解描述接口创建实现类及对象,然后把对象交给spring管理。
在这里插入图片描述

7.3.3定义Http请求API,基于此API借助OpenFeign访问远端服务

package com.jt.consumer.service;
@FeignClient(value="sca-provider")//sca-provider为服务提供者名称
public interface RemoteProviderService{
    @GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务
    public String echoMessage(@PathVariable("string") String string);
}

@FeignClient描述的接口底层会为其创建实现类。
@FeignClient 注解用于描述远程服务调用接口,其value属性值有两个层面的含义:第一个是需要的远程服务名,第二个是当前bean的名字。

7.3.4创建FeignConsumerController中并添加feign访问

@RestController
@RequestMapping("/consumer")
public class FeignConsumerController {
    @Autowired
    private RemoteProviderService remoteProviderService;
    /**基于feign方式的服务调用*/
    @GetMapping("/echo/{msg}")
    public String deFeignEcho(@PathVariable String msg){
        //基于feign方式进行远端服务调用(前提是服务必须存在)
        return remoteProviderService.echoMessage(msg);
    }
}

7.3.5启动消费者服务,在浏览器中直接通过feign客户端进行访问,如图所示(反复刷新检测其响应结果)

在这里插入图片描述

7.4Feign配置进阶实践

7.4.1一个服务提供方通常会提供很多资源服务,服务消费方基于同一个服务提供方写了很多服务调用接口,此时假如没有指定contextId,服务启动就会失败,例如,假如在服务消费方再添加一个如下接口,消费方启动时就会启动失败

/**
 * @FeignClient 注解用于描述远程服务调用接口,其value属性值有两个层面的含义:
 * 第一个是需要的远程服务名,第二个是当前bean的名字,可以使用contextId指定bean名字
 * */
@FeignClient(value = "sca-provider")
public interface RemoteOtherService {
    @GetMapping("/provider/echo/{string}")
    String echoMessage(@PathVariable("string") String string);
}

此时我们需要为远程调用服务接口指定一个contextId,作为远程调用服务的唯一标识(这个标识是Bean对象的名字)即可:

@FeignClient(value = "sca-provider",contextId = "remoteOtherService")
public interface RemoteOtherService {
    @GetMapping("/provider/echo/{string}")
    String echoMessage(@PathVariable("string") String string);
}

7.4.2当我们在进行远程服务调用时,假如调用的服务突然不可用了或者调用过程超时了,怎么办呢?一般服务消费端会给出具体的容错方案,例如,在Feign应用中通过FallbackFactory接口的实现类进行默认的相关处理

第一步:定义FallbackFactory接口的实现:

@Component
public class ProviderFallBackFactory implements FallbackFactory<RemoteProviderService> {
    @Override
    public RemoteProviderService create(Throwable throwable) {
        return new RemoteProviderService() {
            @Override
            public String echoMessage(String string) {
                return "服务超时,稍等片刻再试";
            }
        };
    }
}

第二步:在Feign访问接口中应用FallbackFactory对象:

@FeignClient(value = "sca-provider",
            contextId = "remoteProviderService",
            fallbackFactory = ProviderFallBackFactory.class)    //远程服务调用接口,value可不写
public interface RemoteProviderService {

    @GetMapping("/provider/echo/{string}")
    //在feign接口中@PathVariable后参数必须写,controller中不用写
    String echoMessage(@PathVariable("string") String string);
}

第三步:在配置文件application.yml中添加如下配置,启动feign方式调用时的服务中断处理机制:
在这里插入图片描述
第四步:在服务提供方对应的调用方法中添加Thread.sleep(5000)模拟耗时操作,然后启动服务进行访问测试:
在这里插入图片描述

8.配置中心

8.1背景分析

软件还有一些配置信息,比如数据库的用户名和密码,还有一些我们不想写死在代码里的东西,例如像线程池大小、队列长度等运行参数,以及日志级别、算法策略等, 还有一些是软件运行环境的参数,如Java 的内存大小,应用启动的参数,包括操作系统的一些 参数配置…… 所有这些东西,我们都叫做软件配置。
以前,我们把软件配置写在一个配置文件中,然而,在分布式系统下,这样的方式就变得非常不好管理,并容易出错。假如生产环境下,项目现在正在运行,此时修改了配置文件,我们需要让这些配置生效,通常的做法是不是要重启服务。但重启是不是会带来系统服务短时间的暂停,从而影响用户体验呢,还有可能会带来经济上的很大损失(例如双11重启下服务)。基于这样的背景,配置中心诞生了。

8.2配置中心概述

配置中心最基础的功能就是存储一个键值对,用户发布一个配置(configKey),然后客户端获取这个配置项(configValue);进阶的功能就是当某个配置项发生变更时,不停机就可以动态刷新服务内部的配置项,例如,在生产环境上我们可能把我们的日志级别调整为 error 级别,但是,在系统出问题我们希望对它 debug 的时候,我们需要动态的调整系统的行为的能力,把日志级别调整为 debug 级别。

8.3Nacos配置快速入门

业务描述:在sca-provider项目中添加一个Controller对象,例如ProviderLogController,基于此Controller中的方法演示日志级别的配置。

8.3.1配置准备工作:

第一步:创建ProviderLogController对象
获取字节码对象,创建一个日志对象,slf4j是基于门面模式设计的一套API,基于这个规范有Log4J,Logback等日志库。
以后只要Java中使用日志对象,你就采用下面之中方式创建即可。
假如在log对象所在的类上使用了@Slf4j注解,log不再需要我们手动创建,lombok会帮我们创建。

/**
 * 基于此controller演示配置中心的作用.
 * 在这个controller中我们会基于日志对象
 * 进行日志输出测试.
 */
//@Slf4j
@RefreshScope
@RestController
public class ProviderLogController {
    //获取字节码对象,创建一个日志对象,slf4j是基于门面模式设计的一套API,基于这个规范有Log4J,Logback等日志库
    //以后只要Java中使用日志对象,你就采用下面之中方式创建即可
    //假如在log对象所在的类上使用了@Slf4j注解,log不再需要我们手动创建,lombok会帮我们创建
    private static final Logger log = LoggerFactory.getLogger(ProviderLogController.class);
    //包名类名
    //private static final Logger log = LoggerFactory.getLogger("com.jt.provider.controller.ProviderLogController");
    //http://localhost:8081/provider/log/doLog01
    @GetMapping("/provider/log/doLog01")
    public String doLog01(){trace<debug<info<warn<error
        System.out.println("==doLog01==");
        log.trace("===trace===");
        log.debug("===debug===");
        log.info("===info===");
        log.warn("===warn===");
        log.error("===error===");
        return "log config test 01";
    }
}

第二步:在已有的sca-provider项目中添加如配置依赖

  <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>

第三步: 将项目sca-provider的application.yml的名字修改为bootstrap.yml(启动优先级最高),并添加配置中心配置

#服务注册地址
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848
        #配置中心文件扩展名
        file-extension: yml

8.3.2新建Nacos配置

其中,Data ID的值要与bootstrap.yml中定义的spring.application.name的值相同(服务名-假如有多个服务一般会创建多个配置实例,不同服务对应不同的配置实例)。
在这里插入图片描述

8.3.3测试Nacos数据读取

在这里插入图片描述

8.4@RefreshScope注解的应用

对于nacos配置中心而言,有系统内部对配置变化的感知,还有外部系统对配置的感知,假如我们系统在浏览器中能看到日志级别的变化。
其中,@RefreshScope的作用是在配置中心的相关配置发生变化以后,能够及时看到类中属性值的更新(底层是通过重新创建Controller对象的方式,对属性进行了重新初始化)。
第一步:在ProviderLogController类的上面添加一个@RefreshScope注解

@RefreshScope
@RestController
public class ProviderLogController{
  //.....
}

第二步:添加ProviderLogController中添加一个获取日志级别(debug<info<warn<error)的的属性和方法

@Value("${logging.level.com.jt:error}")
private String logLevel;
@GetMapping("/provider/log/doLog02")
public String doLog02(){
   log.info("log level is  {}",logLevel);
   return  "log level  is "+logLevel;
}

第三步:启动sca-provider服务,然后打开浏览器并输入http://localhost:8081/provider/log/doLog02进行访问测试。

说明,假如对配置的信息访问不到,请检测项目配置文件的名字是否为bootstrap.yml,检查配置文件中spring.application.name属性的值是否与配置中心的data-id名相同,还有你读取的配置信息缩进以及空格写的格式是否正确.

9.1概述

Nacos 配置管理模型由三部分构成,如图所示:
在这里插入图片描述
其中:
Namespace:命名空间,对不同的环境进⾏隔离,⽐如隔离开发环境和⽣产环境
Group:分组,将若⼲个服务或者若⼲个配置集归为⼀组。
Service/DataId:某⼀个服务或配置集,一般对应一个配置文件。

9.2命名空间设计

Nacos中的命名空间一般用于配置隔离,这种命名空间的定义一般会按照环境(开发,生产等环境)进行设计和实现.我们默认创建的配置都存储到了public命名空间
在这里插入图片描述
创建新的开发环境并定义其配置,然后从开发环境的配置中读取配置信息:
第一步:创建新的命名空间
在这里插入图片描述
在指定命名空间下添加配置,也可以直接取配置列表中克隆
在这里插入图片描述
在这里插入图片描述
此时我们修改dev命名空间中Data Id的sca-provider配置
在这里插入图片描述
修改项目module中的配置文件bootstrap.yml,添加如下配置:

#服务注册地址
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848
        file-extension: yml
        namespace: cdcc3c2c-248b-4099-99ea-9fcef6d5320c 
        #默认是public命名空间,此处为dev(开发环境)的空间id

namespace后面的字符串为命名空间的id,可直接从命名空间列表中进行拷贝.然后重启服务

9.3分组设计及实现

当我们在指定命名空间下,按环境或服务做好了配置以后,有时还需要基于服务做分组配置,例如,一个服务在不同时间节点(节假日,活动等)切换不同的配置,可以在新建配置时指定分组名称
在这里插入图片描述
这里的useLocalCache为自己定义的配置值,表示是否使用本地缓存,配置发布以后,修改boostrap.yml配置类,在其内部指定我们刚刚创建的分组:

#服务注册地址
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848
        file-extension: yml
        namespace: cdcc3c2c-248b-4099-99ea-9fcef6d5320c #默认是public命名空间,此处为dev(开发环境)的空间id
        group: DEFAULT_GROUP_51

在指定的Controller类中添加属性和方法用于获取和输出DEFAULT_GROUP_51中的useLocalCache的值:

@RefreshScope
@RestController
public class ProviderCacheController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/provider/cache01")
    public String doUseLocalCache01(){
        return "useLocalCache'value is " + useLocalCache;
    }

然后重启服务,进行访问测试,检测内容输出:
在这里插入图片描述

9.4共享配置设计及读取

当同一个namespace的多个配置文件中都有相同配置时,可以对这些配置进行提取,然后存储到nacos配置中心的一个或多个指定配置文件,哪个微服务需要,就在服务的配置中设置读取即可。
**第一步:在nacos中创建一个共享配置文件:**这里的secret可以理解为一个密钥。
在这里插入图片描述
第二步:在指定的微服务配置文件(bootstrap.yml)中设置对共享配置文件的读取:

#服务注册地址
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848
        #配置中心文件扩展名
        file-extension: yml
        namespace: cdcc3c2c-248b-4099-99ea-9fcef6d5320c #默认是public命名空间,此处为dev(开发环境)的空间id
        #group: DEFAULT_GROUP_51
        #共享配置
        shared-configs[0]:
          data-id: app-public.yml
          refresh: true   #默认false,共享配置更新,引用此配置的地方是否要更新
        #shared-configs:
          #- app-public.yml #不能共享配置更新

第三步:在指定的Controller类中读取和应用共享配置即可:

@RefreshScope
@RestController
public class ProviderSecretController {
    @Value("${app.secret:123456}")
    private String secret;
    @GetMapping("/provider/secret")
    public String doGetSecret(){
        return String.format("the secret is %s", secret);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值