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. word转pdf(使用office)

    1.安装office软件 2.在vs中写代码 注意需要引入 Microsoft.Office.Interop.Word插件 /// <summary> /// 将word转换成pdf文件 ...

  2. redis内存模型及应用解读

    Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型:字符串.哈希 ...

  3. 16、IO (Properties、序列化流、打印流、CommonsIO)

    Properties集合的特点 * A: Properties集合的特点 * a: Properties类介绍 * Properties 类表示了一个持久的属性集.Properties 可保存在流中或 ...

  4. VMwear安装Centos7详细过程

      1.软硬件准备软件:推荐使用VMwear,我用的是VMwear 10镜像:CentOS7   硬件:因为是在宿主机上运行虚拟化软件安装centos,I3CPU双核.硬盘500G.内存4G以上. 2 ...

  5. CodeForces 598A(水)

    还是要注意int和long long的范围,以及double型的问题 pow函数经常会报一个double型的错,参考这篇文章 http://blog.csdn.net/lawrencesgj/arti ...

  6. Java的文档注释之生成帮助文档

    示例: /** * Title: Person类<br/> * Description:通过Person类说明Java中的文档注释<br/> * Company: *** * ...

  7. High Performance MySQL笔记:count

    在SQL中使用count()好像是非常自然的事情: SELECT COUNT(*) FROM TABLE_NAME; 有时候确实会想过,count(*)和单独的count(column_name)有什 ...

  8. HTML5之新增的元素和废除的元素 (声明:内容节选自《HTML 5从入门到精通》)

    新增结构元素: section元素 section元素定义文档或应用程序中的一个区段,比如章节.页眉.页脚或文档中的其他部分.它可以与h1,h2,h3,h4,h5,h6元素结合起来使用,标示文档结构. ...

  9. php中怎么理解Closure的bind和bindTo

    bind是bindTo的静态版本,因此只说bind吧.(还不是太了解为什么要弄出两个版本) 官方文档: 复制一个闭包,绑定指定的$this对象和类作用域. 其实后半句表述很不清楚. 我的理解: 把一个 ...

  10. js-小数计算问题

    先上图: 什么情况? 原因:js采用二进制进行小数计算 先看十进制的小数转换为二进制的方法: 十进制数的整数位是二进制数的整数位,十进制数的小数位是二进制数的小数位 假如我们有小数111.4(10), ...