摘要
路由是微服务架构不可或缺的一部分,本文将会介绍如何使用Zuul或Gateway为SpringCloud构建的微服务提供路由。
正文
1 使用Zuul作为API网关
1.1 如何搭建Zuul项目
- 创建SpringBoot工程并加入依赖
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
- 创建启动类,通过@EnableZuulProxy注解开启Zuul路由转发功能
@EnableZuulProxy
@SpringCloudApplication
public class ZuulApplication{
public static void main(String[] args){
new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
}
}
Zuul项目已经搭建完成,下面开始配置路由规则。
1.2 如何配置路由规则
默认情况,Zuul会为每个ServiceId添加映射,例如:存在一个ServiceId为user-service的服务,Zuul默认将/USER-SERVICE/**的请求转发到user-service服务的/**上。通过配置zuul.ignored-services
可以设置忽视配置的服务映射,*表示忽视全部列表。
下面是配置路由规则的几种方式
zuul.routes.user-service=/api-user/**
将/api-user/**的请求转发到user-service服务上zuul.routes.users.path=/api-user/**
zuul.routes.users.serviceId=user-service
将/api-user/**的请求转发到user-service服务上zuul.routes.users.path=/api-user/**
zuul.routes.users.url=http://user-service.com/
将/api-user/**的请求转发到http://user-service.com/地址上
1.3 如何实现请求过滤
通过继承ZuulFilter实现类,实现抽象方法,定义拦截器,注册到Spring容器达到请求过滤到目的。
public class MyFilter extends ZuulFilter{
@Override
public String filterType() {
// 返回拦截器执行的时期。
// pre路由请求前
// route路由请求时
// post路由请求后
return null;
}
@Override
public int filterOrder() {
// 返回过滤器执行顺序
return 0;
}
@Override
public boolean shouldFilter() {
// 返回过滤器是否生效
return false;
}
@Override
public Object run() {
// 过滤器具体逻辑
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
if(...){ // 条件判断
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
}
return null;
}
}
2 使用Gateway作为API网关
2.1 如何加入Spring Cloud Gateway
加入依赖。关闭网关只要配置spring.cloud.gateway.enabled=false
。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意:Gateway不能与SpringMVC共存。
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or built as a WAR.——SpringCloud参考文档107
2.2 请求转发的匹配条件
Gateway可以通过各种条件将请求转发到合适的处理器,如:请求时间、cookie、请求头、请求的主机、请求方式、请求参数等,详细用法可以查看SpringCloud参考文档。本文讲解以地址作为匹配条件的转发。
下面的配置将/foo/*的请求转发至http://example.org。可以通过配置/foo/**来转发/foo/下的全部请求。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.org
predicates:
- Path=/foo/{segment}
Zuul和Gateway转发不同之处
zuul维护虚拟路径的映射关系作为转发依据,gateway以真实路径作为转发依据。
假如:service-user存在一个访问路径是http://uip:uport/ucp/user/{id}
的请求。(uip、uport、ucp分别代表user服务的地址、端口、上下文地址,下面类似)
下面的配置,将/zcp/user-api/**的请求映射到service-user/**,即:http://zip:zport/zcp/user-api/ucp/user/{id}
等效实际请求地址,实际访问路径会受到路由的上下文路径和映射路径影响。
server:
servlet:
context-path: /zcp
zuul:
routes:
produce:
path: /user-api/**
serviceId: service-user
gateway需要配置真实路径作为转发依据:/ucp/**
,http://gip:gport/ucp/user/{id}
等效实际请求地址,不会受到路由的上下文地址影响。
server:
servlet:
context-path: /gcp
spring:
cloud:
gateway:
routes:
- id: service-user
uri: lb://service-user
predicates:
- Path=/ucp/**
未完待续