SpringCloud-2

Nacos的配置管理

屏幕截图 2022-07-12 092448

统一配置管理

  • 在Nacos的配置列表中新建配置

  • Data ID:服务名+环境+.后缀名 例 userserver-dev.yaml

  • Group:默认即可

  • 配置格式:目前支持 .yaml 和 .properties

  • 配置内容:填写一些可变化的配置

将配置交给Nacos管理的步骤

  • 在Nacos中添加配置文件

    屏幕截图 2022-07-12 104342

  • 再服务中引入nacos的config依赖

     <!--Nacos的配置中心依赖-->
          <dependency>
              <groupId>com.alibaba.cloud</groupId>
              <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
          </dependency>

     

  • 在微服务中添加bootstrap.yml 配置nacos地址,当前环境,服务名称,文件后缀名,决定了的启动时去nacos读取哪个文件。

#bootstrap.yml 读取的优先级更高 和 application.yml 结合使用
#Nacos的配置中心,和配置中的Data ID :命名一致
spring:
application: #服务名
  name: userservice
profiles: #开发环境
  active: dev
cloud:
  nacos:
    server-addr: localhost:8848 #服务地址
    config:
      file-extension: yaml #文件后缀

配置热更新

  • Nacos配置更改后,微服务可以实现热更新,方式

    1. 通过@Value注解注入,结合@RefreshScope

      @RefreshScope //Nacos部署热更新 ,配合@Value注解实现热部署
      public class UserController {}

      @Value("${pattern.dateformat}")
         //yyyy-MM-dd HH:mm:ss
         private String dateformat;
    2. 通过@ConfigurationProperties注入,自动刷新

      1.第一步:创建配置类
      package cn.itcast.user.config;

      import lombok.Data;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.stereotype.Component;

      @Data
      @Component
      @ConfigurationProperties(prefix = "pattern")
      public class PatternConfig {
         private String dateformat;
      }
      2.第二步:注入
         @Autowired
         private PatternConfig properties;
      3.第三步:调用
         properties.getDateformat()
    3. 注意:

      • 不是所有的配置都适合放到配置中心,维护麻烦

      • 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置。

多服务共享配置

  • 多种配置优先级:

    屏幕截图 2022-07-12 145012

  • 总结: 微服务会从Nacos读取配置文件

    1. [服务名]-[spring.profile.active].yaml 环境配置

    2. [服务名].yaml,默认配置,多环境共享

    3. 优先级:

      • 1 > 2 > 本地配置

Nacos集群 搭建步骤

  • 搭建Mysql集群并初始化数据库表

  • 下载解压Nacos

  • 修改集群配置(节点信息),数据库配置

  • 分别启动多个nacos节点

  • nginx反向代理

Feign

  • Feign

    1. Feign是一个声明式的http客户端,其作用就是帮助我们优雅的实现http请求的发送

  • RestTemplate方式调用存在的问题

    1. 代码可读性差,编程体验不统一

    2. 参数复杂URL难以维护

  • Feign的使用步骤

    1. 引入依赖

      <!--feign客户端依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>

       

    2. 添加@EnableFeignClients

      @EnableFeignClients
      @MapperScan("cn.itcast.order.mapper")
      @SpringBootApplication
      public class OrderApplication {}

       

    3. 编写FeignClient接口

      package cn.itcast.order.client;

      import cn.itcast.order.pojo.User;
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;

      @FeignClient("userservice")//指定这个服务名称
      public interface UserClient {
         @GetMapping("/user/{id}")
         User getById(@PathVariable("id") Long id);
      }

       

    4. 使用Feign定义的方法代替RestTemplate

      package cn.itcast.order.service;

      import cn.itcast.order.client.UserClient;
      import cn.itcast.order.mapper.OrderMapper;
      import cn.itcast.order.pojo.Order;
      import cn.itcast.order.pojo.User;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;

      @Service
      public class OrderService {

         @Autowired
         private OrderMapper orderMapper;

         @Autowired
         private UserClient userClient;
      //   private RestTemplate restTemplate;


         public Order queryOrderById(Long orderId) {
             // 1.查询订单
             Order order = orderMapper.findById(orderId);
      /*     定义请求url
             String url = "http://localhost:8081/user/"+order.getUserId();
             换成服务地址
             String url = "http://userservice/user/"+order.getUserId();
             发送Http请求,实现远程调用
             User user = restTemplate.getForObject(url,User.class);*/
             //获取orderId
             Long userId = order.getUserId();
             //调用feignClient
             User feignClientById = userClient.getById(userId);
             //将User封装到Order
             order.setUser(feignClientById);
             // 4.返回
             return order;
        }
      }
    5.