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

基于Nacos的服务治理、配置中心_第1张图片

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项目,并添加一下配置
    
        1.8
        Greenwich.SR5
        2.1.1.RELEASE
        
        2.1.1.RELEASE
        
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            ${spring-cloud-starter-alibaba-nacos-config.version}
        

        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            ${spring-cloud-starter-alibaba-nacos-discovery.version}
        

        
        
            com.lupf
            nacos-api
            0.0.1-SNAPSHOT
        
    

基于Nacos的服务治理、配置中心_第2张图片

  • 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-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的服务治理、配置中心_第3张图片

    • 添加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的服务治理、配置中心_第4张图片
      基于Nacos的服务治理、配置中心_第5张图片

    • 将启动文件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的服务治理、配置中心_第6张图片

      // 直接修改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的服务治理、配置中心_第7张图片

服务治理

RestFul API
  • provider就使用上面 echo/conf接口作为测试接口
    • 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中可以看到如下的服务
      file

    • 测试

      http://127.0.0.1:9113/rest/conf
      

      基于Nacos的服务治理、配置中心_第8张图片

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

      • 添加命名空间
        基于Nacos的服务治理、配置中心_第9张图片
      • 配置将服务发布到指定命名空间
        spring:
            cloud:
                nacos:
                    discovery:
                        namespace: local
        
        基于Nacos的服务治理、配置中心_第10张图片
整合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模块
    
        com.lupf
        nacos-api
        0.0.1-SNAPSHOT
    
    
  • 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的服务治理、配置中心_第11张图片

dubbo服务的治理
  • 添加dubbo的引用
    2.1.1.RELEASE
    
    
        
        com.alibaba.cloud
        spring-cloud-starter-dubbo
        ${spring-cloud-starter-dubbo.version}
    
    
  • 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的服务治理、配置中心_第12张图片
  • 测试
    http://127.0.0.1:9113/dubbo/hello
    
    基于Nacos的服务治理、配置中心_第13张图片

sleuth链路追踪

  • 引入sleuth依赖
    2.1.0.RELEASE
    
        org.springframework.cloud
        spring-cloud-starter-sleuth
        ${spring-cloud-starter-sleuth.version}
    
    
  • 请求测试
    基于Nacos的服务治理、配置中心_第14张图片
    file
dubbo的链路追踪
  • 添加一个dubbo zipkin的依赖
    • 2.7.0之前的版本
      5.10.0
      
      
          io.zipkin.brave
          brave-instrumentation-dubbo-rpc
          ${brave-instrumentation-dubbo-rpc.version}
      
      
    • 大于等于 2.7.0之前的版本
      5.10.0
      
      
          io.zipkin.brave
          brave-instrumentation-dubbo
          ${brave-instrumentation-dubbo.version}
      
      
      file

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
    

    在这里插入图片描述

你可能感兴趣的:(后端,nacos,配置中心,服务治理)