简介
Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用。
网关常见的功能有
- 协议转换,路由转发
- 流量聚合,对流量进行监控,日志输出
- 可以在网关层做权限的判断
- 限流,作为整个系统的前端工程,对流量进行控制
- 作为系统的前端边界,外部流量只能通过网关才能访问系统
- 缓存
如上图所示,客户端向Spring Cloud Gateway发出请求。 如果Gateway Handler Mapping确定请求与路由匹配(这个时候就用到predicate),则将其发送到Gateway web handler处理。 Gateway web handler处理请求时会经过一系列的过滤器链。 过滤器链被虚线划分的原因是过滤器链可以在发送代理请求之前或之后执行过滤逻辑。 先执行所有“pre”过滤器逻辑,然后进行代理请求。 在发出代理请求之后,收到代理服务的响应之后执行“post”过滤器逻辑。这跟zuul的处理过程很类似。在执行所有“pre”过滤器逻辑时,往往进行了鉴权、限流、日志输出等功能,以及请求头的更改、协议的转换;转发之后收到响应之后,会执行所有“post”过滤器的逻辑,在这里可以响应数据进行了修改,比如响应头、协议的转换等。
增新一个项目 分别是服务提供方provider,消费方comsumer,注册中心eureka,网关gateway
provider
@RequestMapping("/hello")
@RestController
public class HelloController {
@GetMapping("")
public String hello(@RequestParam String name) {
return "Hello, " + name + "!";
}
}
comsumer
使用Feign调用
@CommonsLog
@RequestMapping("/hello")
@RestController
public class HelloController {
@Autowired
HelloFeignService helloRemote;
@GetMapping("/{name}")
public String index(@PathVariable("name") String name) {
log.info("the name is " + name);
return helloRemote.hello(name) + "\n" + new Date().toString();
}
}
增加 Hystrix 断路器
@FeignClient(name = "producer", fallback = HelloFeignProviderHystrix.class)
public interface HelloFeignService {
/**
* @param name
* @return
*/
@GetMapping("/hello/")
String hello(@RequestParam(value = "name") String name);
}
gateway
Spring Cloud gateway内置了很多校验条件谓语(predicate)来实现路由功能。
有两种方式配置,一种是配置文件application的方式,一种是代码配置
a.application配置:
spring:
application:
name: sc-gateway-server
cloud:
gateway:
discovery:
locator:
# 是否可以通过其他服务的serviceId来转发到具体的服务实例。默认为false
# 为true,自动创建路由,路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问
enabled: true
routes:
- id: host_route
uri: http://httpbin.org:80/get
predicates:
- Host=**.csdn.** # 请求域名携带csdn的,则转发
- id: query_route
uri: http://httpbin.org:80/get
predicates:
- Query=username, zzz* # 请求参数含有username,且值满足zzz开头的,则转发(对值的匹配可以省略)
- id: header_route
uri: http://httpbin.org:80/get
predicates:
- Header=request, \d+ # 如果请求头含有request,且为数字,则转发
b.代码配置
gateway也提供了代码的方式配置,比如我们注释掉上面的application配置,然后建一个配置类
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/fluent/**")
.uri("http://httpbin.org:80/get"))
.build();
}
}
在上面的代码中,我们使用了一个router,该router使用host去断言请求是否进入该路由,当请求的host有“/fluent/**”,都会进入该router,重定向到了“http://httpbin.org:80/get”。
Spring Cloud Gateway内置了许多Predict,这些Predict的源码在org.springframework.cloud.gateway.handler.predicate包中。
列举各种Predicate如下图:
启动项目
输入URL 可以看到转到了 comsumer 的地址返回了provider的内容