在Spring Boot中实现API网关与路由

大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Spring Boot中实现API网关与路由。API网关是一种用于管理和路由请求的中间层,它可以集中处理认证、路由、负载均衡、缓存等功能。Spring Cloud Gateway是Spring提供的一个功能强大的API网关解决方案。

一、Spring Cloud Gateway简介

Spring Cloud Gateway是一个非阻塞的API网关,它基于Spring WebFlux构建,支持动态路由、负载均衡、断路器等功能。它的核心功能包括:

  • 路由:将请求路由到目标服务。
  • 过滤器:在请求和响应过程中进行处理。
  • 负载均衡:将请求均匀分配到多个实例。
  • 断路器:保护系统免受故障蔓延。

二、集成Spring Cloud Gateway

  1. 添加依赖
    首先,在pom.xml中添加Spring Cloud Gateway的依赖:
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

确保在pom.xml中添加了Spring Cloud的版本管理:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  1. 配置网关
    在Spring Boot应用的配置文件application.yml中定义路由规则。以下是一个简单的配置示例:
spring:
  cloud:
    gateway:
      routes:
        - id: service1
          uri: http://localhost:8081
          predicates:
            - Path=/service1/**
          filters:
            - StripPrefix=1
        - id: service2
          uri: http://localhost:8082
          predicates:
            - Path=/service2/**
          filters:
            - StripPrefix=1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

在这个配置中,我们定义了两个路由:

  • service1:将请求转发到http://localhost:8081,路径前缀/service1将被移除。
  • service2:将请求转发到http://localhost:8082,路径前缀/service2将被移除。
  1. 主应用类
    在主应用类上添加@EnableGateway注解(通常,spring-boot-starter-gateway自动启用,无需额外注解):
package cn.juwatech.gatewaydemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayDemoApplication.class, args);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

三、创建示例服务

为了测试API网关的路由功能,我们需要创建两个简单的服务应用。

  1. Service1
package cn.juwatech.service1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class Service1Application {
    public static void main(String[] args) {
        SpringApplication.run(Service1Application.class, args);
    }
}

@RestController
class Service1Controller {
    @GetMapping("/greet")
    public String greet() {
        return "Hello from Service1!";
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  1. Service2
package cn.juwatech.service2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class Service2Application {
    public static void main(String[] args) {
        SpringApplication.run(Service2Application.class, args);
    }
}

@RestController
class Service2Controller {
    @GetMapping("/greet")
    public String greet() {
        return "Hello from Service2!";
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

四、定义自定义过滤器

Spring Cloud Gateway允许我们定义自定义过滤器,用于在请求和响应过程中插入自定义逻辑。以下是一个自定义过滤器的示例:

  1. 创建过滤器
package cn.juwatech.gatewaydemo.filters;

import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Mono;

@Component
public class CustomFilter implements GatewayFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("Custom filter: Request Path - " + exchange.getRequest().getPath());
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            System.out.println("Custom filter: Response Status - " + exchange.getResponse().getStatusCode());
        }));
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

注册自定义过滤器:

package cn.juwatech.gatewaydemo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import cn.juwatech.gatewaydemo.filters.CustomFilter;

@Configuration
public class GatewayConfig {
    @Bean
    public GatewayFilter customFilter() {
        return new CustomFilter();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

五、负载均衡

Spring Cloud Gateway可以与Spring Cloud LoadBalancer结合使用,以实现客户端负载均衡。添加Spring Cloud LoadBalancer的依赖:

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

在网关配置中,使用服务名进行路由:

spring:
  cloud:
    gateway:
      routes:
        - id: loadBalancedService
          uri: lb://SERVICE-NAME
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

在这里,lb://SERVICE-NAME表示负载均衡的服务名。

六、实现断路器

Spring Cloud Gateway支持断路器功能,通过Resilience4jHystrix库实现。在pom.xml中添加Resilience4j的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.

在配置文件中启用断路器:

spring:
  cloud:
    gateway:
      routes:
        - id: serviceWithCircuitBreaker
          uri: http://localhost:8081
          predicates:
            - Path=/service/**
          filters:
            - CircuitBreaker=cb
            - StripPrefix=1
  resilience4j:
    circuitbreaker:
      instances:
        cb:
          registerHealthIndicator: true
          failureRateThreshold: 50
          waitDurationInOpenState: 10000
          slidingWindowSize: 100
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

七、总结

在Spring Boot中实现API网关与路由,可以有效地集中管理服务的请求路由、过滤、负载均衡及断路器等功能。Spring Cloud Gateway提供了灵活的路由配置、丰富的过滤器机制,并且与Spring Cloud LoadBalancer、Resilience4j等技术无缝集成,帮助构建健壮的微服务架构。