Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关.网关常见的功能有路由转发、权限校验、限流控制等作用.
Nacos 是阿里开源的一款 配制和注册中心,目前已经适配了spring cloud(Spring Cloud Alibaba), 与 dubbo 的适配也在进行中.
之前使用 zuul 的时候, 发现默认情况下 RequestHeaders 中的 Authorization 参数被zuul过滤了, 导致被代理的服务拿不到token,需要经过配制才能传递到服务中. 经过测试,Spring Cloud Gateway 在默认情况下没有此问题.
阅读本篇,需要你提前了解并做好:
- spring boot 和 spring cloud 相信因为标题进来的你已经了解并应用了
- 下载安装并启动 Nacos, nacos 快速入门
- 将服务注册中心替换为 Nacos, 可以参考 Nacos与Spring Cloud快速入门
- spring boot 使用 2.0.x, 不要使用 2.1.x, 因为 Nacos 的相关库还没有适配 2.1.x ,会有问题(比如服务注册不上)
- spring cloud 使用 Finchley.SR1 或者 Finchley.SR2
pom 引入:
~~~
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- nacos 的服务注册与发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- hystrix 熔断器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
~~~
application.yml
server:
port: 80
spring:
application:
name: gateway-server
cloud:
nacos:
discovery:
serverAddr: 127.0.0.1:8848
启动器和简单路由+Hystrix熔断降级
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@EnableDiscoveryClient // 启用服务注册和发现
@RestController // 提供一个简单的降级页面
public class GatewayServerApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServerApplication.class);
}
/**
* @Title: fallback
* @Description: 一个简单的降级页面
* @return
*/
@RequestMapping("/fallback")
public Mono<String> fallback() {
// Mono是一个Reactive stream,对外输出一个“fallback”字符串。
return Mono.just("fallback");
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
// 配制一个路由,把 http://网关地址:网关端口/demo/ 下的请求路由到 demo-service 微服务中
.route(p -> p
.path("/demo/**")
.filters(f -> f
.hystrix(config -> config // 对path()指定的请求使用熔断器
.setName("mycmd") // 熔断器的名字
.setFallbackUri("forward:/fallback"))) // 熔断到 /fallback, 就是上面配制的那个
.uri("lb://demo-service")) // 将请求路由到指定目标, lb开头是注册中心中的服务, http/https 开头你懂的
.build();
}
}
到这里就结束了,可以愉快的启动网关并测试了
【注意】:
这里说一下 Spring Cloud Gateway 与 zuul 的代理的地址有点不一样
zuul 中, 例如我们配制的是 把 /demo/** 路由到 http://服务/, 则网关的请求地址: http://网关/demo/xx/abc.do 实际请求的服务地址为: http://服务/xx/abc.do, zuul自动把 /demo 去掉了.而 Spring Cloud Gateway 不是这样:在Spring Cloud Gateway中,上面的实际请求的服务地址为: http://服务/demo/xx/abc.do ,Spring Cloud Gateway不会把 /demo 去掉,与请求的地址一样