Spring Cloud Gateway 服务网关详解

Java服务端服务网关:Kong与Spring Cloud Gateway的比较 Kong是一个基于OpenResty和Nginx的高性能、可扩展、云原生服务网关。它提供了丰富的插件系统,支持动态路由、认证、限流等。Spring Cloud Gateway是基于Spring生态系统和WebFlux框架构建的反应式网关,它支持非阻塞I/O和事件驱动,提供了声明式的路由规则。Kong和Spring Cloud Gateway都是优秀的服务网关,适用于不同的场景和需求。Kong以其高性能和丰富的插件系统适合于大规模和复杂的微服务架构。 阅读详情

一、Gateway 介绍

1. 为什么要使用 Gateway?(重点)

vue
  |
gateway------->问题:①ip和port硬编码 ②无法负载均衡
  |
|-微服务1-|  |-微服务2-|  |-微服务3-|... ...
|-微服务1-|
|-微服务1-|
   .
   .
   .

解决的问题:

  • 解耦前端与后端:前端无需知道后端服务的具体地址

  • 动态路由:通过服务名实现路由,无需硬编码 IP 和端口

  • 负载均衡:内置 Ribbon 实现客户端负载均衡

  • 统一入口:为所有微服务提供单一入口点

  • 安全控制:统一认证、授权、限流等

2. 什么是 Gateway?

Gateway 是 Spring Cloud 官方基于 WebFlux(Reactor 响应式编程模型)开发的网关组件,用于替代 Zuul。

主要功能:

  • 路由:将请求路由到对应的微服务

  • 过滤:对请求和响应进行预处理和后处理

  • 限流:防止系统被过多请求压垮

  • 熔断:服务降级和熔断保护

3. Gateway 的启动器

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

注意:​ 不要添加 spring-boot-starter-web依赖,因为 Gateway 基于 WebFlux 而非 Servlet。


二、Gateway 工程搭建

1. pom.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
    </properties>
    
    <dependencies>
        <!-- Gateway 核心依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        
        <!-- Nacos 服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        
        <!-- 配置管理 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        
        <!-- 健康检查 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2. application.yml 配置

server:
  port: 8888  # Gateway 服务端口

spring:
  application:
    name: api-gateway  # 服务名称
  
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.61.132:8848  # Nacos 服务地址
        namespace: public
        group: DEFAULT_GROUP
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        file-extension: yaml
    
    gateway:
      discovery:
        locator:
          enabled: true  # 开启从注册中心动态创建路由
          lower-case-service-id: true  # 服务名小写
      
      # 全局跨域配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origins: "*"
            allowed-headers: "*"
            allowed-methods:
              - GET
              - POST
              - PUT
              - DELETE
              - OPTIONS
            allow-credentials: true
            max-age: 3600
      
      # 路由配置
      routes:
        - id: sentinel-consumer
          uri: lb://sentinel-consumer
          predicates:
            - Path=/consumer/**
          filters:
            - StripPrefix=1
        
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix=1

# 日志配置
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    reactor.netty.http.client: DEBUG

# 健康检查端点
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

3. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

三、路由配置

1. 内置断言工厂

Gateway 提供了多种内置的断言工厂,用于匹配 HTTP 请求的不同属性:

spring:
  cloud:
    gateway:
      routes:
        - id: sentinel-consumer
          uri: lb://sentinel-consumer  # 从 Nacos 获取服务列表
          predicates:  # 断言:只有所有条件都为 true 时才进行路由
            - Path=/consumer/**  # 路径匹配
            - After=2022-04-09T13:20:54.957+08:00[Asia/Shanghai]  # 时间之后
            - Before=2023-12-31T23:59:59.999+08:00[Asia/Shanghai]  # 时间之前
            - Between=2022-01-01T00:00:00.000+08:00[Asia/Shanghai],2022-12-31T23:59:59.999+08:00[Asia/Shanghai]
            - Cookie=sessionId, test  # Cookie 匹配
            - Header=X-Request-Id, \d+  # 请求头匹配
            - Host=**.example.com  # 主机名匹配
            - Method=GET,POST  # 请求方法匹配
            - Query=name, zhangsan  # 查询参数匹配
            - RemoteAddr=192.168.1.1/24  # 远程地址匹配

2. 自定义断言工厂

2.1 创建断言工厂
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

@Component
public class AgeRoutePredicateFactory 
        extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {
    
    public AgeRoutePredicateFactory() {
        super(Config.class);
    }
    
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("minAge", "maxAge");
    }
    
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            // 从请求头获取年龄
            String ageStr = exchange.getRequest().getHeaders().getFirst("Age");
            if (ageStr == null) {
                return false;
            }
            
            try {
                int age = Integer.parseInt(ageStr);
                return age >= config.minAge && age <= config.maxAge;
            } catch (NumberFormatException e) {
                return false;
            }
        };
    }
    
    @Validated
    public static class Config {
        @NotNull
        private Integer minAge;
        
        @NotNull
        private Integer maxAge;
        
        public Integer getMinAge() {
            return minAge;
        }
        
        public void setMinAge(Integer minAge) {
            this.minAge = minAge;
        }
        
        public Integer getMaxAge() {
            return maxAge;
        }
        
        public void setMaxAge(Integer maxAge) {
            this.maxAge = maxAge;
        }
    }
}
2.2 使用自定义断言工厂
spring:
  cloud:
    gateway:
      routes:
        - id: age-restricted-route
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
            - Age=18,60  # 使用自定义断言工厂,年龄在18-60之间

四、过滤器配置

1. 内置过滤器工厂

Gateway 提供了丰富的内置过滤器:

spring:
  cloud:
    gateway:
      routes:
        - id: sentinel-consumer
          uri: lb://sentinel-consumer
          predicates:
            - Path=/sentinel-consumer/**
          filters:
            - StripPrefix=1  # 去除路径前缀
            - AddRequestHeader=X-Request-color, blue  # 添加请求头
            - AddRequestParameter=color, blue  # 添加请求参数
            - AddResponseHeader=X-Response-color, blue  # 添加响应头
            - PrefixPath=/api  # 添加路径前缀
            - SetPath=/api/{segment}  # 设置路径
            - SetStatus=401  # 设置状态码
            - RedirectTo=302, https://example.com  # 重定向
            - RemoveRequestHeader=X-Request-Foo  # 移除请求头
            - RemoveResponseHeader=X-Response-Foo  # 移除响应头
            - RewritePath=/red/(?<segment>.*), /$\{segment}  # 重写路径
            - Retry=3  # 重试3次
            - RequestSize=5000000  # 请求大小限制(5MB)
            - RequestRateLimiter=#{@myRateLimiter}  # 限流

2. 自定义过滤器工厂

2.1 创建过滤器工厂
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Component
public class LogGatewayFilterFactory 
        extends AbstractGatewayFilterFactory<LogGatewayFilterFactory.Config> {
    
    public LogGatewayFilterFactory() {
        super(Config.class);
    }
    
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }
    
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            if (config.isEnabled()) {
                ServerHttpRequest request = exchange.getRequest();
                
                // 记录请求信息
                System.out.println("======================================");
                System.out.println("请求路径: " + request.getURI().getPath());
                System.out.println("请求方法: " + request.getMethod());
                System.out.println("请求参数: " + request.getQueryParams());
                System.out.println("请求头: " + request.getHeaders());
                System.out.println("======================================");
                
                // 在请求头中添加日志标识
                ServerHttpRequest modifiedRequest = request.mutate()
                    .header("X-Log-Enabled", "true")
                    .build();
                
                return chain.filter(exchange.mutate().request(modifiedRequest).build())
                    .then(Mono.fromRunnable(() -> {
                        // 记录响应信息
                        System.out.println("响应状态码: " + 
                            exchange.getResponse().getStatusCode());
                    }));
            }
            
            return chain.filter(exchange);
        };
    }
    
    public static class Config {
        private boolean enabled = false;
        
        public boolean isEnabled() {
            return enabled;
        }
        
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}
2.2 使用自定义过滤器工厂
spring:
  cloud:
    gateway:
      routes:
        - id: logging-route
          uri: lb://sentinel-consumer
          predicates:
            - Path=/sentinel-consumer/**
          filters:
            - StripPrefix=1
            - Log=true  # 启用日志过滤器

3. 自定义全局过滤器

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class GlobalLoginFilter implements GlobalFilter, Ordered {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        
        // 获取请求路径
        String path = request.getURI().getPath();
        
        // 排除登录接口和公开接口
        if (path.contains("/auth/login") || 
            path.contains("/auth/register") ||
            path.contains("/public/")) {
            return chain.filter(exchange);
        }
        
        // 从请求头中获取token
        String token = request.getHeaders().getFirst("Authorization");
        
        if (!StringUtils.hasText(token)) {
            // 从查询参数中获取token
            token = request.getQueryParams().getFirst("token");
        }
        
        // token为空,返回未授权
        if (!StringUtils.hasText(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            
            String message = "{\"code\":401,\"message\":\"未授权访问,请先登录\"}";
            DataBuffer buffer = response.bufferFactory()
                .wrap(message.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(buffer));
        }
        
        // 验证token(这里简化处理,实际应该调用认证服务)
        if (!isValidToken(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            
            String message = "{\"code\":401,\"message\":\"Token无效或已过期\"}";
            DataBuffer buffer = response.bufferFactory()
                .wrap(message.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(buffer));
        }
        
        // 将用户信息添加到请求头中
        ServerHttpRequest newRequest = request.mutate()
            .header("X-User-Id", extractUserIdFromToken(token))
            .header("X-User-Name", extractUsernameFromToken(token))
            .build();
        
        return chain.filter(exchange.mutate().request(newRequest).build());
    }
    
    @Override
    public int getOrder() {
        return 0;  // 执行顺序,值越小优先级越高
    }
    
    private boolean isValidToken(String token) {
        // 这里应该调用认证服务验证token
        // 简化处理,假设以"Bearer "开头的token为有效
        return token.startsWith("Bearer ");
    }
    
    private String extractUserIdFromToken(String token) {
        // 从token中提取用户ID
        // 简化处理,返回固定值
        return "123";
    }
    
    private String extractUsernameFromToken(String token) {
        // 从token中提取用户名
        // 简化处理,返回固定值
        return "admin";
    }
}

五、高级配置

1. 统一异常处理

import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
    
    public GlobalErrorWebExceptionHandler(ErrorAttributes errorAttributes,
                                         WebProperties.Resources resources,
                                         ApplicationContext applicationContext,
                                         ServerCodecConfigurer configurer) {
        super(errorAttributes, resources, applicationContext);
        this.setMessageWriters(configurer.getWriters());
        this.setMessageReaders(configurer.getReaders());
    }
    
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }
    
    private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
        Map<String, Object> errorPropertiesMap = getErrorAttributes(request, false);
        
        int status = (int) errorPropertiesMap.getOrDefault("status", 500);
        String message = (String) errorPropertiesMap.getOrDefault("message", "Internal Server Error");
        String path = (String) errorPropertiesMap.get("path");
        
        Map<String, Object> result = new HashMap<>();
        result.put("code", status);
        result.put("message", message);
        result.put("path", path);
        result.put("timestamp", System.currentTimeMillis());
        
        return ServerResponse
            .status(HttpStatus.valueOf(status))
            .contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromValue(result));
    }
}

2. 限流配置

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

@Configuration
public class RateLimiterConfig {
    
    /**
     * 根据IP进行限流
     */
    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
        );
    }
    
    /**
     * 根据用户ID进行限流
     */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getHeaders().getFirst("X-User-Id")
        );
    }
    
    /**
     * 根据接口进行限流
     */
    @Bean
    public KeyResolver apiKeyResolver() {
        return exchange -> Mono.just(
            exchange.getRequest().getURI().getPath()
        );
    }
}

3. 配置文件 application-gateway.yml

spring:
  cloud:
    gateway:
      # 默认过滤器配置
      default-filters:
        - AddRequestHeader=X-Request-Gateway, api-gateway
        - AddResponseHeader=X-Response-Gateway, api-gateway
      
      # 路由配置
      routes:
        # 用户服务路由
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user-service/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@ipKeyResolver}"
                redis-rate-limiter.replenishRate: 10  # 每秒令牌数
                redis-rate-limiter.burstCapacity: 20  # 令牌桶容量
          
        # 订单服务路由
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order-service/**
          filters:
            - StripPrefix=1
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback/order-service
          
        # 商品服务路由
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/product-service/**
          filters:
            - StripPrefix=1
            
        # 认证服务路由
        - id: auth-service
          uri: lb://auth-service
          predicates:
            - Path=/auth/**
          filters:
            - StripPrefix=0
      
      # 熔断降级配置
      hystrix:
        command:
          fallbackcmd:
            execution:
              isolation:
                thread:
                  timeoutInMilliseconds: 5000
      
      # 重试配置
      retry:
        retries: 3
        series: SERVER_ERROR
        methods: GET,POST
        exceptions: java.io.IOException, java.util.concurrent.TimeoutException

六、监控和日志

1. 集成 Spring Boot Admin

<!-- 在pom.xml中添加 -->
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.7.0</version>
</dependency>

2. 配置监控端点

management:
  endpoints:
    web:
      exposure:
        include: "*"
      cors:
        allowed-origins: "*"
        allowed-methods: GET,POST
  endpoint:
    health:
      show-details: always
    gateway:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: ${spring.application.name}

3. 日志配置

logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  level:
    root: INFO
    org.springframework.cloud.gateway: DEBUG
    org.springframework.web: DEBUG
    reactor.netty: DEBUG
  file:
    name: logs/gateway.log
    max-size: 10MB
    max-history: 30

七、最佳实践

1. 生产环境建议

  • 使用配置中心(Nacos Config)管理路由配置

  • 启用熔断和降级机制

  • 配置合理的限流策略

  • 开启请求日志和监控

  • 使用HTTPS确保通信安全

  • 配置合理的超时时间

2. 性能优化

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s
        pool:
          type: elastic
          max-idle-time: 60s
          max-life-time: 60s
      metrics:
        enabled: true

3. 安全配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
            .csrf().disable()
            .authorizeExchange()
                .pathMatchers("/auth/**", "/public/**").permitAll()
                .anyExchange().authenticated()
            .and()
            .oauth2ResourceServer()
                .jwt()
            .and()
            .build();
    }
}

总结

Spring Cloud Gateway 作为微服务架构的入口,提供了强大的路由、过滤、限流等功能。通过合理的配置和使用,可以构建出高性能、高可用的API网关。在实际项目中,需要根据具体业务需求选择合适的配置方案,并注意监控和安全防护。

这份笔记涵盖了Gateway的核心概念、配置方法和最佳实践,适合在优快云等技术平台分享。

SpringCloud之网关Gateway 2、基本搭建4.0.0com.gatewaycode0.0.1-SNAPSHOTgatewayDemo 阅读详情

相关推荐

SpringCloud中的gateWay (网关)

一、网关基本概念 1、API网关介绍 2、Spring Cloud Gateway 3、Spring Cloud Gateway核心概念 二、创建api-gateway模块(网关服务) 1、在创建api_gateway网关模块(springboot) 注意:很重要 所有服务,都需要在nacos中注册服务 ** 2、在pom.xml引入依赖 注意版本号 <dependencies> <!--服务注册nacos--> <dependency>

yuzheh521的博客 5304

Spring Cloud Gateway

在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题,例如:客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性认证复杂,每个微服务都有独立认证存在跨域请求,在一定场景下处理相对复杂为解决上面的问题所以引入了网关的概念:所谓的API网关,就是指系统的统一入口。

杀神lwz的博客 2万+

SpringCloud_Gateway服务网关

在gateway9527服务的com.zzx.config包下,创建日志网关过滤器类LogGatewayFilterFactory/*** 日志网关过滤器} /*** 表示配置填写顺序* @return} /*** 执行过滤的逻辑* @returnlog . info("********* consoleLog日志 开启 ********");});} /*** 过滤器使用的配置内容} }/*** 日志网关过滤器} /**

weixin_49076273的博客 4037

SpringCloud gateway (史上最全)

前言 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家介绍三个版本的 高并发秒杀: 一、版本1 :springcloud + zookeeper 秒杀 二、版本2 :springcloud + redis 分布式锁秒杀 三、版本3 :springcloud + Nginx + Lua 高性能版本秒杀 以及有关Springcloud 几篇核心、重要的文章: 一、Springcloud 配置, 史上最全 一文全懂 二、Springcloud 中 Sprin

骏马逸动,心随你动的博客 3万+

服务网关Spring Cloud Gateway

简介 predicate filter 限流 配合注册中心路由转发 使用 Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。 简介 作用 协议转换,路由转发 流量聚合,对流量进行监控,日志输出 作为整个系统的前端工程,对流量进行控制,有限流的作用 作为系统的前端边界,外部流量只能通过网关才能访问系统 可以在网关层做权限的判断 可以在网关层做缓存 .

Hello World 847

Spring Cloud Gateway 服务网关的部署与使用详细介绍

通过前面的测试可以看到一个现象一旦路由的微服务下线或者失联了,SpringCloudGateway直接返回了一个错误页面,如下图显然这种异常信息不友好,前后端分离架构中必须定制返回的异常信息。传统的SpringBoot服务中都是使用@ControllerAdvice来包装全局异常处理的,但是由于服务下线,请求并没有到达。因此必须在网关中也要定制一层全局异常处理,这样才能更加友好的和客户端交互。/***用于网关的全局异常处理常见的服务器架构入门一致性哈希算法原理详解什么是RPC?...

m0_67392661的博客 228

服务网关之Spring Cloud Gateway

大家都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用 这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调 用。这样的架构,会存在着诸多的问题:客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性认证复杂,每个服务都需要独立认证。存在跨域请求,在一定场景下处理相对复杂。上面的这些问题可以借助API网关来解决。所谓的API网关,就是指系统的统一入口。

weixin_65808248的博客 1832

SpringCloud学习(十)Spring Cloud Gateway服务网关

在SpringBoot2.x版本后,spring出了自己的Spring Cloud Gateway服务网关以替代停止开发进入维护的以及性能不算很好的Zuul。 (一)创建一个gateway-server服务网关子工程 新建工程后,在pom.xml文件中引入以下依赖: <dependencies> <dependency> <gr...

u013068184的博客 912

学习Spring Cloud之Gateway服务网关

过滤器的作用是什么?① 对路由的请求或响应做加工处理,比如添加请求头② 配置在路由下的过滤器只对当前路由的请求生效defaultFilters的作用是什么?① 对所有路由都生效的过滤器需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:参数中是否有authorization,authorization参数值是否为admin如果同时满足则放行,否则拦截实现:​​@Order(-1)@Component@Override// 1.获取请求参数。

weixin_57670212的博客 995

【云原生】Spring Cloud Alibaba 之 Gateway 服务网关实战开发

Spring Cloud Alibaba Gateway 新一代服务网关 实战开发!

wanghuichen的博客 1万+

波克 上海 Unity开发笔试题 2024

主要分为四部分,如果没有准备好,不要点击笔试链接,进入就会自动开始。

z2014z的博客 3392

【Spring Cloud Netflix】GateWay服务网关

GateWay用于在微服务架构中提供统一的入口点,对请求进行路由,过滤和处理。它就像是整个微服务系统的大门,所有外部请求都要通过它才能访问到后端的各个微服务。

L3526581402的博客 1443

vnpy_ctp源码下载后转变为python可用的处理过程

vnpy_ctp源码下载后在window中编译使用

m0_37967652的博客 3327

【Spring Cloud】Gateway服务网关

`Spring Cloud Gateway` 是 `Spring Cloud` 的一个全新项目,该项目是基于 `Spring 5.0`,`Spring Boot 2.0` 和 `Project Reactor` 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。...

懂得一千零一种,赋予你失败的方法! 1234

BUCK-BOOST升降压电路Multisim电路仿真分析

本文分析了三极管型BUCK-BOOST升降压开关电源的工作原理。该电路结合了BUCK降压和BOOST升压拓扑,通过控制三极管Q1的高频通断,使电感L1周期性储能和释能,实现输出电压可高于或低于输入电压且极性相反。详细阐述了Q1导通和关断阶段的工作过程,推导了输出电压与占空比的关系式Vo=-D/(1-D)*Vi,并分析了不同占空比下的工作模式(降压、升压)。通过Multisim仿真验证了理论分析,当D=25%时输出降压至1.6V,D=60%时输出升压至7.5V。电路具有升降压灵活、极性反转、效率高等特点,适用

XU157303764的博客 1434

基于Python的船舶AIS数据爬取与分析:从数据采集到可视化实战

本文详细介绍了如何使用Python构建一个完整的船舶AIS数据爬取与分析系统。文章从AIS系统的基本原理讲起,逐步深入到数据采集、存储、清洗、分析和可视化的全流程。我们将使用最新的Python技术栈,包括aiohttp异步爬虫、MongoDB存储、Pandas数据处理以及Pydeck三维可视化等。本文提供了完整的代码实现,并探讨了在实际应用中可能遇到的问题及其解决方案。关键词:AIS数据、Python爬虫、异步IO、数据可视化、海事分析。

2201_76125261的博客 811

Spring Cloud Gateway服务网关

大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用 这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的架构,会存在着诸多的问题:客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性认证复杂,每个服务都需要独立认证。存在跨域请求,在一定场景下处理相对复杂。上面的这些问题可以借助API网关来解决。所谓的API网关,就是指系统的统一入口。

JFENG14的博客 1065

996引擎 - 读写变量性能测试

单轮100万次读写,取3轮平均耗时(毫秒),有效读取率均为100%,数值越小性能越优。

灵台方寸山斜月三星洞 244

Spring Cloud Alibaba系列(四)使用gateway作为服务网关

什么是网关 在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个独立部署单元可以用不同的开发测试团队维护,可以使用不同的编程语言和技术平台进行设计,这就要求必须使用一种语言和平台无关的服务协议作为各个单元间的通讯方式。 换句话说就是网关为所有的请求提供了统一的入口,方便我们对服务请求和响应做统一管理。 为什么要用网关 API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST AP

gg7894125的博客 1525

机器学习势能(MLPs) 第一章 基础理论与核心概念 第二章 数据生成与训练集构建

密度泛函理论(DFT)作为现代计算材料科学的基石,通过求解Kohn-Sham方程在电子结构层面提供可靠的势能面信息。然而,其计算复杂度随体系电子数呈O(N3) 至O(N4) 增长,对于包含数百个原子的体系,单点计算往往需消耗数小时至数天的计算资源。这一瓶颈严重限制了分子动力学模拟的时间尺度,传统DFT-MD通常仅能覆盖皮秒量级,远不足以观测扩散、相变等慢动力学过程。经验力场通过解析函数形式描述原子间相互作用,实现了经典力学的计算效率,但其参数化过程高度依赖物理直觉与经验调参。

VectorShift的博客 182

华为OD新系统机试真题-勇攀数字高峰(Java/Py/C/C++/Js/Go)

新系统 华为OD机试新系统【勇登数字高峰】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统机试真题【勇登数字高峰】

qq_45776114的博客 1544

Spring Cloud Gateway 服务网关的部署与使用详细教程

点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 10:33更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 E...

芋艿V 433

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: Sentinel服务保护框架完全指南:从原理到实践
下一篇: IDEA + Git + Gitee 全流程实战:从安装、提交到解决冲突
StackNoOverflow
博客等级 码龄1年 22粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值