Nacos服务注册中心


文章目录

  • Nacos服务注册中心
    • 一、Nacos服务注册中心
      • 1. 注册中心简介
      • 2. 构建Nacos服务
        • 2.1 准备工作
        • 2.2 下载与安装
        • 2.3 初始化配置
      • 3. 服务启动与访问
        • 3.1 业务描述
        • 3.2 生产者服务创建及注册
        • 3.3 消费者服务发现及调用
        • 3.4 小节面试分析
    • 二、服务负载均衡设计及实现
      • 1. LoadBalancerClient应用
      • 2. @LoadBalanced
      • 3. Ribbon负载均衡策略
      • 4. 小节面试分析
    • 三、基于Feign的远程服务调用
      • 1. Feign是什么
      • 2. Feign应用实践
      • 3. Feign配置进阶实践
      • 4. Feign 调用过程分析
    • 四、Nacos配置快速入门
      • 1. 配置准备工作
      • 2. 新建Nacos配置
      • 3. 测试Nacos数据读取
      • 4. @RefreshScope注解的应用
      • 5. 小节面试分析
    • 五、Nacos配置管理模型
      • 1. 概述
      • 2. 命名空间设计
      • 3. 分组设计及实现
      • 4. 共享配置设计及读取
      • 5. 小节面试分析
      • 6. 总结(Summary)

一、Nacos服务注册中心

1. 注册中心简介

背景分析

在微服务中,首先需要面对的问题就是如何查找服务(软件即服务),其次,就是如何在不同的服务之间进行通信?如何更好更方便的管理应用中的每一个服务,如何建立各个服务之间联系的纽带,由此注册中心诞生(例如淘宝网卖家提供服务,买家调用服务)。

市面上常用注册中心有Zookeeper(雅虎Apache),Eureka(Netfix),Nacos(Alibaba),Consul(Google),那他们分别都有什么特点,我们如何进行选型呢?我们主要从社区活跃度,稳定性,功能,性能等方面进行考虑即可.本次微服务的学习,我们选择Nacos,它很好的支持了阿里的双11活动,不仅可以做注册中心,还可以作为配置中心,稳定性和性能都很好。

Nacos概述

Nacos(DynamicNaming and Configuration Service)是一个应用于服务注册与发现、配置管理的平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。其官网地址如下:https://nacos.io/zh-cn/docs/quick-start.html

2. 构建Nacos服务

2.1 准备工作

第一: 确保你电脑已配置JAVA_HOME环境变量(Nacos启动时需要)


第二: 确保你的MySQL版本为5.7以上(MariaDB10.5以上)

2.2 下载与安装

第一步: Nacos下载,可在浏览器直接输入如下地址

https://github.com/alibaba/nacos/releases

第二步: 选择对应版本,直接下载


第三步: 解压Nacos(最好不要解压到中文目录下),其目录结构如下

2.3 初始化配置

第一步: 打开操作系统命令行,登陆mysql,执行课前资料中的sql脚本,不是nacos/conf目录下自带的。

例如,我们可以使用mysql自带客户端,在命令行首先登录mysql,然后执行如下指令:

source d:/nacos-mysql.sql

执行成功以后,会创建一个nacos_config数据库,打开数据库会看到一些表,例如;


说明:在执行此文件时,要求mysql的版本大于5.7版本(MariaDB最好10.5.11),否则会出现如下错误:


第二步: 打开/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

3. 服务启动与访问

第一步: 启动Nacos服务(nacos的bin目录去通过指令启动)。

Linux/Unix/Mac启动命令(standalone代表着单机模式运行,非集群模式):

./startup.sh -m standalone

Windows启动命令(standalone代表着单机模式运行,非集群模式):

startup.cmd -m standalone

说明:

  1. 执行执行令时要么配置环境变量,要么直接在nacos/bin目录下去执行.
  2. nacos启动时需要本地环境变量中配置了JAVA_HOME(对应jdk的安装目录),
  3. 一定要确保你连接的数据库(nacos_config)是存在的.
  4. 假如所有的配置都正确,还连不上,检查一下你有几个数据库(mysql,…)

第二步: 访问Nacos服务。

打开浏览器,输入http://localhost:8848/nacos地址,出现如下登陆页面:

其中,默认账号密码为nacos/nacos.

3.1 业务描述

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

3.2 生产者服务创建及注册

第一步: 创建服务提供者工程(module名为sca-provider,假如已有则无需创建),继承parent工程(01-sca),其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 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><!--Web服务--><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>

第二步: 创建并修改配置文件application.yml(或者application.properties),实现服务注册,关键代码如下:

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

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

第三步: 创建启动类(假如已有则无需定义),关键代码如下:

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

第四步: 启动启动类,然后刷先nacos服务,检测是否服务注册成功,如图所示:

第五步: 停掉sca-provider服务,然后不断刷新nacos服务列表,检查服务的健康状态。

3.3 消费者服务发现及调用

第一步: 在sca-provider项目中创建服务提供方对象,基于此对象对外提供服务,例如:

    package com.jt.provider.controller;/**定义Controller对象(这个对象在spring mvc中给他的定义是handler),* 基于此对象处理客户端的请求*/@RestControllerpublic class ProviderController{//@Value默认读取项目配置文件中配置的内容//8080为没有读到server.port的值时,给定的默认值@Value("${server.port:8080}")private String server;//http://localhost:8081/provider/echo/tedu@GetMapping("/provider/echo/{msg}")public String doRestEcho1(@PathVariable String msg){return server+" say hello "+msg;}}

第二步: 创建服务消费者工程(module名为sca-consumer,假如已有则无需创建),继承parent工程(01-sca),其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 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><dependencies><!--Web服务--><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>

第三步: 创建sca-consumer服务中的配置文件application.yml,关键代码如下:

server:port: 8090
spring:application:name: sca-consumer #服务注册时,服务名必须配置cloud:nacos:discovery:server-addr: localhost:8848 #从哪里去查找服务

第四步: 创建消费端启动类并实现服务消费,关键代码如下:

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

第五步: 在sca-consumer启动类中添加如下方法,用于创建RestTemplate对象

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

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

package com.jt.consumer.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** 定义服务消费端Controller,在这个Controller对象* 的方法中实现对远端服务sca-provider的调用*/
@RestController
public class ConsumerController {/*** 从spring容器获取一个RestTemplate对象,* 基于此对象实现远端服务调用*/@Autowiredprivate RestTemplate restTemplate;/*** 在此方法中通过一个RestTemplate对象调用远端sca-provider中的服务* @return* 访问此方法的url: http://localhost:8090/consumer/doRestEcho1*/@GetMapping("/consumer/doRestEcho1")public String doRestEcho01(){//1.定义要调用的远端服务的urlString url="http://localhost:8081/provider/echo/8090";//2.基于restTemplate对象中的相关方法进行服务调用return restTemplate.getForObject(url, String.class);}
}

第七步: 启动消费者服务,并在浏览器输入http://localhost:8090/consumer/doRestEcho1地址进行访问测试。

3.4 小节面试分析

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

二、服务负载均衡设计及实现

业务描述

一个服务实例可以处理请求是有限的,假如服务实例的并发访问比较大,我们会启动多个服务实例,让这些服务实例采用一定策略均衡(轮询,权重,随机,hash等)的处理并发请求,在Nacos中服务的负载均衡(Nacos客户端负载均衡)是如何应用的?

1. LoadBalancerClient应用

LoadBalancerClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于特点算法实现负载均衡方式的调用,案例实现如下:

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

 @Autowiredprivate LoadBalancerClient loadBalancerClient;@Value("${spring.application.name:8090}")private String appName;@GetMapping("/consumer/doRestEcho02")public String doRestEcho02(){ServiceInstance serviceInstance = loadBalancerClient.choose("sca-provider");String url = String.format("http://%s:%s/provider/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);System.out.println("request url:"+url);return restTemplate.getForObject(url, String.class);}}

第二步: 打开Idea服务启动配置,如图所示:


第三步: 修改并发运行选项(假如没有找到这个选项我们需要通过搜索引擎基于组合查询的方法,去找到对应的解决方案,例如搜索 idea allow parallel run),如图所示:

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

server:port: 8082
spring:application:name: sca-providercloud:nacos:server-addr: localhost:8848

第五步: 启动成功以后,访问nacos的服务列表,检测服务是否成功注册,如图所示:


第六步: 启动sca-consumer项目模块,打开浏览器对consumer服务进行访问,访问时不断刷新,检测页面数据变化。

说明,这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。

2. @LoadBalanced

当使用RestTemplate进行远程服务调用时,假如需要负载均衡,还可以在RestTemplate对象构建时,使用@LoadBalanced对构建RestTemplate的方法进行修饰,例如在ConsumerApplication中构建名字为loadBalancedRestTemplate的RestTemplate对象:

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

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

@Autowired
private RestTemplate loadBalancedRestTemplate;

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

@GetMapping("/consumer/doRestEcho3")
public String doRestEcho03(){String url=String.format("http://%s/provider/echo/%s","sca-provider",appName);//向服务提供方发起http请求,获取响应数据return loadBalancedRestTemplate.getForObject(url,//要请求的服务的地址String.class);//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));
}

@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。

3. Ribbon负载均衡策略

基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。如图所示:


当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略.

4. 小节面试分析

1.@Bean注解的作用?

一般用于配置类内部,描述相关方法,用于告诉spring此方法的返回值要交给spring管理,bean的名字默认为方法名,假如需要指定名字可以@Bean(“bean的名字”),最多的应用场景是整合第三方的资源-对象

2.@Autowired注解的作用?

此注解用于描述属性,构造方法,set方法等,用于告诉spring框架,按找一定的规则为属性进行DI操作,默认按属性,方法参数类型查找对应的对象,假如只找到一个,则直接注入,类型多个时还会按照属性名或方法参数名进行值的注入,假如名字也不同,就出报错.

3.Nacos中的负责均衡底层是如何实现的?

通过Ribbon实现,Ribbon中定义了一些负载均衡算法,然后基于这些算法从服务实例中获取一个实例为消费方法提供服务

4.Ribbon 是什么?

Netflix公司提供的负载均衡客户端,一般应用于服务的消费方法

5.Ribbon 可以解决什么问题?

基于负载均衡策略进行服务调用, 所有策略都会实现IRule接口

6.Ribbon 内置的负载策略都有哪些?

8种,可以通过查看IRule接口的实现类进行分析

7.@LoadBalanced的作用是什么?

描述RestTemplate对象,用于告诉Spring框架,在使用RestTempalte进行服务调用时,这个调用过程会被一个拦截器进行拦截,然后在拦截器内部,启动负载均衡策略。

8.我们可以自己定义负载均衡策略吗?

可以,基于IRule接口进行策略定义,也可以参考NacosRule进行实现

三、基于Feign的远程服务调用

背景分析

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

1. Feign是什么

Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现。如图所示:


Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,最终 Feign 由一些社区进行维护,更名为 OpenFeign。

2. Feign应用实践

第一步: 在服务消费方,添加项目依赖(SpringCloud团队基于OpenFeign研发了starter),代码如下:

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

第二步: 在启动类上添加@EnableFeignClients注解,代码如下:

@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {…}

第三步: 定义Http请求API,基于此API借助OpenFeign访问远端服务,代码如下:

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

其中,@FeignClient描述的接口底层会为其创建实现类。

第四步: 创建FeignConsumerController中并添加feign访问,代码如下:

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

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


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

3. Feign配置进阶实践

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

 @FeignClient(name="sca-provider")public interface RemoteOtherService {@GetMapping("/doSomeThing")public String doSomeThing();
}

其启动异常如下:

The bean 'optimization-user.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.

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

@FeignClient(name="sca-provider",contextId="remoteProviderService")//sca-provider为服务提供者名称
interface RemoteProviderService{@GetMapping("/provider/echo/{string}")//前提是远端需要有这个服务public String echoMessage(@PathVariable("string") String string);
}

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

第一步: 定义FallbackFactory接口的实现,代码如下:

package com.jt.service.factory;
/*** 基于此对象处理RemoteProviderService接口调用时出现的服务中断,超时等问题*/
@Component
public class ProviderFallbackFactory implements FallbackFactory<RemoteProviderService> {/*** 此方法会在RemoteProviderService接口服务调用时,出现了异常后执行.* @param throwable 用于接收异常*/@Overridepublic RemoteProviderService create(Throwable throwable) {return (msg)->{return "服务维护中,稍等片刻再访问";};}
}

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

@FeignClient(name = "sca-provider", contextId = "remoteProviderService",fallbackFactory = ProviderFallbackFactory.class)//sca-provider为nacos中的服务名
public interface RemoteProviderService {@GetMapping("/provider/echo/{msg}")public String echoMsg(@PathVariable String msg);
}

第三步: 在配置文件application.yml中添加如下配置,启动feign方式调用时的服务中断处理机制.

feign:  hystrix:enabled: true #默认值为false

第四步: 在服务提供方对应的调用方法中添加Thread.sleep(5000)模拟耗时操作,然后启动服务进行访问测试.

4. Feign 调用过程分析

Feign应用过程分析(底层逻辑先了解):

  1. 通过 @EnableFeignCleints 注解告诉springcloud,启动 Feign Starter 组件。
  2. Feign Starter 会在项目启动过程中注册全局配置,扫描包下所由@FeignClient注解描述的接口,然后由系统底层创建接口实现类(JDK代理类),并构建类的对象,然后交给spring管理(注册 IOC 容器)。
  3. Feign接口被调用时,底层代理对象会将接口中的请求信息通过编码器创建 Request对象,基于此对象进行远程过程调用。
  4. Feign客户端请求对象会经Ribbon进行负载均衡,挑选出一个健康的 Server 实例(instance)。
  5. Feign客户端会携带 Request 调用远端服务并返回一个响应。
  6. Feign客户端对象对Response信息进行解析然后返回客户端。

四、Nacos配置快速入门

业务描述

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

1. 配置准备工作

第一步: 创建ProviderLogController对象,例如:

package com.jt.provider.controller;import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/*** 基于此controller演示配置中心的作用.* 在这个controller中我们会基于日志对象* 进行日志输出测试.*/
//@Slf4j
@RestController
public class ProviderLogController {//创建一个日志对象//org.slf4j.Logger (Java中的日志API规范,基于这个规范有Log4J,Logback等日志库)//org.slf4j.LoggerFactory//log对象在哪个类中创建,getLogger方法中的就传入哪个类的字节码对象//记住:以后只要Java中使用日志对象,你就采用下面之中方式创建即可.//假如在log对象所在的类上使用了@Slf4j注解,log不再需要我们手动创建,lombok会帮我们创建private static Logger log=LoggerFactory.getLogger(ProviderLogController.class);@GetMapping("/provider/log/doLog01")public String doLog01(){//trace<debug<info<warn<errorSystem.out.println("==doLog01==");log.trace("===trace===");log.debug("===debug===");log.info("===info====");log.warn("===warn===");log.error("===error===");return "log config test";}
}

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

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

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

spring:application:name: sca-providercloud:nacos:discovery:server-addr: 127.0.0.1:8848config:server-addr: 127.0.0.1:8848file-extension: yml # Configure the data format of the content, default to properties

2. 新建Nacos配置

打开nacos配置中心,新建配置,如图所示:


其中,Data ID的值要与bootstrap.yml中定义的spring.application.name的值相同(服务名-假如有多个服务一般会创建多个配置实例,不同服务对应不同的配置实例)。配置发布以后,会在配置列表中,显示我们的配置,例如:

3. 测试Nacos数据读取

配置创建好以后,启动sca-provider服务,然后打开浏览器,输入http://localhost:8081/provider/log/doLog01,检测idea控制台日志输出。然后再打开nacos控制台动态更新日志级别,再访问资源并检测后台日志输出.

然后,修改nacos配置中心的日志级别,再刷新浏览器,检测日志的输出,是否会发生变化.

4. @RefreshScope注解的应用

对于nacos配置中心而言,有系统内部对配置变化的感知,还有外部系统对配置的感知,假如我们系统在浏览器中能看到日志级别的变化,该如何实现呢?我们现在来实现一个案例.

第一步: 在ProviderLogController类的上面添加一个@RefreshScope注解,例如:

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

其中,@RefreshScope的作用是在配置中心的相关配置发生变化以后,能够及时看到类中属性值的更新(底层是通过重新创建Controller对象的方式,对属性进行了重新初始化)。

第二步: 添加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;
}

5. 小节面试分析

1.配置中心一般都会配置什么内容?

可能会经常变化的配置信息,例如连接池,日志、线程池、限流熔断规则

2.什么信息一般不会写到配置中心?

服务端口,服务名,服务的注册地址,配置中心

3.项目中为什么要定义bootstrap.yml文件?

此文件被读取的优先级比较高,可以在服务启动时读取配置中心的数据

4.Nacos配置中心宕机了,我们的服务还可以读取到配置信息吗?

可以从内存,客户端获取了配置中心的配置信息以后,会将配置信息在本地内存中存储一份.

5.微服务应用中我们的客户端如何获取配置中心的信息?

我们的服务一般首先会从内存读取配置信息,同时我们的微服务还可以定时向nacos配置中心发请求拉取(pull)更新的配置信息

6.微服务应用中客户端如何感知配置中心数据变化?

1.4.x版本的nacos客户端会基于长轮询机制从nacos获取配置信息,所谓的长轮询就是没有配置更新时,会在nacos服务端的队列进行等待.

7.服务启动后没有从配置中心获取我们的配置数据是什么原因?

依赖,配置文件名字bootstrap.yml,配置中心的dataId名字是否正确,分组是否正确,配置的名字是否正确,缩进关系是否正确,假如是动态发布,类上是否有@RefreshScope注解

8.你项目中使用的日志规范是什么?

SLF4J

9.你了解项目中的日志级别吗?

debug,info,error,…,可以基于日志级别控制日志的输出

五、Nacos配置管理模型

1. 概述

Nacos 配置管理模型由三部分构成,如图所示:

其中:

  • Namespace:命名空间,对不同的环境进⾏隔离,⽐如隔离开发环境和⽣产环境。
  • Group:分组,将若⼲个服务或者若⼲个配置集归为⼀组。
  • Service/DataId:某⼀个服务或配置集,一般对应一个配置文件。

2. 命名空间设计

Nacos中的命名空间一般用于配置隔离,这种命名空间的定义一般会按照环境(开发,生产等环境)进行设计和实现.我们默认创建的配置都存储到了public命名空间,如图所示:

创建新的开发环境并定义其配置,然后从开发环境的配置中读取配置信息,该如何实现呢?

第一步: 创建新命名空间,如图所示:

命名空间成功创建以后,会在如下列表进行呈现。

在指定命名空间下添加配置,也可以直接取配置列表中克隆,例如:


克隆成功以后,我们会发现在指定的命名空间中有了我们克隆的配置,如图所示:

此时我们修改dev命名空间中Data Id的sca-provider配置,如图所示:

修改项目module中的配置文件bootstrap.yml,添加如下配置,关键代码如下:

spring:cloud:nacos:config:namespace: 6058fd3f-0d4d-44f2-85d6-5fc7d2348046……

其中,namespace后面的字符串为命名空间的id,可直接从命名空间列表中进行拷贝.然后重启服务,继续刷新http://localhost:8081/provider/log/doLog02地址。检测输出,看看输出的内容是什么,是否为dev命名空间下配置的内容。

3. 分组设计及实现

当我们在指定命名空间下,按环境或服务做好了配置以后,有时还需要基于服务做分组配置,例如,一个服务在不同时间节点(节假日,活动等)切换不同的配置,可以在新建配置时指定分组名称,如图所示:

其中,这里的useLocalCache为自己定义的配置值,表示是否使用本地缓存.

配置发布以后,修改boostrap.yml配置类,在其内部指定我们刚刚创建的分组,代码如下:

server:port: 8081
spring:application:name: sca-providercloud:nacos:config:server-addr: 127.0.0.1:8848group: DEFAULT_GROUP_51 # Group, default is DEFAULT_GROUPfile-extension: yml # Configure the data format of the content, default to propertiesnamespace: 7da4aa75-f64c-43c6-b101-9d77ad96f1c0

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

package com.jt.provider.controller;@RefreshScope
@RestController
public class ProviderCacheController {@Value("${useLocalCache:false}")private boolean useLocalCache;@RequestMapping("/provider/cache01")public String doUseLocalCache01(){return "useLocalCache'value is   "+useLocalCache;}
}

然后重启服务,进行访问测试,检测内容输出。

4. 共享配置设计及读取

当同一个namespace的多个配置文件中都有相同配置时,可以对这些配置进行提取,然后存储到nacos配置中心的一个或多个指定配置文件,哪个微服务需要,就在服务的配置中设置读取即可。例如:

第一步: 在nacos中创建一个共享配置文件,例如:

其中,这里的secret可以理解为一个密钥。

第二步: 在指定的微服务配置文件(bootstrap.yml)中设置对共享配置文件的读取,例如:

spring:application:name: sca-providercloud:nacos:config:server-addr: localhost:8848# 命名空间namespace: 83ed55a5-1dd9-4b84-a5fe-a734e4a6ec6d# 分组名# group: DEFAULT_GROUP# 配置中心文件扩展名file-extension: yml# 共享配置shared-configs[0]:data-id: app-public.ymlrefresh: true #默认false,共享配置更新,引用此配置的地方是否要更新

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

package com.jt.provider.controller;@RefreshScope
@RestController
public class ProviderSecretController {@Value("${app.secret:123456}")private String secret;@GetMapping("/provider/secret")public String doGetSecret(){//return String.format()return "The Secret is "+secret;}
}

**第四步:**启动服务,然后打开浏览器进行访问测试。

5. 小节面试分析

1.Nacos配置管理模型的背景?

环境不同配置不同

2.Nacos配置中的管理模型是怎样的?

namespace,group,service/data-id

3.Nacos客户端(微服务)是否可以读取共享配置?

可以

6. 总结(Summary)

重难点分析

  • 配置中心的选型。(市场活跃度、稳定性、性能、易用)
  • Nacos配置中心基本应用。(新建,修改、删除配置以后,在Nacos客户端应用配置)
  • 配置管理模型应用。(namespace,group,service/dataId)
  • Nacos配置变更的动态感知。(底层原理分析)

FAQ分析

  • 为什么需要配置中心?(动态管理发布配置,无需重启服务,更好保证服务的可用)
  • 配置中一般要配置什么内容?(经常变化的配置数据-日志级别,线程池、连接池、…)
  • 市面上有哪些主流配置中心?(Nacos,….)
  • 配置中心选型时要重点考虑哪些因素?(市场活跃度、稳定性、性能、易用)
  • Nacos客户端(微服务业务)如何动态感知配置中心数据变化的?(nacos2.0之前nacos客户端采用长轮询机制每隔30秒拉取nacos配置信息.)
  • Nacos配置管理模型是怎样的?(命名空间-namespace,分组-group,服务实例-dataId)

二、Nacos服务注册中心应用实践相关推荐

  1. 1.4 Nacos服务注册中心应用实践

    文章目录 1.注册中心简介 1.1 背景分析 1.2 Nacos概述 2.构建Nacos服务 2.1 准备工作 2.2 下载与安装 2.3 初始化配置 2.4 服务启动与访问 2.4.1 命令行启动 ...

  2. Nacos服务注册中心应用实践

    目录 注册中心简介 背景分析 Nacos概述 构建Nacos服务 准备工作 下载与安装 初始化配置 服务启动与访问 消费者服务发现及调用 思路总结: 注册中心简介 背景分析 如何更好更方便的管理应用中 ...

  3. 微服务2——服务的注册,调用(Nacos服务注册中心+服务调用+调用负载均衡)sca-comsumersca-provider

    一.Nacos的安装和构建  以及启动 其官网地址如下: Nacos官网 1.安装前提: 第一:确保你电脑已配置JAVA_HOME环境变量(Nacos启动时需要),例如: 第二:确保你的MySQL版本 ...

  4. 04-Nacos服务注册中心应用实践

    文章目录 注册中心简介 背景分析 Nacos概述 构建Nacos服务 准备工作 下载与安装 初始化配置 服务启动与访问 服务注册与调用入门(重点) 业务描述 生产者服务创建及注册 消费者服务发现及调用 ...

  5. Nacos服务注册中心

    文章目录 注册中心简介 背景分析 Nacos概述 构建Nacos服务 准备工作 下载与安装 初始化配置 服务启动与访问 服务注册与调用入门(重点) 业务描述 生产者服务创建及注册 消费者服务发现及调用 ...

  6. Nacos服务注册中心(微服务)

    为什么要用服务注册中心? 在微服务中,首先需要面对的问题就是如何查找服务(软件即服务), 其次就是如何在不同的服务之间进行通信? 如何更好更方便的管理应用中的每一个服务,如何建立各个服务之间联系的纽带 ...

  7. 微服务 注册中心的作用_SpringCloud(二)服务注册中心与Eureka工作原理介绍

    微服务的注册中心 author:QYX 注册中心可以说是微服务架构中的通讯录,它记录了服务和服务地址的映射关系,在分布式架构中,服务会注册到这里,当服务需要调用其他服务时, 就会在这里找到服务的地址, ...

  8. SpringCloud Alibaba微服务实战(二) - Nacos服务注册与restTemplate消费

    说在前面 基础环境搭建,理论,请看上一篇,在这就不扯理论了,直接上代码. 项目结构 代码实现 第一步:在父pom的项目中引入dependencyManagement 在引入父pom之前咱们先来回顾下d ...

  9. Spring Cloud H (二)服务注册中心 Zookeeper

    目录 前言 一.Zookeeper数据结构 二.统一配置管理 三.统一命名服务 四.Zookeeper安装启动 五.zoo.conf参数解读 六.集群搭建 七.Zookeeper Session 为什 ...

最新文章

  1. 手动建库11.2.0.4
  2. 命令行的艺术 (GitHub 星标 6 万多)
  3. 在VMware ESX Server使用华为存储
  4. PostgreSQL on XFS 性能优化 - 1
  5. python如何实现多进程_Python实现多进程的四种方式
  6. 计算机设计策略,专家经验谈:Excel工作表的设计策略
  7. 多个Spring Boot项目部署在一个Tomcat容器无法启动
  8. QT的QFormBuilder类的使用
  9. 时序分析:HMM模型(状态空间)
  10. ML.NET 0.8特性简介
  11. 移动端,fixed bottom问题
  12. 高性能MySQL—第一章 MySQL架构与历史
  13. Android实例-屏幕操持常亮(XE8+小米2)
  14. 电信充q币短信怎么发_移动、联通、电信话费快来领!微信小额提现免手续费方法!刚需羊毛!...
  15. 防风网-挡风抑尘墙:挡风抑尘墙
  16. Node进阶:核心模块http简介
  17. 商业模式画布 - 天涯的日志 - 网易博客
  18. 编程入门书籍:大学学习计算机基础必读 5 本经典入门书籍,收藏
  19. 如此详细的尾灯模组方案,不看看吗?
  20. Google Earth Engine(GEE)——MODIS 影像LST地表温度随时间变化的趋势案例分析

热门文章

  1. 基于html的策略类游戏开发,基于HTML5的即时战略游戏的设计与实现
  2. Swift-编程一小时
  3. 【缅怀妈妈系列诗歌】之十九:妈妈,祝您生日快乐
  4. wp load.php下载,WP 代码分析:wp-load.php
  5. 01Trie树 CF923C Perfect Security
  6. 亚马逊测评技术怎么样?到底能不能做?赚钱吗?
  7. CSDN 职场论坛问答精选1
  8. 沃趣科技与「DaoCloud 道客」达成生态合作,共同助推数字化新发展
  9. 用Python爬虫获取网络拍卖行的艺术品价格和拍卖结果
  10. (目录)[0]尝试用Unity3d制作一个王者荣耀(持续更新)-游戏规划