java版springcloud B2B2C o2o多用戶商城 springcloud架構-SpringCloud Zuul基於Consul配置及詳解

一.構建工程

1.引入依賴

<!--SpringBoot2.0以上版本需引入該依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

2.創建主類

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
@RestController
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

3.配置application.properties

zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.service-id=api-a

zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.service-id=api-b

這裏存在 api-a 和 api-b 兩個微服務應用, 當請求http://localhost:port/api-a/helloWorld, 會被路由轉發至 api-a 服務的 /helloWorld 接口, 當請求http://localhost:port/api-b/helloWorld, 會被路由轉發至 api-b 服務的 /helloWorld 接口. 當請求 URL 符合配置規則時, 就會被轉發至 service-id 對應的微服務應用接口.
瞭解springcloud架構可以加求求:三五三六二四七二五九
 4.配置請求過濾
SpringCloud Zuul 還有另一個和核心功能: 請求過濾. Zuul 允許開發者在 API 網關上通過定義過濾器來實現對請求的攔截與過濾, 實現方法非常簡單, 只需繼承 ZuulFilter 抽象類並實現它定義的4個抽象函數就可以完成對請求的攔截和過濾.

public class MyGatewayFilter extends ZuulFilter {

  /*4種過濾器類型, 
  pre:可以在請求被路由之前調用, 
  route:在路由請求時候被調用, 
  post:在route和error過濾器之後被調用, 
  error:處理請求時發生錯誤時被調用*/ 
  @Override 
  public String filterType() { 
    return "pre";
  }
    @Override
    public int filterOrder() {
        return 0;  //優先級爲0,數字越大,優先級越低
    }

    @Override
    public boolean shouldFilter() {
        return true;  // 是否執行該過濾器,此處爲true,說明需要過濾
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));

        Object accessToken = request.getParameter("token");  //獲取token參數
        if (accessToken == null) {
            log.warn("token is empty");
            ctx.setSendZuulResponse(false);  //過濾該請求, 不對其進行路由
            ctx.setResponseStatusCode(401);  //返回錯誤碼
            ctx.setResponseBody("token is null!");  //返回錯誤內容
            return null;   //Zuul還未對返回數據做處理
        }
    return null;
    }
}

創建過濾器後,它並不會直接生效, 我們還需爲其創建具體的 Bean 才能啓動該過濾器.

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
@RestController
public class LixjApplication {

    public static void main(String[] args) {
        SpringApplication.run(LixjApplication.class, args);
    }

    @Bean
    public MyGatewayFilter myGatewayFilter(){
        return new MyGatewayFilter();
    }
}

二. 路由詳解

1.路徑匹配規則

/api-a/?    可以匹配 /api-a/ 之後拼接一個任務字符的路徑 , 比如 /api-a/a , /api-a/b , /api-a/c

/api-a/*    可以匹配 /api-a/ 之後拼接任意字符的路徑, 比如 /api-a/a, /api-a/aaa, /api-a/bbb . 但它無法匹配 /api-a/a/b 這種多級目錄路徑

/api-a/**   可以匹配 /api-a/* 包含的內容之外, 還可以匹配形如 /api-a/a/b 的多級目錄路徑

2.路由匹配順序

隨着版本的迭代, 我們需要對一個服務做一些功能拆分, 將原屬於 api-a 服務的某些功能拆分到另一個全新的服務 api-a-part 中, 而這些拆分的外部調用 URL 路徑希望能夠符合規則 /api-a/part/** .

 zuul.routes.api-a.path=/api-a/**
    zuul.routes.api-a.service-id=api-a

    zuul.routes.api-a-part.path=/api-a/part/**
    zuul.routes.api-a-part.service-id=api-a-part

在源碼中, 路由規則是通過 LinkedHashMap 保存的, 也就是說, 路由規則的保存時有序的, 而內容的加載是通過遍歷配置文件中路由規則依次加入的, 所以導致問題的根本原因是對配置文件中內容的讀取, 但上述properties配置無法保證路由規則加載順序, 我們需要使用 YML 文件來配置, 以實現有序的路由規則.

zuul:
    routes:
        api-a-part:
            path=/api-a/part/**
            service-id=api-a-part 
        api-a:
            path=/api-a/**
            service-id=api-a

3.本地跳轉

zuul.routes.api-c.path=/api-c/**
zuul.routes.api-c.url=forward:/api-c

發佈了101 篇原創文章 · 獲贊 118 · 訪問量 7518
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章