SpringCloud配置中心+Feign+Gateway網關


1. 配置中心

1.1 配置中心的設置

SpringCloud配置中心也可以使用nacos來完成


nacos配置中心的配置通過 [服務名]-[類型].[后綴名] 來定位到需要讀取這個配置文件的服務

1.2 配置中心的讀取

  1. 給需要使用配置中心的服務 添加依賴
<!--nacos配置管理依賴-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 給需要使用配置中心的服務 添加 bootstrap.yml 配置文件並輸入配置
# 通過 [服務名稱]-[開發環境].[文件類型] 可以定位到 Nacos 的配置中心的具體配置
spring:
  application:
    name: userservice # 服務名稱
  profiles:
    active: dev #開發環境,這里是dev 
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后綴名
  1. 部署熱更新
    每次修改配置中心的文件,服務不需要再重啟就能讀取到最新配置
    方法1. 想要熱更新的Field所在class上添加 @RefreshScope 注解,這樣配置中心的xx.yyy屬性更新后,str的屬性也會更新
@Component
@RefreshScope
class Test{

    @Value("xx.yyy")
    private String str;    
}

方法2. 使用 @ConfigurationProperties 注解獲取配置中心的配置,然后添加到IOC容器中。這樣配置中心的xx.yyy屬性更新后,yyy的屬性也會更新

@Component
@ConfigurationProperties(prefix = "xx")
class Test{
    private String yyy;
}

@Component
class Org{
    
    @Autowired
    private Test test;
}

1.3 配置中心的共享

直接使用 [服務名稱].[文件類型] 為Data ID來創建配置

這樣該服務的所有類型的開發環境下都能讀取到該配置
配置的優先級:[服務名稱]-[開發環境].[文件類型] > [服務名稱].[文件類型] > 本地配置文件(applicaiton.yml)

2. Feign遠程調用

Feign提供了一種優雅的方式調用遠程接口,不需要再使用 RestTemplate 了

2.1 使用步驟

  1. 給需要使用遠程調用功能的服務 添加依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!--servlet API-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
  1. 給需要使用遠程調用功能的服務的啟動類添加 @EnableFeignClients 注解
  2. 編寫Feign客戶端(接口)
@FeignClient("userservice") //服務名
public interface UserFeign {

    // 請求方式、請求路徑、方法參數、返回值要和 被請求的服務 的接口相同
    @GetMapping("/user/{id}")   
    User findByID(@PathVariable("id")Long id);
}
  1. 使用
@Component
class Test{

    @Autowired
    private UserFeign userFeign;

    public void test(){
        User user = userFeign.findByID(1L);
    }
}

2.2 自定義配置

  1. 主要屬性
  2. 配置文件方式
    基於配置文件修改feign的日志級別可以針對單個服務:
feign:  
  client:
    config: 
      userservice: # 針對某個微服務的配置
        loggerLevel: FULL #  日志級別 

也可以針對所有服務:

feign:  
  client:
    config: 
      default: # 這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置
        loggerLevel: FULL #  日志級別 
  1. 代碼方式
public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志級別為BASIC
    }

    //設置feign發送請求的攔截器,解決feign遠程調用請求頭丟失的問題
    @Bean
    public RequestInterceptor requestInterceptor(){
        //設置以后,Feign在遠程調用之前,會先執行apply方法
        return requestTemplate -> {
            //1.使用RequestContextHolder獲取在Controller層進入的請求的所有屬性,底層是使用ThreadLocal的機制
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if(attributes == null)
                return;
            HttpServletRequest request = attributes.getRequest();
            //2.同步請求頭數據  (Cookie)
            String cookie = request.getHeader("Cookie");
            requestTemplate.header("Cookie",cookie);
        };
    }
}

2.3 Feign的性能優化

使用連接池代替默認的URLConnection

  1. 引入依賴
<!--httpClient的依賴 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>
  1. 添加配置
feign:
  httpclient:
    enabled: true # 開啟feign對HttpClient的支持
    max-connections: 200 # 最大的連接數
    max-connections-per-route: 50 # 每個路徑的最大連接數

2.4 最佳實踐

把Feign抽取成模塊,然后需要用到的服務再引入即可

  1. 創建模塊 feign
  2. 引入依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 抽取公共類(pojo類,Feign類,FeignConfig類等等)
  2. 給需要用到的服務 引入依賴
<dependency>
     <groupId>com.cc</groupId>
     <artifactId>feign</artifactId>
     <version>1.0</version>
</dependency>
  1. 解決包掃描問題(服務的啟動類上)

3. Gateway網關

3.1 Gateway入門

  1. 創建 Gateway 模塊並引入依賴
<!--網關-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服務發現依賴-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 編寫配置信息(application.yml)
server:
  port: 10010 # 網關端口
spring:
  application:
    name: gateway # 服務名稱
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 網關路由配置
        - id: user-service # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
          uri: lb://userservice # 路由的目標地址 lb就是負載均衡,后面跟服務名稱
          predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
            - Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求
  1. 運行流程
  2. 斷言工廠(predicates屬性)
  3. 過濾器工廠

    5.1 過濾器種類

    5.1.1 例子:請求頭過濾器
    給所有進入userservice的請求添加一個請求頭:Truth=itcast is freaking awesome! 修改application.yml文件就好
spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 過濾器
        - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加請求頭

5.2 默認過濾器

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默認過濾項
      - AddRequestHeader=Truth, Itcast is freaking awesome! 

5.3 全局過濾器,用來添加自己的邏輯
實現 GlobalFilter 接口

@Order(-1)  // order指定的越小,同等級Filter就先執行
@Component
public class AuthFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        // 如果滿足條件就放行(執行下一個過濾器)
        if(request.getQueryParams().get("auth") != null){
            return chain.filter(exchange);
        }

        // 如果不滿足條件就重定向到 "https://www.baidu.com/"
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.SEE_OTHER);
        response.getHeaders().set("Location", "https://www.baidu.com/");
        return exchange.getResponse().setComplete();
    }
}
  1. 跨域問題
    在application.yml中添加如下配置
spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域處理
        add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允許哪些網站的跨域請求 
              - "http://localhost:8090"
            allowedMethods: # 允許的跨域ajax的請求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允許在請求中攜帶的頭信息
            allowCredentials: true # 是否允許攜帶cookie
            maxAge: 360000 # 這次跨域檢測的有效期
  1. 如果GateWay無法使用Feign
    將以下類加入IOC容器
@Configuration
public class GateWayConfig {
    @Bean
    @ConditionalOnMissingBean
    public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
        return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM