SpringCloud,Zuul

        SpringCloud微服務體系中,一種常見的負載均衡的方式是,客戶端的請求先通過負載均衡(Zuul+Ngnix),再達到服務網關(Zuul集羣),然後纔到具體的服務器。

        服務統一註冊到服務註冊中心集羣,服務的所有配置文件由配置服務管理。


一、Zuul介紹

        Zuul的主要功能是路由轉發和過濾器。路由是微服務的一部分,比如/api/user轉發到user服務,/api/shop轉發到shop服務。

        Zuul默認和Ribbon實現了負載均衡。

        Zuul有以下功能:

  • Authentication(身份驗證)
  • Insights
  • Stress Testing(壓力測試)
  • Canary Testing(最先測試)
  • Dynamic Routing(動態路由)
  • Service Migration(服務遷移)
  • Load Shedding(甩負荷)
  • Security(安全性)
  • Static Response handling(靜態響應處理)
  • Active/Active traffic management

       

二、創建zuul工程,服務路由

        1.創建SpringBoot工程,引入eureka、zuul、web依賴。

        2. 在啓動類開啓@EnableEurekaClient註解和@EnableZuulProxy註解

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {

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

        3. 修改配置

        配置註冊中心地址;設置zuul服務端口、服務名;配置網關,這裏將所有/api-ribbon/開頭的請求都轉發給service-ribbon服務,將所有/api-feign/開頭的請求都轉發給service-feign服務。

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8766
spring:
  application:
    name: service-zuul
zuul:
  routes:
    api-ribbon:
      path: /api-ribbon/**
      serviceId: service-ribbon
    api-feign:
      path: /api-feign/**
      serviceId: service-feign

        4. 訪問zuul服務

http://localhost:8766/api-ribbon/say?name=longtian


http://localhost:8766/api-feign/hello?name=longtian



三、服務過濾

        創建Zuul服務過濾器需要繼承抽象類com.netflix.zuul.ZuulFileter,該類實現了com.netflix.zuul.IZuulFilter,有兩個抽象方法:

public abstract String filterType();

public abstract int filterOrder();

以及IZuulFilter接口的兩個方法:

boolean shouldFilter();

Object run() throws ZuulException;

        1. filterType()返回一個字符串代表過濾器的類型。zuul定義了四種不同生命週期的過濾器:

            pre:路由之前

            routing:路由時

            post:路由之後

            error:發送錯誤時調用

        2. filterOrder(),過濾的順序

        3. shouldFileter(),這裏可以寫邏輯判斷,是否要過濾。true,永遠過濾。

        4. run(),過濾器的具體邏輯。可能很複雜,包括查sql、緩存等去判斷到底有沒有訪問權限。

@Component
public class MyFilter extends ZuulFilter {
    private static Logger log = LoggerFactory.getLogger(MyFilter.class);

    public String filterType(){
        return "pre";
    }

    public int filterOrder(){
        return 0;
    }

    public boolean shouldFilter(){
        return true;
    }

    public Object run(){
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String token = request.getParameter("token");

        if(StringUtils.isEmpty(token)) {
            log.error("accepted token is null");
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(401);
            try {
                context.getResponse().getWriter().write("token error");
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
        log.info("ok");
        return null;
    }
}

訪問 http://localhost:8766/api-ribbon/say?name=longtian


訪問 http://localhost:8766/api-ribbon/say?name=longtian&token=1







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