7.1、为什么需要Zuul

Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用:

7.2、Zuul的工作原理

Zuul 是通过 Servlet 来实现的,
Zuul 通过自定义的 Zuu!Servlet (类似于 Spring MVC的DispatcServlet )来对请求进行控制
 
Zuul 的核心是一系列过滤器
可以在 Http 请求的发起和响应返回期间执行 系列的过滤器。
包含以下四种过滤器:

Zuul 采取了动态读取、编译和运行这些过滤器
过滤器 间不能直接相互通信,通过RequestContext 对象来共享数据
每个请求都会创建一个RequestContext 对象
特性:

请求的生命周期图:

7.3、案例

7.3.1、搭建 Zuul 服务

新建一个项目:

pom文件:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
此时需要使用到的工程:
配置均是之前的配置:
spring.application.name=feign
server.port=
eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
#开启Hystrix的功能
feign.hystrix.enabled=true

在下方配置文件的使用:

spring.application.name=hystric
server.port=
eureka.client.service-url.defaultZone=http://localhost:8762/eureka/
#开启Hystrix的功能
feign.hystrix.enabled=true

在下方配置文件的使用:

新建工程的配置类:

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class EurekaZuulClientApplication { public static void main(String[] args) {
SpringApplication.run(EurekaZuulClientApplication.class, args);
}
}
配置文件:
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/ server:
port:
spring:
application:
name: zuul zuul:
routes:
#自定义的
ribbonapi:
#路径
path: /ribbonapi/**
#引入的application(上述需要使用到的工程名)
serviceid: hystric feignapi:
path: /feignapi/**
serviceid: feign
zuul.routes.ribbonapi中的ribbonapi时自己定义的
需要指定path和serviceId两者配合使用
就可以将指定类型的请求url路由到制定的serviceId
即满足/ribbonapi 开头的请求Url都会被分发到hystric 服务
如果某个服务存在多个实例,Zul结合Ribbon会做负载均衡,将请求均分的部分路由到不同服务的实例。
 
此时也需要进行启动上述的两个工程,分别修改器端口号进行访问测试:
Eureka注册中心:

 
两个服务是可以进行访问的

此时访问:
hi是之前的请求url

这里会有负载均衡

可见Zuul在路由转发做了负载均衡。
 
如果不需要用 Ribbon 做负载均衡
可以指定服务实例的 Uri
zuul:
routes:
ribbonapi:
path: /ribbonapi/**
serviceid: hystric
url: http://localhost:8089
重新启动此时不会负载均衡,值会使用这个端口的进行服务!!!
 
如果你想指定 Url 并且想做负载均衡
那么就需要自己维护负载均衡的服务注册列表。
首先、ribbon.eureka.enabled 改为 false 
Ribbon 负载均衡客户端不向Eureka Client 获取服务注册列表信息
然后需要自己维护一份注册列表
该注册列表对应的服务名为hiapi-vl(这 名字可自定义)

7.3.2、Zuul 上配置 API 接口的版本号

 
若要给每个服务的API接口的加上前缀
此时的v1就是版本号
 
待补充.....

7.3.3、Zuul 上配置熔断器

 
Zuul 作为 Netflix 组件,可以和Ribbon、Eureka、Hystrix 等组件相结合,
实现负载均衡、熔断器的功能。
 
在默认情况下, Zuul和Ribbon相结合,实现了负载均衡的功能
 
MyFallbackProvider.class
package com.cr.eurekazuulclient.zull;

import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger; @Component
public class MyFallbackProvider implements FallbackProvider { @Override
public String getRoute() {
// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
return "hystric";
} public ClientHttpResponse fallbackResponse(){
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
} @Override
public int getRawStatusCode() throws IOException {
return ;
} @Override
public String getStatusText() throws IOException {
return "OK";
} @Override
public void close() { } @Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("The service is unavailable.".getBytes());
} @Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
} @Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) { if (cause != null && cause.getCause() != null){
String reason = cause.getCause().getMessage();
System.out.println("exception:" + reason);
}
return fallbackResponse();
}
}
此时启动服务!!!
访问hystrix的地址:
关闭该端口的服务:
此时的字符串是上文中的提示字符串

重启hystrix服务:

7.3.4、在Zuul中使用过滤器

过滤器的类型:

实现过滤器自需要继承ZuulFilter,并且实现其中的抽象方法
包括:filterType()、fil terOrder()、shouldFilter ()、Object run()
 
filterType():过滤器类型
filterOrder()是过滤顺序,值越小越早执行过滤器
shouldFilter()表示该过滤器是都过滤逻辑,为true则执行run()方法,false则不执行run()方法
run()方法写具体的过滤逻辑
 
本次的测试请求参数是否传送token参数
若没有传,则请求不被路由到具体的服务实例直接返回响应状态吗401
package com.cr.eurekazuulclient.zull;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest;
import java.util.logging.Logger; @Component
public class MyZuulFilter extends ZuulFilter { //private static Logger log= (Logger) LoggerFactory.getLogger(MyZuulFilter.class);
@Override
public String filterType() {
return "pre";
} @Override
public int filterOrder() {
return ;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
Object accessToken = request.getParameter("token"); if (accessToken == null){
System.out.println("token is empty");
//log.warning("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode();
try {
ctx.getResponse().getWriter().write("token is empty");
}catch (Exception e){
return null;
}
}
return null;
}
}
Zuul 的过滤器 ZuulFilter 的使用。
 
注意 EnableZuulProxy 注解能注册到 eureka 服务上,是因为该注解包含了
eureka 客户端的注解,该 EnableZuulProxy 是一个复合注解。
 
http://localhost:8150/routes 地址可以查看该zuul微服务网关代理了多少微服务的serviceId
 
 
     * 在 zuul 中定义了四种不同生命周期的过滤器类型:
     *
     *      1、pre:可以在请求被路由之前调用;
     *
     *      2、route:在路由请求时候被调用;
     *
     *      3、post:在route和error过滤器之后被调用;
     *
     *      4、error:处理请求时发生错误时被调用;

此时请求:

此时加上参数token:

MyZuulFilter这个 Bean 注入 IoC 容器之后
对请求进行了过滤
并在请求路由转发之前进行了逻辑判断
 
在实际开发中,可以用此过滤器进行安全验证

7.3.5、Zuul常见的使用方式

Zuul 是采用了类似于 Spring MVC的DispatchServlet 来实现的
采用的是异步阻塞模型,所以性能比 Ngnix 差
 
由于 Zuul和其他 Netflix 组件可以相互配合、无缝集成 Zuul 很容易
就能实现负载均衡、智能路由和熔断器等功能
 
大多数情况下、Zuul 都是以集群的形式存在的
 
由于Zuul的横向扩展能力非常好
所以当负载过高时
可以通过添加实例来解决性能瓶颈。

7、Spring -Cloud-路由网管Spring Cloud Zuul的更多相关文章

  1. spring boot 2.0.3+spring cloud (Finchley)5、路由网关Spring Cloud Zuul

    Zuul作为微服务系统的网关组件,用于构建边界服务,致力于动态路由.过滤.监控.弹性伸缩和安全. 为什么需要Zuul Zuul.Ribbon以及Eureka结合可以实现智能路由和负载均衡的功能:网关将 ...

  2. spring cloud 路由

    Spring Cloud Feign:用于微服务之间,只映射内网ip Spring Cloud Gateway:用于服务端,对外开放的接口,对外统一访问gateway映射的ip 是这样吗? 但是这样权 ...

  3. 一起来学spring Cloud | 第一章:spring Cloud 与Spring Boot

    目前大家都在说微服务,其实微服务不是一个名字,是一个架构的概念,大家现在使用的基于RPC框架(dubbo.thrift等)架构其实也能算作一种微服务架构. 目前越来越多的公司开始使用微服务架构,所以在 ...

  4. Spring Cloud(六)服务网关 zuul 快速入门

    服务网关是微服务架构中一个不可或缺的部分.通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能.Spring Cloud Netflix中 ...

  5. (2)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Cloud是什么?Spring Cloud版本介绍

    ​ Spring Cloud 是一系列框架的有序集合.它利用 Spring Boot 的开发便利性,巧妙地简化了分布式系统基础设施的开发,如服务注册.服务发现.配置中心.消息总线.负载均衡.断路器.数 ...

  6. spring cloud 入门系列六:使用Zuul 实现API网关服务

    通过前面几次的分享,我们了解了微服务架构的几个核心设施,通过这些组件我们可以搭建简单的微服务架构系统.比如通过Spring Cloud Eureka搭建高可用的服务注册中心并实现服务的注册和发现: 通 ...

  7. 微服务领域是不是要变天了?Spring Cloud Alibaba正式入驻Spring Cloud官方孵化器!

    引言 微服务这个词的热度自它出现以后,就一直是高烧不退,而微服务之所以这么火,其实和近几年互联网的创业氛围是分不开的. 与传统行业不同,互联网企业有一个特点,那就是市场扩张速度非常之快,可能也就是几天 ...

  8. spring boot 2.0.3+spring cloud (Finchley)6、配置中心Spring Cloud Config

    https://www.cnblogs.com/cralor/p/9239976.html Spring Cloud Config 是用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持, ...

  9. spring cloud (一):大话 Spring Cloud

    转自:http://www.ityouknow.com/springcloud/2017/05/01/simple-springcloud.html 研究了一段时间Spring Boot了准备向Spr ...

随机推荐

  1. HDU 1874(简单最短路) (大优化)

    优先队列那里用greater会报错 http://acm.hdu.edu.cn/showproblem.php?pid=1874 /* 使用pair代替结构 */ #include <iostr ...

  2. jenkins学习笔记

    Jenkins 是一款流行的开源持续集成(Continuous Integration)工具,广泛用于项目开发,具有自动化构建.测试和部署等功能.本系列博客以 windows 10 环境为例 1 安装 ...

  3. cf1056B. Divide Candies(数论 剩余系)

    题意 题目链接 求满足\(i^2 + j^2 \% M = 0\)的数对\((i, j)\)的个数,\(1 \leqslant i, j \leqslant 10^9, M \leqslant 100 ...

  4. int占几个字节?

    class Program19 { static void Main(string[] args) { // true,或false Console.WriteLine("bool占用:&q ...

  5. CC150相关问题

    18.9 动态计算中位数 利用两个堆:一个最大堆,存放小于中位数的值:一个最小堆,存放大于中位数的值. 则两个堆的堆顶即为数组中最中间的两个数. 在插入新元素的时候,我们只要维护两个堆, 使其堆中元素 ...

  6. Visual Staudio 2015 打开指定文件,定位到指定文件目录下

    Visual Staudio 2015 项目定位文件位置 每次使用的Visual Staudio 2015 写代码的时候总是打开了.cs文件或xaml文件时, 还要手动去找该 文件位置,每次都要翻好大 ...

  7. 词法分析器Lexer

    词法分析 In computer science, lexical analysis, lexing or tokenization is the process of converting a se ...

  8. time random sys 模块

    time模块 顾名思义就是时间模块 我们在之前就用过一些时间模块 比如你想要让打印的时间延迟就time.sleep() 首先我们知道这是一个时间操作的模块 它可以分为三种模式:时间戳模式.格式化时间模 ...

  9. 二、Asp.Net Core WebAPI——OcelotDemo

    项目源码OcelotDemo 基础知识在教程或者官网文档查看 Ocelot源码 基于.NET平台的Ocelot网关框架教程汇总 这篇文章不错. 这里我只写我想说的 项目结构 API1和API2是测试的 ...

  10. 辉光的UIView

    辉光的UIView 辉光UIView使用了一个UIView的一个category,名为UIView+Glow,请自行到github上查找. 源码如下: // // RootViewController ...