Springcloud之Zuul网关入门

摘要:
在SpringCloud中实现微服务的架构基本成形:服务注册、服务注册和发现是在SpringCloudNetflix中使用Eureka实现的;服务可以通过Ribbon或Feign进行消费和负载平衡。Zuul是对服务的统一访问。因此,Zuul提供了一个简化的配置语法:Zuul。路线=zuul:routes:test provider:/test provider/**#这是映射路径2.5。zuul指定默认的路由规则:默认情况下,所有服务的映射路径都是服务名称本身。3过滤器:作为网关的重要功能之一,Zuul实现了请求认证。

Spring Cloud实现微服务的架构基本成型:

  使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载。

  为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。

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

Zuul的核心是一系列的过滤器,完成包括:

  • 认证和安全:识别每个需要认证的资源,拒绝不符合要求的请求。
  • 性能监测:在服务边界追踪并统计数据,提供精确的生产视图。
  • 动态路由:根据需要将请求动态路由到后端集群。
  • 压力测试:逐渐增加对集群的流量以了解其性能。
  • 负载分配:预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。
  • 静态资源处理:直接在边界返回某些响应,从而避免其转发到内部集群。

不管是自于客户端(PC或移动端)的请求,还是服务内部调用。一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现 鉴权、动态路由等等操作。

Zuul就是服务的统一入口。

1.工程入门

1.1工程基本信息:

Springcloud之Zuul网关入门第1张

1.2 添加Zuul依赖:

Springcloud之Zuul网关入门第2张

 1.3编写application.yml配置信息

server:
  port: 8090 #服务端口
spring:
  application:
    name: api-gateway #指定服务名

1.4编写引导类

使用@EnableZuulProxy注解开启Zuul功能

@SpringBootApplication
@EnableZuulProxy // 开启网关功能
public class ItestZuulApplication {

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

1.5编写路由规则

使用Zuul来代理test-provider服务

server:
  port: 8090 #服务端口
spring:
  application:
    name: api-gateway #指定服务名
zuul:
  routes:
    test-provider: # 这里是路由id,随意写
      path: /test-provider/** # 这里是映射路径
      url: http://127.0.0.1:8081 # 映射路径对应的实际url地址

将符合  path  规则的一切请求,都代理到 url参数指定的地址

测试

2面向服务的路由

对itest-zuul工程修改优化

2.1.添加Eureka客户端依赖

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

2.2添加Eureka配置,获取服务信息

eureka:
  client:
    registry-fetch-interval-seconds: 5 # 获取服务列表的周期:5s
    service-url:
      defaultZone: http://127.0.0.1:8086/eureka

2.3在启动类中添加Eureka客户端发现功能

@SpringBootApplication
@EnableZuulProxy // 开启Zuul的网关功能
@EnableDiscoveryClient
public class TestZuulApplication {

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

2.4修改映射配置,通过服务名称获取

因为已经有了Eureka客户端,直接可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。

zuul:
  routes:
    test-provider: # 这里是路由id,随意写
      path: /test-provider/** # 这里是映射路径
      serviceId: test-provider # 指定服务名称

简化配置

  • zuul.routes.<route>.path=/xxx/**: 来指定映射路径。<route>是自定义的路由名

  • zuul.routes.<route>.serviceId=service-provider:来指定服务名。

大多数情况下<route>路由名称和服务名会写成一样的。

因此Zuul就提供了一种简化的配置语法:

zuul.routes.<serviceId>=<path>

zuul:
  routes:
    test-provider: /test-provider/** # 这里是映射路径

2.5 Zuul指定了默认的路由规则:

默认情况下,一切服务的映射路径就是服务名本身。例如服务名为:test-provider,则默认的映射路径就是:/test-provider/**

zuul:
  routes:
    service-provider: /service-provider/**
    service-consumer: /service-consumer/**
  prefix: /api # 添加路由前缀

通过zuul.prefix=/api来指定了路由的前缀,这样在发起请求时,路径就要以/api开头。

3过滤器:

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。

3.1ZuulFilter

ZuulFilter是过滤器的顶级父类。其中定义的4个最重要的方法:

public abstract ZuulFilter implements IZuulFilter{

    abstract public String filterType();

    abstract public int filterOrder();
    
    boolean shouldFilter();// 来自IZuulFilter

    Object run() throws ZuulException;// IZuulFilter
}

  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。

  • run:过滤器的具体业务逻辑。

  • filterType:返回字符串,代表过滤器的类型。包含以下4种:

    • pre:请求在被路由之前执行,一般用于请求认证、负载均衡和日志记录。

    • route:在路由请求时调用。这里使用Apache HttpClient或Netflix Ribbon构造对目标的HTTP请求。

    • post:在route和errror过滤器之后调用,般会在此步骤添加响应头、收集统计和性能数据等。

    • error:处理请求时发生错误调用。

  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

Zuul Filter有以下几个特征:

  • Type:用以表示路由过程中的阶段(内置包含PRE、ROUTING、POST和ERROR)
  • Execution Order:表示相同Type的Filter的执行顺序
  • Criteria:执行条件
  • Action:执行体

Zuul提供了动态读取、编译和执行Filter的框架。各个Filter间没有直接联系,但是都通过RequestContext共享一些状态数据。

3.2过滤器的生命周期

Springcloud之Zuul网关入门第3张

3.1正常流程:

  • 请求到达首先会经过pre类型过滤器,而后到达route类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。

3.2异常流程:

  • 整个过程中,pre或者route过滤器出现异常,都会直接进入error过滤器,在error处理完毕后,会将请求交给POST过滤器,最后返回给用户。

  • 如果是error过滤器自己出现异常,最终也会进入POST过滤器,将最终结果返回给请求客户端。

  • 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和route不同的是,请求不会再到达POST过滤器了。

3.3过滤器使用场景:

  • 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了

  • 异常处理:一般会在error类型和post类型过滤器中结合来处理。

  • 服务调用时长统计:pre和post结合使用。

4.自定义过滤器

模拟一个登录的校验。

基本逻辑:如果请求中有access-token参数,则认为请求有效,放行。

4.1定义过滤器类package:filter.LoginFilter

@Component
public class LoginFilter extends ZuulFilter {
    /**
     * 过滤器类型,前置过滤器
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器的执行顺序
     */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * 该过滤器是否生效
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 登陆校验逻辑*/
    @Override
    public Object run() throws ZuulException {
        // 获取zuul提供的上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        // 从上下文对象中获取请求对象
        HttpServletRequest request = context.getRequest();
        // 获取token信息
        String token = request.getParameter("access-token");
        // 判断
        if (StringUtils.isBlank(token)) {
            // 过滤该请求,不对其进行路由
            context.setSendZuulResponse(false);
            // 设置响应状态码,401
            context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
            // 设置响应信息
            context.setResponseBody("{"status":"401", "text":"request error!"}");
        }
        // 校验通过,把登陆信息放入上下文信息,继续向后执行
        context.set("token", token);
        return null;
    }
}

5.Zuul中的负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。

但是所有的超时策略都是走的默认值,如熔断超时时间只有1S,很容易就触发了。

建议我们手动进行配置:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000 # 设置hystrix的超时时间为6000ms

相关结束。

免责声明:文章转载自《Springcloud之Zuul网关入门》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Robots.txt 协议详解及使用说明解决Eclipse中“诡异”的错误:找不到或无法加载主类下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Vue中解决路由切换,页面不更新的实用方法

前言:vue-router的切换不同于传统的页面的切换。路由之间的切换,其实就是组件之间的切换,不是真正的页面切换。这也会导致一个问题,就是引用相同组件的时候,会导致该组件无法更新,也就是我们口中的页面无法更新的问题了。 一、问题呈现 在路由中进行切换结果 这时候会发现input标签的value值并没有随着路由的改变而改变。并没有更新 二、解决方...

.NET作品集:linux下的博客程序

博客程序架构 本博客程序是博主11年的时候参考loachs小泥鳅博客内核开发的.net跨平台博客cms,距今已有6年多了,个人博客网站一直在用,虽然没有wordpress那么强大,但是当时在深究.net的同时,自己能写一个博客程序,并且基于独立Linux服务器搭建一个自己的.net网站还是挺有意思,毕竟当年运行在linux下的.net网站还是极少数的,之前的...

静态路由

1. 路由基础 1.1 路由概述 路由的作用: 指引数据的转发 三层查询:目的IP地址 路由查询: 不用关心网络地址和广播地址能不能用 每经过一台三层设备都会进行查询路由表 数据传输: 变化:MAC地址(源和目的),每经过一个三层转发都会改变 不变:IP地址(源和目的) 命令: 思科:show ip route 华为:display ip r...

Linux下的静态路由配置

在日常运维作业中,经常会碰到路由表的操作。下面就linux运维中的路由操作做一梳理:------------------------------------------------------------------------------先说一些关于路由的基础知识:1)路由概念路由:   跨越从源主机到目标主机的一个互联网络来转发数据包的过程路由器:能够...

TCP/IP协议(一)网络基础知识 网络七层协议

参考书籍为《图解tcp/ip》-第五版。这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述)、OSI参考模型、网络概念的本质、网络构建的设备等     下面是协议层从底层至顶层的一个模型图:   一、计算机网络的背景 1.1 计算机的发展 有人说:“20世纪最伟大的发明就是计算机”,自诞生伊始,计算机经历了...

DDWRT "中继桥接"模式 配置方法

一直喜欢耍路由,TOMATO玩双通、3G路由,后来是DD-WRT蹭网,不过一直都没有摆脱一个问题,那就是都是“玩家”,废话少说 ,进入主题中继蹭网: 准备: 我的DD-WRT固件版本(R2):DD-WRT v24-sp2 (07/16/10) mega(至少要 V24 RC5以上) 准备蹭网的主路由(R1):ssid、连接密码 注:如果破解密码请goog...