常用的微服务架构
种种架构的不足就是缺少权限控制, 现在我们需要增加的就是服务网关了,
服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、
均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,
为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,
使得服务集群主体能够具备更高的可复用性和可测试性。
下面我们通过实例例子来使用一下Zuul来作为服务的路有功能
准备工作
在使用Zuul之前,我们先构建一个服务注册中心、以及两个简单的服务,比如:我构建了一个simple-service,
一个simple-service1。然后启动eureka-server和这两个服务。
通过访问eureka-server,我们可以看到simple-service和simple-service1已经注册到了服务中心。
开始使用Zuul
引入依赖spring-cloud-starter-zuul、spring-cloud-starter-eureka,如果不是通过指定serviceId的方式,eureka依赖不需要,
但是为了对服务集群细节的透明性,还是用serviceId来避免直接引用url的方式吧。
|
|
应用主类使用@EnableZuulProxy注解开启Zuul
@SpringCloudApplication注解,通过源码我们看到,
它整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker
application.properties中配置Zuul应用的基础信息,如:应用名、服务端口等。
在Zuul中提供了两种映射方式:
通过url直接映射,我们可以如下配置:
|
|
该配置,定义了,所有到Zuul的中规则为:/api-a-url/**的访问都映射到http://localhost:2222/上,
也就是说当我们访问http://localhost:5555/api-a-url/add?a=1&b=2的时候,Zuul会将该请求路由到:
http://localhost:2222/add?a=1&b=2上。
通过serviceId的映射
|
|
通过浏览器就可以访问了。如http://localhost:5555/api-b
服务过滤
在完成了服务路由之后,我们对外开放服务还需要一些安全措施来保护客户端只能访问它应该访问到的资源。
所以我们需要利用Zuul的过滤器来实现我们对外服务的安全控制。
在服务网关中定义过滤器只需要继承ZuulFilter抽象类实现其定义的四个抽象函数就可对请求进行拦截与过滤。
自定义过滤器的实现,需要继承ZuulFilter,需要重写实现下面四个方法:
filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
pre:可以在请求被路由之前调用
routing:在路由请求时候被调用
post:在routing和error过滤器之后被调用
error:处理请求时发生错误时被调用
filterOrder:通过int值来定义过滤器的执行顺序
shouldFilter:返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关,默认false,不执行
run:过滤器的具体逻辑
然后在主类中注入该类
最后在浏览器中输入http://localhost:5555/api-b/add?a=1&b=2就不可以访问,
而http://localhost:5555/api-b/add?a=1&b=2&c=d可以访问了
根据之前对filterType生命周期介绍,可以参考下图去理解,并根据自己的需要在不同的生命周期中去实现不同类型的过滤器。
总结:
服务网关的优点:
不仅仅实现了路由功能来屏蔽诸多服务细节,更实现了服务级别、均衡负载的路由。
实现了接口权限校验与微服务业务逻辑的解耦。通过服务网关中的过滤器,在各生命周期中去校验请求的内容,
将原本在对外服务层做的校验前移,保证了微服务的无状态性,同时降低了微服务的测试难度,
让服务本身更集中关注业务逻辑的处理。
实现了断路器,不会因为具体微服务的故障而导致服务网关的阻塞,依然可以对外服务。