书接上回,这个接的有点久(手动滑稽)。。。css
上次说道使用Nginx对coap接入作负载均衡,让协议服务器能够横向扩展,但咱们的设备管理系统在访问时仍是访问的咱们服务器的地址,若是如今有其它服务要调用咱们的设备管理系统若是直接使用其ip地址会有服务地址暴露的风险,而且后期若是作鉴权,都很差作,因此这里咱们引出了spring cloud另一个组件,zuul网关。html
zuul是netfilx开源的一个api gateway服务器,记住是api 服务器,它只能作api请求网关,或者说是http请求的网关。像上面咱们用Nginx作udp路由,使用的是端口监听,它是作不了的。java
为啥要用zuul,由于统一入口呀,统一入口能干啥,那可就多了哦git
为啥它能干这么多事呢?程序员
上面说zuul是一个api服务器,它本质上是一个web servlet服务器,或者说是个filter应用,专干拦截过滤的勾当((^o^)/~)。web
zuul的工做流程是一系列的filters,和servlet的filter,spring中的aop是同样同样儿的。spring
一个http请求要走的路api
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中以便过滤请求使用。这就知足了咱们动态增过滤器的需求。
这就有点想aop的请求前,请求后,发生错误执行了。
zuul还内置了两个特殊的过滤器
staticResponseFilter:容许从zull自己生成响应,而不是将请求转发,网关不是作转发么,它本身响应请求是个什么鬼,看名字静态?是噻,像那种百年不变的js,css,图片这种静态资源彻底能够由网关本身响应。
surgicalDebugFilter:容许将特定请求路由到分隔的调试集群和主机上
关于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启动后,在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
从控制台日志咱们能够看出对请求进行的过滤。
这个就看一下程序员DD大牛写的,我就不献丑了,zuul 1.0与2.0从设计结构与流程上都发生了变化,区别仍是蛮大的。
http://blog.didispace.com/api-gateway-Zuul-1-zuul-2-how-to-choose/