前言:
上篇博客中,我们快速搭建了一个Spring Cloud微服务的dome,那么这个博客就是在哪个dome的基础上开始讲解一下服务网关zuul的使用,zuul的作用我在我的前面博客中也有提到,这里就不多说。
上次和这次dome的代码已上传到github,需要自取:
https://github.com/xuhao008/Spring-Cloud
一、Zuul网关的基本知识
首先网关顾名思义,就像我们生活中的海关,你必须具备一定条件就可以通过,所有我们的网关也就是这样,主要是过滤或拦截,当我们的用户访问服务的时候,通过网关的验证,然后转发到相对应的服务。
Zuul过滤器生命周期
Zuul大部分功能都是通过过滤器来实现的,Zuul定义了4种标准的过滤器类型,这些过滤器类型对应于请求的典型生命周期:
- pre: 这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择请求的微服务,记录调试信息等。
- routing: 这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
- post: 这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的http header、收集统计信息和指标、将响应从微服务发送给客户端等。
- error: 在其他阶段发送错误时执行该过滤器。
二、快速搭建zuul网关
创建一个Maven子项目
选择项目创建完毕,我们就来编写pom.xml,yml配置和启动类
1、导入maven坐标依赖
pom.xml
<dependencies>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
2、在resources下创建application.ym配置文件,并编写
application.yml
server:
port: 7777
spring:
application:
name: service-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8081/eureka
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
zuul:
routes:
#服务名称,随便取
service-a:
#用什么路径取服务对应的服务
path: /a/**
#serviceId,对应了服务名称
serviceId: service-a
#url: http://localhost:8888/ #也可以使用请求路径,不用服务名称
service-b:
path: /b/**
serviceId: service-b
3、编写启动类
ZuulApplication.java
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class,args);
}
}
编写完毕以后,就可以启动我们的服务和网关了
然后我们访问:http://localhost:7777/b/hello
三、设置网关的过滤器
刚刚我们已经成功搭建和设置了网关,虽然可以通过网关服务其他服务了,但是我们都是网关最重要的功能是拦截和过滤,我们刚刚还没有涉及到,选择我们一起来看看。
首先我们创建一个类,继承ZuulFilter ,实现它的4个方法
- filterType(),用来设置过滤类型
- filterOrder(), 设置过过滤器优先级,数字越大,优先级越低
- shouldFilter,返回true或false,表示是否开启过滤
- run(),一些自定义的过滤信息方法
下面我们开始编写:
创建com.xkkj.filter包,创建TokenFilter.java
@Component
public class TokenFilter extends ZuulFilter {
@Override
public String filterType() {
// 可以在请求被路由之前调用
return "pre";
}
@Override
public int filterOrder() {
// filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低
return 0;
}
@Override
public boolean shouldFilter() {
// 是否执行该过滤器,此处为true,说明需要过滤
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context .getRequest();
// 获取请求的参数
String token = request.getParameter("token");
if (token!=null) {
//对请求进行路由
context .setSendZuulResponse(true);
context .setResponseStatusCode(200);
return null;
} else {
//不对其进行路由
context .setSendZuulResponse(false);
context .setResponseStatusCode(400);
context .setResponseBody("ERROR");
return null;
}
}
}
这里我们判断token是否有值,如果没有就抛出error。
下面我们运行看看:
地址:http://localhost:7777/b/hello
地址:http://localhost:7777/b/hello?token=1
地址:http://localhost:9999/hello
这里我们可以看到,如果通过zuul网关去访问你对应的服务,就会触发你的过滤器,如果你是直接访问你对应服务的地址,过滤就不会生效。
而这种网关转发之后的请求 就叫做反向代理你可以隐藏你本地的服务器的真实地址 只暴露给外界网关的地址 然后由网关转发给服务器。