一。为什么要有网关

  我们先看一个图,如果按照consumer and server(最初的调用方式),如下所示

  这样我们要面临如下问题:

  1. 用户面临着一对N的问题既用户必须知道每个服务。随着服务的增多难免会....

  2.消费端(在这里可能是服务,也有可能为controller等),如何进行安全控制?比如说对调用者身份的验证,防止爬虫,或者限制IP在一定时间内的请求数?

  3.即便做了这些验证,那么每个消费端都要重复的编写代码?会不会造成冗余?

  那么解决这些问题,我们不妨进行改造一下:

  

  这样我们可以将一对N转成了一对一,用户只需跟网关打交道就好了,这样我们可以在网关里处理身份验证等安全性问题,何乐而不为呢

二。SpringCloud中的zuul

  Zuul 是在云平台上提供动态路由,监控,弹性,安全等服务框架,Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。同时Zuul使用一系列不同类型的过滤器,使我们能够快速,灵活地将功能应用于我们的安全服务。这些过滤器可帮助我们执行以下功能:

  • 身份验证和安全性 - 识别每个资源的身份验证要求并拒绝不符合要求的请求。

  • 洞察和监测 - 跟踪有意义的数据和统计数据,以便为我们提供准确的生产视图。

  • 动态路由 - 根据需要动态路由请求到不同的后端群集。

  • 压力测试 - 逐渐增加群集流量以衡量性能。

  • 加载Shedding - 为每种类型的请求分配容量并删除超出限制的请求。

  • 静态响应处理 - 直接在边缘建立一些响应,而不是将它们转发到内部群集

  • 多区域弹性 - 跨AWS区域的路由请求,以便扩大我们的ELB使用范围。

  1.首先我们先添加spring-cloud对zuul的依赖:

compile('org.springframework.cloud:spring-cloud-starter-zuul')

  2.我们创建application.yml配置文件:

 

spring:
application:
name: gateway-server
server:
port: 8080
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka
zuul:
routes:
orders:
path: /orders/**
#url: http://www.baidu.com
serviceId: ORDER-SERVER
pay:
path: /pay/**
serviceId: PAY-SERVER

  3.编写启动类

package com.zhibo.springcloud.zuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ZuulApplication { public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class,args);
}
}

  注意@EnableZuulProxy是@EnableZuulServer的一个超集,我们可以通过源代码发现 org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration继承了ZuulServerAutoConfiguration

三。 zuul中的filter

  4.1 filter(过滤器)是一个很重要的概念,它可以在真正的请求之前进行必要的业务操作,比如说验证等。那么在zuul中过滤器最核心的接口为IZuulFilter,该接口定义非常简单: 

/*
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.zuul; import com.netflix.zuul.exception.ZuulException; /**
* BAse interface for ZuulFilters
*
* @author Mikey Cohen
* Date: 10/27/11
* Time: 3:03 PM
*/
public interface IZuulFilter {
/**
* a "true" return from this method means that the run() method should be invoked
*
* @return true if the run() method should be invoked. false will not invoke the run() method
*/
boolean shouldFilter(); /**
* if shouldFilter() is true, this method will be invoked. this method is the core method of a ZuulFilter
*
* @return Some arbitrary artifact may be returned. Current implementation ignores it.
* @throws ZuulException if an error occurs during execution.
*/
Object run() throws ZuulException; }

  而ZuulFilter是一个实现IZuulFilter接口的抽象类,这个类在接口的基础上又添加了如下抽象方法

/**
* to classify a filter by type. Standard types in Zuul are "pre" for pre-routing filtering,
* "route" for routing to an origin, "post" for post-routing filters, "error" for error handling.
* We also support a "static" type for static responses see StaticResponseFilter.
* Any filterType made be created or added and run by calling FilterProcessor.runFilters(type)
*
* @return A String representing that type
*/
abstract public String filterType(); /**
* filterOrder() must also be defined for a filter. Filters may have the same filterOrder if precedence is not
* important for a filter. filterOrders do not need to be sequential.
*
* @return the int order of a filter
*/
abstract public int filterOrder();

  我在这里简单解释一下这几个方法作用:

  filterType:定义过滤器的类型:常见的有pre(预处理阶段) post(请求原始服务之前) error(发生错误以后) route(请求原始服务之后)

  filterOrder:定义多个过滤器的优先级,值越小优先级越高

  shouldFilter:值如果为true,那么终会执行run()方法

  run : 过滤器实际上执行的内容

  4.2 RequestContext是ConcurrentMap的一个子类,这个类可以拿到HttpServletRequest与HttpServletResponse,同时这个类当中的数据可以被多个zuulFilter共享,其中有几个方法值得我们注意以下:

   getCurrentContext() 获取ThreadLocal中的RequestContext对象

   setSendZuulResponse() 如果设置为false那么将终止对原始地址的路由

   setResponseStatusCode() 设置http的状态响应码

   addZuulResponseHeader() 设置响应头,通过这个方法我们能解决响应时中文乱码问题

   setResponseBody() 设置响应体

 

  4.3 代码示例:实现用户名验证 

 

package com.zhibo.springcloud.zuul;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; @Component
public class ValidateUserZuulFilter extends ZuulFilter { /**
*
* @return
*/
@Override
public String filterType() {
return "pre";
} @Override
public int filterOrder() {
return 0;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
String loginName = request.getParameter("loginName");
if (loginName == null || !"admin".equals(loginName)) {
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(500);
Gson gson = new GsonBuilder().create();
requestContext.addZuulResponseHeader("content-type", "application/json;charset=utf-8");
requestContext.setResponseBody(gson.toJson(new ResponseEntity("没有登录名", HttpStatus.CONFLICT)));
return null;
}
return null;
}
}

四。zuul中超时的设置总结

  在这篇文章里已经很详细的说明了,请大家参考:周立的Springcloud超时总结

SpringCloud学习之zuul的更多相关文章

  1. SpringCloud学习之Zuul统一异常处理及回退

    一.Filter中统一异常处理 其实在SpringCloud的Edgware SR2版本中对于ZuulFilter中的错误有统一的处理,但是在实际开发当中对于错误的响应方式,我想每个团队都有自己的处理 ...

  2. SpringCloud学习笔记-zuul网关

    公司目前使用的是dubbo方式实现微服务,想试水改造接口层服务为Spring Cloud, 以下是网络拓补图. 第一层负载均衡可以用nginx或者zuul(即有2层zuul), 本图画的是nginx. ...

  3. SpringCloud 学习(5) --- Zuul(一)基本概念、配置

    [TOC] Spring Cloud eureka:注册中心 服务端:提供注册 客户端:进行注册 ribbon:负载均衡(集群) Hystrix:熔断器,执行备选方案 Feign:远程调用 Zuul: ...

  4. SpringCloud学习之Zuul路由转发、拦截和熔断处理(七)

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

  5. SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理

    前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...

  6. SpringCloud学习笔记(6):使用Zuul构建服务网关

    简介 Zuul是Netflix提供的一个开源的API网关服务器,SpringCloud对Zuul进行了整合和增强.服务网关Zuul聚合了所有微服务接口,并统一对外暴露,外部客户端只需与服务网关交互即可 ...

  7. springCloud学习05之api网关服务zuul过滤器filter

    前面学习了zuul的反向代理.负载均衡.fallback回退.这张学习写过滤器filter,做java web开发的对filter都不陌生,那就是客户端(如浏览器)发起请求的时候,都先经过过滤器fil ...

  8. springCloud学习总览

      写完最后一篇特意去看了看第一篇是什么时候写的---2018/11/19,到现在三个月多一点,总的来说这三个月通过<Spring 微服务实战>这本书,算是对微服务进行了一次扫盲学习.   ...

  9. SpringCloud学习笔记:服务支撑组件

    SpringCloud学习笔记:服务支撑组件 服务支撑组件 在微服务的演进过程中,为了最大化利用微服务的优势,保障系统的高可用性,需要通过一些服务支撑组件来协助服务间有效的协作.各个服务支撑组件的原理 ...

随机推荐

  1. CentOS7安装配置iptables防火墙

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/50779761 CentOS7默认的防火墙不是iptables,而是firewall ...

  2. mycat入门_介绍与安装

    利用闲暇时间接触了下mycat. 一.介绍 1.概述: 国内最活跃的.性能最好的开源数据库中间件,可以理解为数据库和应用层之间的一个代理组件. 2.作用: 读写分离.分表分库.主从切换. 3.原理: ...

  3. Python习题(第一课)

    想了想其他的太简单了,还是不放了,剩三题吧. 一.完美立方 编写一个程序,对任给的正整数N (N≤100),寻找所有的四元组(a, b, c, d),使得a^3= b^3 + c^3 + d^3,其中 ...

  4. WebAPI 跨域解决方案.

    先下载支持跨域的.dll,然后using System.Web.Http.Cors. 我把webapi解决方案部署到IIS上了.测试过后可以解决跨域. 方案一(用了*号,这样有安全隐患.): 直接在w ...

  5. php代码开启缓冲的使用方法

    php可以开启缓冲区,就是将内容放到缓冲区,再决定什么时候发送给浏览器. 感谢:http://www.jb51.net/article/38964.htm 解析PHP中ob_start()函数的用法 ...

  6. Linux命令及lamp搭建

    单纯属于Linux的命令:1.强制卸载有依赖关系的软件包: rpm -e httpd-2.2.15-26.el6.x86_64 --nodeps(--nodeps表示无依赖)4.删除当前目录所有的文件 ...

  7. CSS基础:块级元素与盒模型

    简介 在 HTML4.01 中,元素通常可以分为块级元素( “Block-level element” ) 和内联元素 ( "Inline-level element" ) 两大类 ...

  8. MySQL中使用sql语句获得表结构

    最近在研究PHP,那么就必须涉及到mysql.其中一个功能通过表数据自动生成页面,紧接着发现在一张空表中无法读取数据(因为人家刚刚新建,就是空的没有数据) 延伸出来便是直接查表结构获得字段名,再进行处 ...

  9. First:安装配置JDK and 部署Tomcat

    (一)准备 百度云地址(win,64Bit): 1.tomcat(7.0):链接:https://pan.baidu.com/s/1f60DOGO5Hnj9bq-987FNrw 密码:6q55 2.j ...

  10. linux下的Shell编程(4)特殊的变量和占位符

    $#表示包括$0在内的命令行参数的个数.在Shell中,脚本名称本身是$0,剩下的依次是$0.$1.$2-.${9},等等. $*表示整个参数列表,不包括$0,也就是说不包括文件名的参数列表. $?表 ...