zuul网关找不到服务_填坑之路(四)zuul为微服务统一网关,路由分发

  • Post author:
  • Post category:其他


场景:

前面几节已经实现了能够实现服务间进行调用,并且做到了负载均衡,但是还是有一个问题。很多的服务,没有一个统一的对外网关也是很头疼的事,更何况服务直接没有进行权限控制。如果想在AAA或BBB这样的“提供业务”的服务上加权限控制,这个很繁琐,工作量也很大,即使打成公共的jar也是很繁琐。如果使用zuul就可以很好的实现路由网关,和权限控制

第一步:创建一个新项目zuul,添加相关依赖,springboot版本是1.4.3.RELEASE

org.springframework.cloud

spring-cloud-starter-eureka-server

org.springframework.cloud

spring-cloud-starter-zuul

org.springframework.cloud

spring-cloud-dependencies

Camden.SR4

pom

import

第二步、配置路由分发和注册中心地址

server.port=8085

eureka.client.serviceUrl.defaultZone=http://localhost:8899/eureka/

spring.application.name=ZUUL

#配置zuul路由分发功能,此处api-a/index 则会访问到AAA中的index方法

#http://127.0.0.1:8085/api-a/index相当于 http://127.0.0.1:8081/index

zuul.routes.api-a.path= /api-a/**

zuul.routes.api-a.serviceId=aaa

zuul.routes.api-b.path= /api-b/**

zuul.routes.api-b.serviceId=bbb

注意:前文有2个一样的微服务,AAA和BBB,这里就是模拟 api-a开头的全部分发到AAA,api-b的全部分发到BBB.

第三步、在启动类加 @EnableZuulProxy开启zuul代理

到这里,就可以实现访问 http://127.0.0.1:8085/api-a/index相当于访问 AAA里面的/index,AAA的端口是8081.实际就是访问 http://127.0.0.1:8081/index。这里已经完成了路由分发,但是还没有做到权限控制,也就是我们的接口处于裸奔状态,下面讲如何做权限控制,思路是添加一个filter,然后过滤请求,不符合要求的中断掉。具体如下:

第四步、建一个filter来过滤请求,关键决定是否放行的参数是ctx.setSendZuulResponse(boolean ),true放行,false中断

MyFilter类

/**

* 此处自定义一个拦截器基于zuul,进行权限验证,可以集成jwt

*/

@Component

public class MyFilter extends ZuulFilter {

private static Logger log = LoggerFactory.getLogger(MyFilter.class);

/**

* 定义filter的类型,有pre、route、post、error四种

* 过滤器类型选择:

* * pre 为路由前

* * route 为路由过程中

* * post 为路由过程后

* * error 为出现错误的时候

* * 同时也支持static ,返回静态的响应,详情见StaticResponseFilter的实现

* @return

*/

@Override

public String filterType() {

log.info(“——–filterType”);

return “pre”;

}

/**

* filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低

*

* @return

*/

@Override

public int filterOrder() {

return 0;

}

/**

* 是否执行该过滤器,此处为true,说明需要过滤

*

* @return

*/

@Override

public boolean shouldFilter() {

return true;

}

@Override

public Object run() {

RequestContext ctx = RequestContext.getCurrentContext();

HttpServletRequest request = ctx.getRequest();

log.info(String.format(“%s >>> %s”, request.getMethod(), request.getRequestURL().toString()));

Object accessToken = request.getParameter(“token”);

if (accessToken == null) {

log.warn(“token 不存在”);

//决定是否放行路由(也叫分发这个路由),此处不放行

ctx.setSendZuulResponse(false);

ctx.setResponseStatusCode(401);

try {

ctx.getResponse().getWriter().write(“token 不存在”);

} catch (Exception e) {

e.printStackTrace();

}

} else {

//有 token进行放行

ctx.setSendZuulResponse(true);

ctx.setResponseStatusCode(200);

}

return null;

}

到这里已经完成了权限控制,这里做的比较简单就是看有没有一个参数叫token,有的话就放行了,这里可以集成jwt,在这里进行鉴权。其实还有一个问题:如何访问不是api-a和api-b的呢,其实直接不带api-a就行了。

还存在的问题:zuul是网关,是绝对不能停机的,那么如果有新增路由或者修改,怎么办?如果能够实现动态路由是不是就可以了,在不停机的情况下自动刷新并重载配置。以及当系统有N多个微服务时候,那么多的配置如何管理,如何动态刷新?具体实现请看下2节SpringCloud Config和Spring Bus.



版权声明:本文为weixin_39610594原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。