2018-07-07

Zuul--学习笔记(5)



目录

一、参考Spring Cloud官方文档
--1、路由器和过滤器:Zuul
--2、如何加入Zuul
--3、嵌入式Zuul反向代理
--4、@EnableZuulProxy与@EnableZuulServer
二、实操
--1、注册中心、网关路由器、用户服务提供者、订单服务提供者
--2、zuul-demo的配置
--3、user-server配置
--4、order-server配置
--5、运行结果
----5.1、由euraka发现服务
----5.2、配置zuul的path
三、zuul过滤器
--1、Spring Cloud官方文档
----1.1、如何编写预过滤器
--2、实操
----2.1、在zuul-demo上修改
----2.2、运行结果



一、参考Spring Cloud官方文档

1、路由器和过滤器:Zuul

Zuul的简介.PNG

路由在微服务体系结构的一个组成部分。例如,/可以映射到您的Web应用程序,/api/users映射到用户服务,并将/api/shop映射到商店服务。Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。

Netflix使用Zuul进行以下操作:

  • 认证

  • 洞察

  • 压力测试

  • 金丝雀测试

  • 动态路由

  • 服务迁移

  • 负载脱落

  • 安全

  • 静态响应处理

  • 主动/主动流量管理

Zuul的规则引擎允许基本上写任何JVM语言编写规则和过滤器,内置Java和Groovy。

2、如何加入Zuul

要在您的项目中包含Zuul,请使用组org.springframework.cloud和artifact id spring-cloud-starter-zuul的启动器。

3、嵌入式Zuul反向代理

Spring Cloud已经创建了一个嵌入式Zuul代理,以简化UI应用程序想要代理对一个或多个后端服务的呼叫的非常常见的用例的开发。此功能对于用户界面对其所需的后端服务进行代理是有用的,避免了对所有后端独立管理CORS和验证问题的需求。

要启用它,使用@EnableZuulProxy注释Spring Boot主类,并将本地调用转发到相应的服务。按照惯例,具有ID“用户”的服务将接收来自位于/users(具有前缀stripped)的代理的请求。代理使用Ribbon来定位一个通过发现转发的实例,并且所有请求都以 hystrix命令执行,所以故障将显示在Hystrix指标中,一旦电路打开,代理将不会尝试联系服务。

要跳过自动添加的服务,请将zuul.ignored-services设置为服务标识模式列表。如果一个服务匹配一个被忽略的模式,而且包含在明确配置的路由映射中,那么它将被无符号。例:

application.yml

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

在此示例中,除 “用户” 之外,所有服务都被忽略。

要获得对路由的更细粒度的控制,您可以独立地指定路径和serviceId:

application.yml

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

另一种方式是配合Ribbon来实现多个实例的路由访问

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根据使用何种注释来启用Zuul安装多个过滤器。@EnableZuulProxy是@EnableZuulServer的超集。换句话说,@EnableZuulProxy包含@EnableZuulServer安装的所有过滤器。“代理”中的其他过滤器启用路由功能。如果你想要一个“空白”Zuul,你应该使用@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 {
}

二、实操

1、注册中心、网关路由器、用户服务提供者、订单服务提供者

  • 注册中心euraka-demo-server(参考Eureka--学习笔记(1))
  • 网关路由器zuul-demo
  • 用户服务提供者user-server
  • 订单服务提供者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>

启动类

@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

调用类

@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

调用类

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

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

5、运行结果

5.1、由euraka发现服务

UI监控界面

监控.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过滤器

1、Spring Cloud官方文档

1.1、如何编写预过滤器

前置过滤器用于设置RequestContext中的数据,用于下游的过滤器。主要用例是设置路由过滤器所需的信息。

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;
    }
}

上面的过滤器从foo请求参数填充SERVICE_ID_KEY。实际上,做这种直接映射并不是一个好主意,而是从foo的值来查看服务ID。

2、实操

2.1、在zuul-demo上修改

前置过滤器

@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、运行结果

在浏览器输入http://localhost:8090/orders/order/count?sign=1234

result5.PNG

在浏览器输入http://localhost:8090/orders/order/count?sign=abcd

result6.PNG

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335