网关
通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。
下面我们通过实例例子来使用一下Zuul来作为服务的路有功能。
准备
在使用Zuul之前,我们先构建一个服务注册中心、以及两个简单的服务,比如:我构建了一个service-A,一个service-B。然后启动eureka-server和这两个服务。通过访问eureka-server,我们可以看到service-A和service-B已经注册到了服务中心。
尝试通过服务网关来访问service-A和service-B,根据配置的映射关系,分别访问下面的url
- http://localhost:4444/api-a/add?a=1&b=2:通过serviceId映射访问service-A中的add服务
- http://localhost:4444/api-b/add?a=1&b=2:通过serviceId映射访问service-B中的add服务
- http://localhost:4444/api-a-url/add?a=1&b=2:通过url映射访问service-A中的add服务(本示例并没有使用url映射,可以在配置文件里面去掉serviceId映射配置,添加上url映射)
推荐使用serviceId的映射方式,除了对Zuul维护上更加友好之外,serviceId映射方式还支持了断路器,对于服务故障的情况下,可以有效的防止故障蔓延到服务网关上而影响整个系统的对外服务
服务过滤
在完成了服务路由之后,我们对外开放服务还需要一些安全措施来保护客户端只能访问它应该访问到的资源。所以我们需要利用Zuul的过滤器来实现我们对外服务的安全控制。
  在服务网关中定义过滤器只需要继承ZuulFilter抽象类实现其定义的四个抽象函数就可对请求进行拦截与过滤。
  比如下面的例子,定义了一个Zuul过滤器,实现了在请求被路由之前检查请求中是否有accessToken参数,若有就进行路由,若没有就拒绝访问,返回401 Unauthorized错误。
package com; import javax.servlet.http.HttpServletRequest; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; public class AccessFilter extends ZuulFilter{ public Object run() {//过滤器的具体逻辑 // TODO Auto-generated method stub RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accessToken = request.getParameter("accessToken"); if(accessToken == null) { ctx.setSendZuulResponse(false);//不进行路由 ctx.setResponseStatusCode(401); return null; } return null; } public boolean shouldFilter() {
