vlambda博客
学习文章列表

基于Nacos的服务治理、配置中心

基于Nacos的服务治理、配置中心

Nacos集群环境的搭建

参看《基于Docker搭建Nacos集群》:https://lupf.cn/articles/2020/05/21/1590058654840.html ;亦或者通过官方提供的其他方式安装,详情参考:https://nacos.io/zh-cn/docs/quick-start.html

Nacos作为配置中心

  • apollo配置中心 整理Nacos的服务治理,顺带着整理一下Nacos的配置中心;目前实际的生产使用的是Apollo;个人相比较更加喜欢Apollo一点,如果想了解Apollo的使用可参考:《SpringBoot集成Apollo配置中心(5分钟集成系列)》https://lupf.cn/articles/2019/11/19/1574169822114.html

  • 创建一个基础的SpringCloud项目,并添加一下配置

      <properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR5</spring-cloud.version>
    <spring-cloud-starter-alibaba-nacos-discovery.version>2.1.1.RELEASE
    </spring-cloud-starter-alibaba-nacos-discovery.version>
    <spring-cloud-starter-alibaba-nacos-config.version>2.1.1.RELEASE
    </spring-cloud-starter-alibaba-nacos-config.version>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter</artifactId>
    </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>
    </dependency>

    <!--Nacos配置中心-->
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${spring-cloud-starter-alibaba-nacos-config.version}</version>
    </dependency>

    <!--Nacos服务治理-->
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>${spring-cloud-starter-alibaba-nacos-discovery.version}</version>
    </dependency>

    <!-- 服务的API -->
    <dependency>
    <groupId>com.lupf</groupId>
    <artifactId>nacos-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    </dependency>
    </dependencies>

    基于Nacos的服务治理、配置中心

  • Nacos配置

    • dataId,用于匹配nacos中对应的配置文件 : 默认规则 ${spring.application.name}-${spring.profiles.active}.${file-extension} 如: nacos-provider-dev.yml ,如果没有环境区分就是nacos-provider.yml ;dataId允许根据自己的要求进行配置,具体如下

      # 规则: ${prefix}-${spring.profiles.active}-${spring.profiles.active}.${file-extension}
      # 如下的配置最终匹配的配置文件为:nacos-provider-dev.yml 如果没有匹配上会去匹配nacos-provider.yml
      spring:
      application:
      name: nacos-provider
      cloud:
      nacos:
      config:
      server-addr: 192.168.1.160:8848,192.168.1.160:8848 # nacos的地址
      file-extension: yml # 配置文件的格式
      prefix: ${spring.application.name} # 配置文件的前缀 不配置默认使用的是
      group: DEFAULT_GROUP
      profiles:
      active: dev
    • group: 用于对配置文件进行分组

    • Nacos配置文件的命名规则

    • 添加nacos-provider.yml

      server:
      port: 9112
      spring:
      application:
      name: nacos-provider
      cloud:
      nacos:
      discovery:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
      config:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
      key1: value1
      profix_key1: value3

      基于Nacos的服务治理、配置中心

    • 添加nacos-consumer.yml

      server:
      port: 9113
      spring:
      application:
      name: nacos-consumer
      cloud:
      nacos:
      discovery:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
      config:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848

      基于Nacos的服务治理、配置中心基于Nacos的服务治理、配置中心

    • 将启动文件application.yml修改为bootstrap.yml 并添加一下配置

      spring:
      application:
      name: nacos-provider
      cloud:
      nacos:
      config:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848 # nacos的地址
      file-extension: yml # 配置文件的格式
      prefix: ${spring.application.name} # 配置文件的前缀 不配置默认使用的是
      group: DEFAULT_GROUP
      profiles:
      active: dev
    • 启动项目

      // 出现以下日志说明配置文件加载成功
      2020-06-16 16:19:17.369 INFO [nacos-provider,,,] 13892 --- [ main] c.a.c.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-provider.yml', group: 'DEFAULT_GROUP', data: server:
      port: 9112
      spring:
      application:
      name: nacos-provider
      cloud:
      nacos:
      discovery:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
      config:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
      key1: value1
      profix_key1: value3
    • 添加配置文件获取的工具类 RemoteConfig // @RefreshScope 为自动刷新配置

      @Data
      @Component
      @RefreshScope
      public class RemoteConfig {

      @Value ("${key1}")
      private String key1;

      @Value ("${profix_key1}")
      private String profixKey1;
      }
    • 添加测试使用的NacosConfigController

      @RestController
      @RequestMapping ("echo")
      @Slf4j
      public class NacosConfigController {
      @Autowired
      RemoteConfig remoteConfig;

      @GetMapping ("conf")
      public String echo() {
      log.info("provider rest conf resp {}", remoteConfig.toString());
      return remoteConfig.toString();
      }
      }
    • 测试获取及自动刷新

      http://127.0.0.1:9112/echo/conf

      基于Nacos的服务治理、配置中心

      // 直接修改nacos上的配置 将value3修改为value1 并发布
      // 控制台会出现以下日志
      2020-06-16 16:29:11.216 INFO [nacos-provider,,,] 2880 --- [.168.1.208_8848] o.s.c.e.event.RefreshEventListener : Refresh keys changed: [profix_key1]

      // 再次刷新,发现值已经修改成功了

      基于Nacos的服务治理、配置中心

服务治理

RestFul API
  • provider就使用上面 echo/conf接口作为测试接口

    • 添加命名空间基于Nacos的服务治理、配置中心

    • 配置将服务发布到指定命名空间

      spring:
      cloud:
      nacos:
      discovery:
      namespace: local

      基于Nacos的服务治理、配置中心

    • provider和consumer添加配置文件

      spring:
      cloud:
      nacos:
      discovery:
      server-addr: 192.168.1.160:8848,192.168.1.161:8848,192.168.1.162:8848
    • provider和consumer启动类添加以下注解

      @EnableDiscoveryClient
    • consumer实例化RestTemplate

      @LoadBalanced
      @Bean
      public RestTemplate restTemplate() {
      return new RestTemplate();
      }
    • 测试RestFulController

      @RestController
      @RequestMapping ("rest")
      @Slf4j
      public class RestFulController {
      @Autowired
      RestTemplate restTemplate;

      @GetMapping ("conf")
      public String echo() {
      log.info("consumer rest conf req start....");
      return restTemplate.getForObject("http://nacos-provider/echo/conf", String.class);
      }
      }
    • 启动服务,nacos中可以看到如下的服务基于Nacos的服务治理、配置中心

    • 测试

      http://127.0.0.1:9113/rest/conf

      基于Nacos的服务治理、配置中心

    • 服务的命名空间 当不同的环境需要进行区分的时候,如开发环境、测试环境、正式环境;那么这些环境下的服务可能是有区别且不能穿插调用,因此我们就可以通过命名空间各个服务进行隔离;

整合feign的服务治理
  • nacos-api添加fiegn的请求及响应对象已经对应的service

    @Data
    @AllArgsConstructor
    public class ReqBean implements Serializable {
    private String name;

    private String msg;
    }

    @Data
    @AllArgsConstructor
    public class RespBean implements Serializable {
    private String code;

    private String msg;
    }

    @FeignClient (value = "nacos-provider", path = "/api", fallback = FeignService.DefaultFallback.class)
    public interface FeignService {

    @PostMapping ("/hello")
    RespBean hello(@RequestBody ReqBean reqBean);

    @PostMapping ("/hi")
    String hi(@RequestParam (value = "name") String name);

    class DefaultFallback implements FeignService {

    @Override
    public RespBean hello(ReqBean reqBean) {
    return new RespBean("-1", "ERR");
    }

    @Override
    public String hi(String name) {
    return "hello name";
    }
    }
    }
    • provider和consumer模块添加api模块

      <dependency>
      <groupId>com.lupf</groupId>
      <artifactId>nacos-api</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      </dependency>
    • provider和consumer添加以下注解,开启feign

      @EnableFeignClients (basePackages = "com.lupf.*")
    • provider实现FeignService

      @Service
      @Slf4j
      public class FeignServiceImpl implements FeignService {
      @Override
      public RespBean hello(ReqBean reqBean) {
      log.info("provider feign hello reqBean:{}", reqBean.toString());
      return new RespBean("0", "success");
      }

      @Override
      public String hi(String name) {
      log.info("provider feign hi req name:{}", name);
      return "hi:" + name;
      }
      }
    • provider添加对外暴露的controller;注意,路径、参数需要和FeignService配置的路径一致

      @RestController
      @RequestMapping ("api")
      public class FeignController {
      @Qualifier ("feignServiceImpl")
      @Autowired
      FeignService feignService;

      @PostMapping ("hello")
      public RespBean trans(@RequestBody ReqBean reqBean) {
      return feignService.hello(reqBean);
      }

      @PostMapping ("hi")
      public String hello(String name) {
      return feignService.hi(name);
      }
      }
    • consumer的调用FeignController

      @RestController
      @RequestMapping ("feign")
      @Slf4j
      public class FeignController {

      @Autowired (required = false)
      FeignService feignService;

      @GetMapping ("hello")
      public String hello() {
      log.info("consumer feign hello request start....");
      ReqBean reqBean = new ReqBean("张三", "hello");
      RespBean trans = feignService.hello(reqBean);
      log.info("consumer feign hello request return:{}", trans.toString());
      return trans.toString();
      }

      @GetMapping ("hi")
      public String hi() {
      log.info("consumer feign hi request start....");
      String zhang_san = feignService.hi("zhang san");
      log.info("consumer feign hi request return:{}", zhang_san);
      return zhang_san;
      }
      }
    • 测试

      http://127.0.0.1:9113/feign/hello
      http://127.0.0.1:9113/feign/hello

      基于Nacos的服务治理、配置中心

dubbo服务的治理
  • 添加dubbo的引用

    <spring-cloud-starter-dubbo.version>2.1.1.RELEASE</spring-cloud-starter-dubbo.version>

    <dependency>
    <!--<groupId>org.springframework.cloud</groupId>-->
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-dubbo</artifactId>
    <version>${spring-cloud-starter-dubbo.version}</version>
    </dependency>
  • nacos的nacos-provider.yml和nacos-consumer.yml添加一下配置

    dubbo:
    application:
    qos-enable: false
    consumer:
    check: false
    protocol:
    name: dubbo
    port: -1
    reference:
    check: false
    registry:
    address: spring-cloud://localhost
    check: false
    scan:
    base-packages: com.lupf

    dubbo.scan.base-packages 为你的包路径

  • provider添加Dubbo的具体实现

    // 注意,这里的Service为:org.apache.dubbo.config.annotation.Service 不是Spring的service
    @Service
    @Slf4j
    public class DubboServiceImpl implements DubboService {
    @Override
    public RespBean hello(ReqBean reqBean) {
    log.info("provider reqBean:{}", reqBean.toString());
    return new RespBean("999", "dubbo success");
    }
    }
  • consumer创建测试DubboController

    @RestController
    @RequestMapping ("dubbo")
    @Slf4j
    public class DubboController {
    @Reference
    DubboService dubboService;

    @GetMapping ("hello")
    public String hello() {
    log.info("consumer dubbo request start....");
    ReqBean reqBean = new ReqBean("张三", "hello");
    RespBean trans = dubboService.hello(reqBean);
    log.info("consumer dubbo request return:{}", trans.toString());
    return "success";
    }
    }

    基于Nacos的服务治理、配置中心

  • 测试

    http://127.0.0.1:9113/dubbo/hello

    基于Nacos的服务治理、配置中心

sleuth链路追踪

  • 引入sleuth依赖

    <spring-cloud-starter-sleuth.version>2.1.0.RELEASE</spring-cloud-starter-sleuth.version>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
    <version>${spring-cloud-starter-sleuth.version}</version>
    </dependency>
  • 请求测试基于Nacos的服务治理、配置中心基于Nacos的服务治理、配置中心

dubbo的链路追踪
  • 添加一个dubbo zipkin的依赖

    • 2.7.0之前的版本

      <brave-instrumentation-dubbo-rpc.version>5.10.0</brave-instrumentation-dubbo-rpc.version>

      <dependency>
      <groupId>io.zipkin.brave</groupId>
      <artifactId>brave-instrumentation-dubbo-rpc</artifactId>
      <version>${brave-instrumentation-dubbo-rpc.version}</version>
      </dependency>
    • 大于等于 2.7.0之前的版本

      <brave-instrumentation-dubbo.version>5.10.0</brave-instrumentation-dubbo.version>

      <dependency>
      <groupId>io.zipkin.brave</groupId>
      <artifactId>brave-instrumentation-dubbo</artifactId>
      <version>${brave-instrumentation-dubbo.version}</version>
      </dependency>

Nacos常见问题

导致log4j2不打印日志日志的问题
  • 错误描述

    WARN No Root logger was configured, creating default ERROR-level Root logger with Console appender
  • 解决方式,启动类添加配置

    public static void main(String[] args) {
    // 因为nacos的log4j2导致本项目的日志不输出的问题
    // 配置关闭nacos日志
    System.setProperty("nacos.logging.default.config.enabled", "false");
    SpringApplication.run(xxxx.class, args);
    }
Nacos频繁的心跳日志

服务频繁的心跳导致较多无效的日志输出

  • 提升nacos的日志级别,使其不输出

    logging.level.com.alibaba.nacos.client.naming=error