分布式项目(九)zuul 网关

书接上回,这个接的有点久(手动滑稽)。。。

上次说道使用Nginx对coap接入做负载均衡,让协议服务器可以横向扩展,但我们的设备管理系统在访问时还是访问的我们服务器的地址,如果现在有其它服务要调用我们的设备管理系统如果直接使用其ip地址会有服务地址暴露的风险,并且后期如果做鉴权,都不好做,所以这里我们引出了spring cloud另外一个组件,zuul网关。

Zuul是什么

zuul是netfilx开源的一个api gateway服务器,记住是api 服务器,它只能做api请求网关,或者说是http请求的网关。像上面我们用Nginx做udp路由,使用的是端口监听,它是做不了的。

为啥要用zuul 它能干啥

为啥要用zuul,因为统一入口呀,统一入口能干啥,那可就多了哦

  • 审查与监控
  • 动态路由,负载均衡
  • 静态响应处理
  • 验证与安全保障

为啥它能干这么多事呢?

上面说zuul是一个api服务器,它本质上是一个web servlet服务器,或者说是个filter应用,专干拦截过滤的勾当((^o^)/~)。

zuul核心原理

zuul的工作流程是一系列的filters,和servlet的filter,spring中的aop是一样一样儿的。

一个http请求要走的路

http请求->zuul servlet->zuulFilter Runner -> filter1->filter2->.... ->业务服务器-> filter2->filter1->http response

这有点向什么,Status2的拦截器,也是请求的时候一个关卡一个关卡的过去,回来的时候在从后面的关卡一个一个的回来。

知道工作流程,突然发现一个问题,filter之间是如何传递数据的,一般这种问题就两种解决方案,一是我自己走哪儿带哪儿,这个好理解,就想我们带钱一样,就揣我兜里,想用的时候就用,二是放在一个地方我用的时候在去拿,这就比如钱太多了拿不动,咋办,放银行,用的时候我再去取。

zuul采用的是第二种方式,filter之前通过一个requestContext的静态类对进行数据的传递,那我把数据放进去了我取得时候咋知道是我的呢,钱存银行,银行会给你发张卡,你凭卡取钱,requestContext可没有卡,但它有另一个东西,ThreadLocal线程数据缓存器,这数据是A线程存的,那只有你A线程才能取出来,其它线程只能瞅着,错,连瞅都瞅不了。

刚才我们说网关是一个服务的入口,或者说是一个服务集群的入口,它的核心是filter,但我们又时候需要加一些新的filter,来满足我们新的需求,但是我们又不能把网关给停的,网关停了不整个服务就干瞪眼了么,所以我们需要它能动态地加载filter。

zuul的过滤器是由groovy写成的,这些过滤器被放在了zull server上特定的目录下面,zuul会定期轮训这些目录,修改过的过滤器会动态地加载到zuul server中以便过滤请求使用。这就满足了我们动态增过滤器的需求。

zuul过滤器类型

  • zuul定义了四种过滤器类型,这些过滤器类型对应请求的处于什么周期
  • pre:请求路由之间调用,可以做权限检测
  • routing:这种过滤器将请求,这种过滤器用于构建发送到微服务的请求,并使用Apache httpClient或ribbon请求微服务
  • post:这种过滤器在路由到微服务以后执行,可以用来添加标准的http header,收集统计信息和指标,将响应从微服务发送给客户端
  • error:在其它阶段发生错误是执行

这就有点想aop的请求前,请求后,发生错误执行了。

zuul还内置了两个特殊的过滤器

staticResponseFilter:允许从zull本身生成响应,而不是将请求转发,网关不是做转发么,它自己响应请求是个什么鬼,看名字静态?是噻,像那种百年不变的js,css,图片这种静态资源完全可以由网关自己响应。

surgicalDebugFilter:允许将特定请求路由到分隔的调试集群和主机上

关于zuul就简单介绍一下,下面开始编写代码。

创建protocol-zuul

maven配置

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
	<version>2.1.1.RELEASE</version>
</dependency>

<dependency>
	<groupId>cn.le</groupId>
	<artifactId>consul-discovery-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

#application配置

spring.application.name=protocol-zuul
server.port=8888

#健康检查路径
spring.cloud.consul.discovery.health-check-path=/actuator/health

#eureka.client.service-url.defaultZone=http://127.0.0.1:1111/eureka/

spring.cloud.consul.discovery.prefer-ip-address=true
spring.cloud.consul.discovery.instance-id=${spring.application.name}:${server.port}
spring.cloud.consul.discovery.hostname=${spring.application.name}
spring.cloud.consul.discovery.service-name=${spring.application.name}

#配置路由到此服务器
zuul.routes.api-a.service-id=iot-manage
#配置路由规则
zuul.routes.api-a.path=/manage/**
zuul.routes.api-a.stripPrefix=false

zuul关于路由映射的方式两种,一种是使用ip映射,一种是现在使用的这种zuul.routes.api-a.service-id的方法,ip映射的方式可以在独立使用zuul的时候使用,我们这里使用了注册中心,所以使用id名称映射的方式,这种方式对动态扩容,服务发现、注册友好。

而ip映射,电脑的IP地址有时候是会变动的,一旦变动,懂了赛。

启动zuul服务

zuul启动后,在consul的管理页面就可以看到zuul的服务了。

前面我们直接访问一下http://127.0.0.1:8081/manage/swagger-ui.html 可以正常打开设备管理系统的swagger的界面,但是现在我们有的服务网关,需要从服务网关去访问, http://127.0.0.1:8888/manage/swagger-ui.html 8888是zuul服务的端口,利用访问zuul的方式去访问设备管理系统看看能不能成功打开swagger。

一样能正常打开,这就表示zuul成功了。

自定义过滤器

刚才我们只用利用zuul去访问manager系统,但是没做任何处理,如果我们需要在访问之前对请求做处理,比如验证是否登录。

创建AuthFilter类,并继承ZuulFilter,作用是声明AuthFilter是一个ZuulFilter,并且可以让ZuulFilter Runner调用。

package cn.le.pre;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

[@Component](https://my.oschina.net/u/3907912)
/**
 * 自定义过滤器,继承zuulFilter即可
 */
public class AuthFilter extends ZuulFilter {

    //pre类型,请求路由之前调用
    [@Override](https://my.oschina.net/u/1162528)
    public String filterType() {
        return "pre";
    }
    //过滤器的执行顺序,数字越小表示越先执行
    [@Override](https://my.oschina.net/u/1162528)
    public int filterOrder() {
        return 0;
    }
    //判断此过滤器是否执行,true执行,false不执行
    [@Override](https://my.oschina.net/u/1162528)
    public boolean shouldFilter() {
        return true;
    }
    //过滤器执行逻辑
    [@Override](https://my.oschina.net/u/1162528)
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        System.out.println("AuthFilter----"+request);
        return null;
    }
}

这里只打印了请求信息,并没有写关于登录的逻辑,因为登录是一个综合组件配套的逻辑,这里篇幅有限就不实现了。

重新访问一下http://192.168.0.105:8888/manage/swagger-ui.html

从控制台日志我们可以看出对请求进行的过滤。

zuul 1.0与zuul 2.0对比

这个就看一下程序员DD大牛写的,我就不献丑了,zuul 1.0与2.0从设计结构与流程上都发生了变化,区别还是蛮大的。

http://blog.didispace.com/api-gateway-Zuul-1-zuul-2-how-to-choose/

结束语

https://gitee.com/distant/cloud-work.git

https://gitee.com/distant/iot-pt.git

转载于:https://my.oschina.net/u/2258281/blog/3063165

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值