前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud详细教程 | 第五篇:路由器和过滤器Zuul(Greenwich版本)

SpringCloud详细教程 | 第五篇:路由器和过滤器Zuul(Greenwich版本)

作者头像
小东啊
发布2019-06-26 15:23:46
7640
发布2019-06-26 15:23:46
举报
文章被收录于专栏:李浩东的博客李浩东的博客

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

一. 简介

1. Zuul 是什么?

Zuul是Netflix开源的微服务网关,他可以和Eureka,Ribbon,Hystrix等组件配合使用

Nginx大家都知道是反向代理服务器,可以做到负载均衡,过滤等功能,其实网关Zuul和它是一样的,比如你的eureka-client服务部署在很多服务器上,前端需要联调,难道都要记住这么多IP和接口,不可能记住的,这个时候就需要网关进行暴露统一接口进行转发请求不同的服务器上,一方面是安全另一方面负载均衡

2.Zuul能做什么?
  • 认证
  • 洞察
  • 压力测试
  • 金丝雀测试
  • 动态路由
  • 服务迁移
  • 负载脱落
  • 安全
  • 静态响应处理
  • 主动/主动流量管理

Zuul的规则引擎允许通过任何JVM语言来编写规则和过滤器, 支持基于Java和Groovy的构建。 配置属性 zuul.max.host.connections 已经被两个新的配置属性替代, zuul.host.maxTotalConnections (总连接数)和 zuul.host.maxPerRouteConnections,(每个路由连接数) 默认值分别是200和20.

二. 使用Zuul作为路由转发

1.创建zuul服务加入依赖

代码语言:javascript
复制
        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>        </dependency>

2.改造pom.xml文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <parent>        <groupId>com.li</groupId>        <artifactId>SpringCloudLearn</artifactId>        <version>1.0-SNAPSHOT</version>        <relativePath>../</relativePath>    </parent>    <artifactId>zuul-server</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>zuul-server</name>    <description>Demo project for Spring Boot</description>
    <properties>        <java.version>1.8</java.version>        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>    </properties>
    <dependencies>        <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>    </dependencies>
    <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.springframework.cloud</groupId>                <artifactId>spring-cloud-dependencies</artifactId>                <version>${spring-cloud.version}</version>                <type>pom</type>                <scope>import</scope>            </dependency>        </dependencies>    </dependencyManagement>
    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build>
</project>

在程序的启动类加上@EnableEurekaClient向注册中心注册和@EnableZuulProxy开启zuul的功能

代码语言:javascript
复制
package com.li.zuulserver;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy@EnableEurekaClient@SpringBootApplicationpublic class ZuulServerApplication {
    public static void main(String[] args) {        SpringApplication.run(ZuulServerApplication.class, args);    }
}

配置application.properties文件

代码语言:javascript
复制
# 端口号server.port=8767# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=zuul-server#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/# 创建两个路由转发# ribbon转ribbon-server服务zuul.routes.ribbon.service-id=ribbon-serverzuul.routes.ribbon.path=/ribbon/**
# feign转feign-server服务zuul.routes.feign.service-id=feign-serverzuul.routes.feign.path=/feign/**

这个意味着 HTTP 调用"/ribbon"被转发到"ribbon-server"服务. 路由必须配置一个可以被指定为ant风格表达式的"path", 所以“/ribbon/*”只能匹配一个层级,依次类推

依次启动eureka-server,eureka-client,feign-server,ribbon-server,zuul-server5个工程进行测试

打开浏览器 访问 http://localhost:8761/ 发现已经注册成功

接着访问: http://localhost:8767/ribbon/hello?name=lhd

访问: http://localhost:8767/feign/hello?name=lhd

说明zuul做到了路由转发的功能

三. zuul服务过滤

zuul还有过滤的功能, 比如安全认证,我们请求接口需要携带tokrn,我们就可以使用zuul进行过滤,不需要到达原接口就可以进行拦截

如何编写预过滤器?

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

实现过滤器 只需要继承ZuulFilter即可

代码语言:javascript
复制
package com.li.zuulserver.filter;
import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import com.netflix.zuul.exception.ZuulException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.HttpStatus;import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;import java.io.IOException;
/** * @Classname MyFilter * @Description TODO * @Author 李号东 lihaodongmail@163.com * @Date 2019-03-31 08:20 * @Version 1.0 */
@Component // 注入beanpublic class RoutingFilter extends ZuulFilter {
    private static Logger log = LoggerFactory.getLogger(RoutingFilter.class);

    /**     * 过滤器的类型     * pre:可以在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。     * roting:在路由请求时候被调用。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。     * post:在routing和error过滤器之后被调用。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。     * error:处理请求时发生错误时被调用     *     * @return     */    @Override    public String filterType() {        return "pre";    }
    /**     * 过滤的顺序 越小越先很执行     *     * @return     */    @Override    public int filterOrder() {        return 0;    }
    /**     * 是否过滤 true 过滤 false 不执行过滤器     *     * @return     */    @Override    public boolean shouldFilter() {        return true;    }
    /**     * 过滤器的具体逻辑     *     * @return     * @throws ZuulException     */
    @Override    public Object run() throws ZuulException {        // 获取请求的上下文类 注意是:com.netflix.zuul.context包下的        RequestContext ctx = RequestContext.getCurrentContext();        //避免中文乱码        ctx.addZuulResponseHeader("Content-type", "text/json;charset=UTF-8");        ctx.getResponse().setCharacterEncoding("UTF-8");        //获取request对象        HttpServletRequest request = ctx.getRequest();        log.info("请求方式:{},地址:{}", request.getMethod(), request.getRequestURL().toString());        // 获取token参数        Object accessToken = request.getParameter("token");        if (accessToken == null) {            // 使其不进行转发 自定义route类型时,在shouldFilter中也需要进行此参数判断            ctx.setSendZuulResponse(false);            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());            try {                ctx.getResponse().getWriter().write("非法访问");            } catch (Exception e) {            }            return null;        } else {            if ("123".equals(accessToken)) {                try {                    ctx.getResponse().getWriter().write("token is error");                } catch (IOException e) {                    e.printStackTrace();                }                return null;            }        }        return null;    }}

说下过滤类型

pre:可以在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。 roting:在路由请求时候被调用。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。 post:在routing和error过滤器之后被调用。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。 error:处理请求时发生错误时被调用

filterType 该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了四种不同生命周期的过滤器类型,具体如下:

  • pre:可以在请求被路由之前调用。
  • routing:在路由请求时候被调用。
  • post:在routing和error过滤器之后被调用。
  • error:处理请求时发生错误时被调用 看下官网wiki提供的四种过滤器的生命周期图

zuul请求生命周期

重启zuul-server服务 不携带token访问

http://localhost:8767/feign/hello?name=lhd

带上一个错误token

正常访问接口 token正确 可以正常访问

搞定!

源码下载: https://github.com/LiHaodong888/SpringCloudLearn

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 李浩东的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 简介
    • 1. Zuul 是什么?
      • 2.Zuul能做什么?
      • 二. 使用Zuul作为路由转发
      • 三. zuul服务过滤
      相关产品与服务
      负载均衡
      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档