2018-07-07

Zuul--學(xué)習(xí)筆記(5)



目錄

一、參考Spring Cloud官方文檔
--1、路由器和過(guò)濾器:Zuul
--2、如何加入Zuul
--3、嵌入式Zuul反向代理
--4、@EnableZuulProxy與@EnableZuulServer
二、實(shí)操
--1、注冊(cè)中心、網(wǎng)關(guān)路由器、用戶服務(wù)提供者、訂單服務(wù)提供者
--2、zuul-demo的配置
--3、user-server配置
--4、order-server配置
--5、運(yùn)行結(jié)果
----5.1、由euraka發(fā)現(xiàn)服務(wù)
----5.2、配置zuul的path
三、zuul過(guò)濾器
--1、Spring Cloud官方文檔
----1.1、如何編寫預(yù)過(guò)濾器
--2、實(shí)操
----2.1、在zuul-demo上修改
----2.2、運(yùn)行結(jié)果



一、參考Spring Cloud官方文檔

1、路由器和過(guò)濾器:Zuul

Zuul的簡(jiǎn)介.PNG

路由在微服務(wù)體系結(jié)構(gòu)的一個(gè)組成部分。例如,/可以映射到您的Web應(yīng)用程序,/api/users映射到用戶服務(wù),并將/api/shop映射到商店服務(wù)。Zuul是Netflix的基于JVM的路由器和服務(wù)器端負(fù)載均衡器。

Netflix使用Zuul進(jìn)行以下操作:

  • 認(rèn)證

  • 洞察

  • 壓力測(cè)試

  • 金絲雀測(cè)試

  • 動(dòng)態(tài)路由

  • 服務(wù)遷移

  • 負(fù)載脫落

  • 安全

  • 靜態(tài)響應(yīng)處理

  • 主動(dòng)/主動(dòng)流量管理

Zuul的規(guī)則引擎允許基本上寫任何JVM語(yǔ)言編寫規(guī)則和過(guò)濾器,內(nèi)置Java和Groovy。

2、如何加入Zuul

要在您的項(xiàng)目中包含Zuul,請(qǐng)使用組org.springframework.cloud和artifact id spring-cloud-starter-zuul的啟動(dòng)器。

3、嵌入式Zuul反向代理

Spring Cloud已經(jīng)創(chuàng)建了一個(gè)嵌入式Zuul代理,以簡(jiǎn)化UI應(yīng)用程序想要代理對(duì)一個(gè)或多個(gè)后端服務(wù)的呼叫的非常常見(jiàn)的用例的開(kāi)發(fā)。此功能對(duì)于用戶界面對(duì)其所需的后端服務(wù)進(jìn)行代理是有用的,避免了對(duì)所有后端獨(dú)立管理CORS和驗(yàn)證問(wèn)題的需求。

要啟用它,使用@EnableZuulProxy注釋Spring Boot主類,并將本地調(diào)用轉(zhuǎn)發(fā)到相應(yīng)的服務(wù)。按照慣例,具有ID“用戶”的服務(wù)將接收來(lái)自位于/users(具有前綴stripped)的代理的請(qǐng)求。代理使用Ribbon來(lái)定位一個(gè)通過(guò)發(fā)現(xiàn)轉(zhuǎn)發(fā)的實(shí)例,并且所有請(qǐng)求都以 hystrix命令執(zhí)行,所以故障將顯示在Hystrix指標(biāo)中,一旦電路打開(kāi),代理將不會(huì)嘗試聯(lián)系服務(wù)。

要跳過(guò)自動(dòng)添加的服務(wù),請(qǐng)將zuul.ignored-services設(shè)置為服務(wù)標(biāo)識(shí)模式列表。如果一個(gè)服務(wù)匹配一個(gè)被忽略的模式,而且包含在明確配置的路由映射中,那么它將被無(wú)符號(hào)。例:

application.yml

 zuul:
  ignoredServices: '*'
  routes:
    users: /myusers/**

在此示例中,除 “用戶” 之外,所有服務(wù)都被忽略。

要獲得對(duì)路由的更細(xì)粒度的控制,您可以獨(dú)立地指定路徑和serviceId:

application.yml

zuul:
  routes:
    users:
      path: /myusers/**
      serviceId: users_service

另一種方式是配合Ribbon來(lái)實(shí)現(xiàn)多個(gè)實(shí)例的路由訪問(wèn)

application.yml

zuul:
  routes:
    users:
      path: /myusers/**
      serviceId: users

ribbon:
  eureka:
    enabled: false

users:
  ribbon:
    listOfServers: example.com,google.com

4、@EnableZuulProxy與@EnableZuulServer

Spring Cloud Netflix根據(jù)使用何種注釋來(lái)啟用Zuul安裝多個(gè)過(guò)濾器。@EnableZuulProxy是@EnableZuulServer的超集。換句話說(shuō),@EnableZuulProxy包含@EnableZuulServer安裝的所有過(guò)濾器。“代理”中的其他過(guò)濾器啟用路由功能。如果你想要一個(gè)“空白”Zuul,你應(yīng)該使用@EnableZuulServer。

@EnableZuulProxy

/**
 * Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
 * forward requests to backend servers. The backends can be registered manually through
 * configuration or via DiscoveryClient.
 *
 * @see EnableZuulServer for how to get a Zuul server without any proxying
 *
 * @author Spencer Gibb
 * @author Dave Syer
 * @author Biju Kunjummen
 */
@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {
}

@EnableZuulServer

/**
 * Set up the application to act as a generic Zuul server without any built-in reverse
 * proxy features. The routes into the Zuul server can be configured through
 * {@link ZuulProperties} (by default there are none).
 *
 * @see EnableZuulProxy to see how to get reverse proxy out of the box
 *
 * @author Spencer Gibb
 * @author Biju Kunjummen
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ZuulServerMarkerConfiguration.class)
public @interface EnableZuulServer {
}

二、實(shí)操

1、注冊(cè)中心、網(wǎng)關(guān)路由器、用戶服務(wù)提供者、訂單服務(wù)提供者

  • 注冊(cè)中心euraka-demo-server(參考Eureka--學(xué)習(xí)筆記(1))
  • 網(wǎng)關(guān)路由器zuul-demo
  • 用戶服務(wù)提供者user-server
  • 訂單服務(wù)提供者order-server

2、zuul-demo的配置

pom.xml

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

啟動(dòng)類

@SpringBootApplication
@EnableZuulProxy
public class ZuulDemoApplication {

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

application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

server:
  port: 8090

spring:
  application:
    name: api-gateway

3、user-server配置

pom.xml

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8091
spring:
  application:
    name: user-server

調(diào)用類

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/getmsg/{id}")
    public String getmsg(@PathVariable Integer id){
        return  id + " baby are too young too simple";
    }

}

4、order-server配置

pom.xml

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8092
spring:
  application:
    name: order-server

調(diào)用類

@RequestMapping("/order")
@RestController
public class OrderController {

    @GetMapping("/count")
    public String count(){
        return "5";
    }
}

5、運(yùn)行結(jié)果

5.1、由euraka發(fā)現(xiàn)服務(wù)

UI監(jiān)控界面

監(jiān)控.PNG

瀏覽器中輸入 http://localhosh:8090/order-server/order/count

result1.PNG

瀏覽器中輸入 http://localhosh:8090/user-server/user/getmsg/2

result2.PNG

5.2、配置zuul的path

zuul-demo中的application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka

server:
  port: 8090

spring:
  application:
    name: api-gateway

zuul:
  routes:
    users:
      path: /users/**
      serviceId: user-server
    orders:
      path: /orders/**
      serviceId: order-server

在瀏覽器中輸入http://localhost:8090/orders/order/count

result3.PNG

在瀏覽器中輸入http://localhost:8090/users/user/getmsg/1

result4.PNG

三、zuul過(guò)濾器

1、Spring Cloud官方文檔

1.1、如何編寫預(yù)過(guò)濾器

前置過(guò)濾器用于設(shè)置RequestContext中的數(shù)據(jù),用于下游的過(guò)濾器。主要用例是設(shè)置路由過(guò)濾器所需的信息。

public class QueryParamPreFilter extends ZuulFilter {
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1; // run before PreDecoration
    }

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded
                && !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined serviceId
    }
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request.getParameter("foo") != null) {
            // put the serviceId in `RequestContext`
            ctx.put(SERVICE_ID_KEY, request.getParameter("foo"));
        }
        return null;
    }
}

上面的過(guò)濾器從foo請(qǐng)求參數(shù)填充SERVICE_ID_KEY。實(shí)際上,做這種直接映射并不是一個(gè)好主意,而是從foo的值來(lái)查看服務(wù)ID。

2、實(shí)操

2.1、在zuul-demo上修改

前置過(guò)濾器

@Component
public class ZuulPrefilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest  req = ctx.getRequest();
        String sign = req.getParameter("sign");
        if(null == sign || "".equals(sign)){
            return false;
        }else if("abcd".equals(sign)){
            return false;
        }
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(403);
        return null;
    }
}

2.2、運(yùn)行結(jié)果

在瀏覽器輸入http://localhost:8090/orders/order/count?sign=1234

result5.PNG

在瀏覽器輸入http://localhost:8090/orders/order/count?sign=abcd

result6.PNG

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。