Spring Cloud Gateway 基础使用

迷南。 2021-11-17 10:31 332阅读 0赞

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

项目结构


























项目 端口 描述
eureka-server 8761 服务的注册与发现
service-one 8081 服务
gateway-client 8080 网关 gateway

eureka-server

eureka-server项目非常简单 引入

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  4. </dependency>

启动类里面

  1. @EnableEurekaServer
  2. @SpringBootApplication
  3. public class EurekaServerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EurekaServerApplication.class, args);
  6. }
  7. }

配置文件

  1. spring:
  2. application:
  3. name: eureka-server
  4. server:
  5. port: 8761
  6. eureka:
  7. instance:
  8. hostname: localhostname
  9. client:
  10. fetch-registry: false
  11. register-with-eureka: false
  12. service-url:
  13. defaultZone: http://localhost:8761/eureka/

service-one 项目

搭建非常简单,添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  8. </dependency>

启动类里面

  1. @EnableEurekaClient
  2. @SpringBootApplication
  3. public class ServiceOneApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ServiceOneApplication.class, args);
  6. }
  7. }

配置文件

  1. spring:
  2. application:
  3. name: service-one
  4. server:
  5. port: 8081
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://localhost:8761/eureka/

创建类控制器 UserController,http://localhost:8081/user/who

  1. @RequestMapping("/user")
  2. @RestController
  3. public class UserController {
  4. @RequestMapping("who")
  5. public String who() {
  6. return "my name is liangwang";
  7. }
  8. }

创建类控制器OrderController,http://localhost:8081/order/info

  1. @RequestMapping("/order")
  2. @RestController
  3. public class OrderController {
  4. @RequestMapping("/info")
  5. public String orderInfo() {
  6. return "order info date : " + new Date().toString();
  7. }
  8. }

gateway-client项目

使用的是Finchley.SR2版本的,其中已经包含了 spring-boot-starter-webflux
添加依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-gateway</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  8. </dependency>

使用RouteLocator的Bean进行路由转发,将请求进行处理,最后转发到目标的下游服务

  1. @SpringBootApplication
  2. public class GatewayClientApplication {
  3. @Value("${test.uri}")
  4. private String uri;
  5. @Bean
  6. public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
  7. return builder.routes()
  8. //basic proxy
  9. .route(r -> r.path("/order/**")
  10. .uri(uri)
  11. ).build();
  12. }
  13. public static void main(String[] args) {
  14. SpringApplication.run(GatewayClientApplication.class, args);
  15. }
  16. }

上面的代码里是在访问http://localhost:8080/order/的时候,网关转发到http://service-one:8081/order/,service-one服务在eureka中有注册,最终是对应服务的ip:port

使用配置文件
application.yml

  1. test:
  2. uri: lb://service-one
  3. spring:
  4. application:
  5. name: gateway-client
  6. cloud:
  7. gateway:
  8. routes:
  9. - id: route_service_one
  10. uri: ${test.uri} # uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称
  11. predicates:
  12. - Path=/user/**
  13. server:
  14. port: 8080
  15. logging:
  16. level:
  17. org.springframework.cloud.gateway: TRACE
  18. org.springframework.http.server.reactive: DEBUG
  19. org.springframework.web.reactive: DEBUG
  20. reactor.ipc.netty: DEBUG
  21. eureka:
  22. client:
  23. service-url:
  24. defaultZone: http://localhost:8761/eureka/
  25. instance:
  26. prefer-ip-address: true

其中test.uri是我自定义的属性,uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称,按照上面的配置是http://localhost:8080/usr/** => http://service-one:8081/user/** 到此项目搭建完成,接下来测试了,依次启动eureka-server、service-one、gateway-client
访问

  • http://localhost:8080/user/who
  • http://localhost:8080/order/info

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LTk1OWU1NWY2YTliN2EzYzEucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy85NDQvZm9ybWF0L3dlYnA

WX20181113-180248@2x.png

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LTY3N2FjMzdlNmFlZGVmNmMucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy83MzYvZm9ybWF0L3dlYnA

WX20181113-180339@2x.png

不启用注册中心

即使集成了eureka-client也不想使用注册中心服务,可以关闭

  1. eureka.client.enabled=false

StripPrefix属性的使用

按照上面的配置,每一个路由只能对应一个控制器的转发,不够灵活,假如我想让userapi的请求都转到service-one服务,比如:

  • http://localhost:8080/userapi/user/who => http://localhost:8081/user/who
  • http://localhost:8080/userapi/order/info => http://localhost:8081/order/info
    在路由配置上增加 StripPrefix=1

    spring:
    application:

    1. name: gateway-client

    cloud:

    1. gateway:
    2. routes:
    3. - id: route_service_one
    4. uri: ${test.uri} # uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称
    5. predicates:
    6. - Path=/userapi/**
    7. filters:
    8. - StripPrefix=1 # 表示在转发时去掉userapi

修改完配置,重启gateway-client项目:

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LTdmNDdkNjY1MDk4ZTg5MjAucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy84MzYvZm9ybWF0L3dlYnA

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LTI2ZDA4YzUwZTZkMWU0YzQucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy83MjYvZm9ybWF0L3dlYnA

使用Hystrix

在gateway-client项目中引入依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  4. </dependency>

在spring cloud gateway中可以使用Hystrix。Hystrix是 spring cloud中一个服务熔断降级的组件,在微服务系统有着十分重要的作用。
Hystrix是 spring cloud gateway中是以filter的形式使用的,代码如下:

  1. @SpringBootApplication
  2. public class GatewayClientApplication {
  3. @Value("${test.uri}")
  4. private String uri;
  5. @Bean
  6. public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
  7. return builder.routes()
  8. //basic proxy
  9. .route(r -> r.path("/order/**")
  10. .uri(uri)
  11. )
  12. .route(r -> r.path("/user/**")
  13. .filters(f -> f
  14. .hystrix(config -> config
  15. .setName("myserviceOne")
  16. .setFallbackUri("forward:/user/fallback")))
  17. .uri(uri)).build();
  18. }
  19. public static void main(String[] args) {
  20. SpringApplication.run(GatewayClientApplication.class, args);
  21. }
  22. }

上面代码中添加了一个路由并配置了hystrix的fallbackUri,新添加一个FallBackController控制器

  1. @RestController
  2. public class FallBackController {
  3. @RequestMapping("/user/fallback")
  4. public Mono<String> fallback() {
  5. return Mono.just("service error, jump fallback");
  6. }
  7. }

重启gateway-client项目,并关闭service-one服务,在浏览器访问 http://localhost:8080/user/who

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LWUzZjFlZDUxMTYyNWU2OGIucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy82NjAvZm9ybWF0L3dlYnA

使用yml配置Hystrix

  1. spring:
  2. application:
  3. name: gateway-client
  4. cloud:
  5. gateway:
  6. routes:
  7. - id: route_service_one
  8. uri: ${test.uri} # uri以lb://开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称
  9. predicates:
  10. - Path=/userapi/**
  11. filters:
  12. - StripPrefix=1 # 表示在转发时去掉userapi
  13. - id: userapi2_route
  14. uri: ${test.uri}
  15. predicates:
  16. - Path=/userapi2/**
  17. filters:
  18. - StripPrefix=1
  19. - name: Hystrix
  20. args:
  21. name: myfallbackcmd
  22. fallbackUri: forward:/user/fallback

在配置中增加了一个新的路由userapi2_route,还配置了Hystrix,当发生错误时会转发到fallbackUri,测试访问 http://localhost:8080/userapi2/order/info

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8yMTUxOTA1LWU2ZTk4MmZjMTljODUxMjQucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXAlN0NpbWFnZVZpZXcyLzIvdy83NjIvZm9ybWF0L3dlYnA

发表评论

表情:
评论列表 (有 0 条评论,332人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring Cloud -- GateWay

    1. 为什么需要网关 > 在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务

    相关 Spring cloud gateway

    网关核心功能是路由转发,因此不要有耗时操作在网关上处理,让请求快速转发到后端服务上。 早期的cloud中使用的是基于Zuul的网关,但是由于Zuul1.x是阻塞的,后面clo