说明:
Spring Cloud Zuul是SpringClud的网关,我们知道,网关一般是应用的入口,做一些公共的和业务无关的校验工作,例如加验签、加解密等一些操作,而zuul作为微服务的网关,有如下原因:
1、作为系统的统一入口,屏蔽了微服务内部的实现细节;
2、与服务治理框架相结合(例如:Eureka),实现自动化的实例维护、以及负载均衡的路由转发;
3、实现接口的校验与微服务业务逻辑的解耦;
4、通过zuul中的各种过滤器,在各生命周期去校验请求内容,将原本对外服务层做的校验前移,保证了微服务的无状态性,同时降低了微服务的测试难度,让微服务更加关注本身的业务逻辑的处理;
好了,接下来我们开始一个zuul网关服务:
一、引入zuul的pom以来:
4.0.0
com.ck.springcloud
hello-service-api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
1.3.7.RELEASE
org.springframework.cloud
spring-cloud-starter-zuul
org.springframework.cloud
spring-cloud-starter-eureka-server
org.springframework.cloud
spring-cloud-dependencies
Brixton.SR5
pom
import
因为Zuul要结合Eureka使用,所以也要引入Eureka的依赖,下面会讲解Zuul怎么和Eureka的结合使用;
二、增加启动类,增加Zuul的启动配置注解@EnableZuulProxy:
package controller;
import com.netflix.zuul.FilterLoader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableZuulProxy
@EnableConfigurationProperties(FilterConfiguration.class)
public class Application {
FilterConfiguration filterConfiguration;
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).run(args);
}
@Bean
public AccessFilter getAccessFilter(){
return new AccessFilter();
}
@Bean
public FilterConfiguration filterLoader(FilterConfiguration filterConfiguration){
this.filterConfiguration = filterConfiguration;
System.out.println(filterConfiguration.getInterval()+filterConfiguration.getRoot());
return filterConfiguration;
}
}
三、增加配置文件application.yml文件:
spring:
application:
name: api-gateway
server:
port: 5555
eureka:
client:
serviceUrl:
defaultZone: http://localhost:1111/eureka/
zuul:
routes:
api-a:
path: /api-a/**
url: http://localhost:8080
api-b:
path: /api-b/**
serviceId: feign-consumer
AccessFilter:
pre:
disable: true
zuuls:
filter:
root: filter
interval: 5
在上面的配置中,我们配置了2个路由规则:
1、是/api-a/**的请求都会转发到http://localhost:8080
2、/api-b/**的请求都会通过Ribbon负载均衡随机转发到微服务名feign-consumer(通过与Eureka注册中心结合,动态的获取所有微服务实例)的实例上;
通过简单的配置,现在一个简单的Spring Cloud Zuul网关就实现了!
Zuul中还可以增加过滤器,在转发请求到微服务之前做拦截过滤,实现过滤器很简单,只要集成ZuulFilter父类;
例子:
package controller;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
public class AccessFilter extends ZuulFilter {
//表明这是一个前置过滤器,在转发到微服务之前执行
@Override
public String filterType() {
return "pre";
}
//多个过滤器之前,通过返回的order判断过滤器的执行顺序
@Override
public int filterOrder() {
return 0;
}
//这个过滤器是否执行,true表示执行
@Override
public boolean shouldFilter() {
return true;
}
//具体的拦截执行逻辑,过去逻辑是如果请求参数中没有accessToken就拦截此次请求
//否则通过
@Override
public Object run() {
System.out.println("access token start");
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest httpServletRequest = requestContext.getRequest();
Object accessToken = httpServletRequest.getParameter("accessToken");
if(accessToken == null){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
System.out.println("access token ok");
return null;
}
}
最后别忘记了,在Application启动类中将AccessFilter注册成bean:
@Bean
public AccessFilter getAccessFilter(){
return new AccessFilter();
}
禁用过滤器的方法,一种是修改过滤器的shouldFilter方法,这种方法缺乏灵活性,需要修改程序,第二种方式是增加配置:
zuul.
其中SimpleClassName代表过滤器的类名,filterType代表过滤器的类型;