SpringCloud——服務網關

1、背景

上篇博客《SpringCloud——Eureka服務註冊和發現》中介紹了註冊中心Eureka、服務提供者和服務消費者。這篇博客我們將介紹服務網關。

圖(1) 未使用服務網關的做法
這裏寫圖片描述

圖(2) 服務網關的做法
這裏寫圖片描述

服務網關,英文Service GateWay,他是微服務框架中唯一的入口。有些類似外觀模式,對外只提供一個訪問的入口。這樣做的好處有很多,減少了客戶端多次調用微服務,也可以在“入口”處進行負載或權限的處理。

在SpringCloud Netflix中,Zuul就是這樣一個角色。

2、實例

1)、Zuul環境搭建

引入jar包

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

在Application中開啓Zuul

@EnableZuulProxy
@SpringCloudApplication  //整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker,主要目的還是簡化配置
public class ZuulApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
    }
    }

Zuul環境搭建完畢之後,我們就可以來看他的主要功能了,包括服務路由和服務過濾。

2)、路由配置

方法一:url配置
在application.properties中,進行如下配置。

zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/

之後,我們就可以通過”/api-a-url”來代替”http://localhost:2222/“進行訪問,類似修改本地hosts文件來設置域名。這種方式屏蔽了ip和端口。

缺點: url路由粒度過粗。需要知道所有服務地址才能完成映射。

方法二:服務映射(serviceId)
既然eureka中已經有我們的配置信息,那我們可以藉助他來完成地址映射。

zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=compute-service
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

3)、服務過濾

定義過濾

public class AccessFilter extends ZuulFilter {

    /*filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命週期的過濾器類型,具體如下:
    pre:可以在請求被路由之前調用
    routing:在路由請求時候被調用
    post:在routing和error過濾器之後被調用
    error:處理請求時發生錯誤時被調用
    filterOrder:通過int值來定義過濾器的執行順序
    shouldFilter:返回一個boolean類型來判斷該過濾器是否要執行,所以通過此函數可實現過濾器的開關。在上例中,我們直接返回true,所以該過濾器總是生效。
    run:過濾器的具體邏輯。需要注意,這裏我們通過ctx.setSendZuulResponse(false)令zuul過濾該請求,不對其進行路由,然後通過ctx.setResponseStatusCode(401)設置了其返回的錯誤碼,當然我們也可以進一步優化我們的返回,比如,通過ctx.setResponseBody(body)對返回body內容進行編輯等。
    */
    @Override
    public Object run() {
         RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            Object accessToken = request.getParameter("accessToken");  //定義規則:訪問url中必須帶有accessToken參數
            if(accessToken == null) {
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(401);
                return null;
            }
            return null;

    }
    ……
}

實例化

    //實例化過濾器
    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }

啓動項目,如果訪問的url中不含有accessToken參數則會報錯,只有包含該參數的請求url纔會被放行。

3、小結

Zuul的主要功能:負載均衡、服務路由、服務過濾等,並不是新鮮的東西。api gateway類似外觀模式,提供統一的入口。負載均衡和路由和Nginx的功能很像,過濾和權限管理類似shiro的權限配置。

萬變不離其宗,目的都是在於把這些與服務本身關係不大的東西剝離出來,而且是越早剝離越好,能在Controller處理的絕不放在Service,能在轉發前處理的就不要留到轉發後。類似大家說的服務的無狀態性,over!

回家倒計時四個小時………………

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章