zuul是什么
路由是微服务体系结构的一个组成部分。是Netflix的基于JVM的开发的路由和服务器端负载均衡器,如果没有服务网关,多个服务提供给前端调用地址管理错综复杂,增加了客户端的复杂性,认证也相对麻烦,每个服务都需要编写相同的认证…
简单来讲,springcloud中建立一个zuulwanggua网关服务,这样在分布式的场景中,如果一个页面需要用到多个服务请求的时候,不需要向每一个不同的服务器发送请求,只需要向一个网管服务发送请求就可以了。
这样做的好处明显有两个,第一个,前段不需要管理多个URL或者IP,如果想要访问不同服务中的东西,都向网关一个IP或URL发送即可。第二点,在针对一些权限控制方面,不需要每个服务单独做权限控制,只需要在网管服务这一层中发送即可,在网管上作统一的权限控制。
Zuul的位置
如上图所示,zuul网关在系统中的位置处于逻辑层和显示层之间。
如何使用Zuul(简单版)
- 首先,yml文件中如下
server:
port: 5003
spring:
application:
name: train-zuul
profiles:
active: dev
# 将配置中心注册到eureka实现高可用
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://train:*****@localhost:5000/eureka/
zuul:
routes:
hello-service2:
path: /api-admin/** # 访问的地址
serviceId: train-adminweb # 跳转的服务名
hello-service1:
path: /api-front/** # 访问的地址
serviceId: train-frontweb # 跳转的服务名
如上所示,服务访问 http://localhost:5003/api-admin/,可以通过zuul网关转发到对应的服务中去。当然这个地方可以也可以使用URL等。如果需要忽视某一个访问路径转发,也可以通过ignore-*配置进行忽视,这里略过
主入口需要加入注解
@EnableZuulProxy
- 应用在实际情况中,可能出现权限控制的问题,针对某些接口需要进行权限控制,那么可以通过集成ZuulFilter来进行过滤器的配置。下面是一个例子,针对/api-admin/admin/login 这个路径不过滤,可以让其直接转发到相应的服务,但是对于其他的路径均需过滤,实现的方案如下:
@Component
public class ZuulConfigFilter extends ZuulFilter{
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run(){
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
logger.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
String token = request.getParameter("token");
logger.info("ServletPath:"+request.getServletPath());
if (request.getServletPath().equals("/api-admin/admin/login")) {//暂时简单化测试
ctx.setSendZuulResponse(true);// 对该请求进行路由
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);// 设值,可以在多个过滤器时使用
return null;
} else {
ctx.setSendZuulResponse(false);// 过滤该请求,不对其进行路由
ctx.setResponseStatusCode(403);// 返回错误码
ctx.setResponseBody("{\"result\":\"Request illegal!the token is null\"}");// 返回错误内容
ctx.set("isSuccess", false);
return null;
}
}
}
在上面的代码中,filterType指的是过滤类型,可以是出错时,路由前,路由后等,这里采用的pre指的是路由前;filterOrder指的是执行顺序,越小越先执行;shouldFilter指的是是否过滤,在这里可以针对一些链接不作过滤处理,但上面的例子实在下面的过滤操作中进行的,其实在这里判断是否过滤更有理由。
△ 在这里,由于login没有过滤,所以正常返回“show”字符串,其他的链接都被过滤了,所以显示的是错误信息。
以上即是最简单的zuul网关过滤例子,关于其他的细节部分可以通过官方教程,下一次可以出一个和oauth2整合的Demo。