Spring cloud gateway自定义filter以及负载均衡

自定义全局filter

package com.example.demo;

import java.nio.charset.StandardCharsets;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
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.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author woniu
 * @date 2019/10/11 16:07
 */
@Component
public class CustomerTokenFilter implements GlobalFilter, Ordered{

    private static final Log log = LogFactory.getLog(GatewayFilter.class);

    private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis());
        log.info("contain token " + exchange.getRequest().getHeaders().containsKey("token"));
        log.info("token is " + exchange.getRequest().getHeaders().get("token"));
        if (exchange.getRequest().getPath().value().contains("success") || exchange.getRequest().getPath().value()
                .contains("rest")) {
            return chain.filter(exchange).then(
                    Mono.fromRunnable(() -> {
                        Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN);
                        if (startTime != null) {
                            log.info(exchange.getRequest().getURI().getRawPath() + ": " + (System.currentTimeMillis() - startTime) + "ms");
                        }
                    })
            );
        } else {
            byte[] bytes =
                    "{\"status\":429,\"msg\":\"Too Many Requests\",\"data\":{}}".getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
            ServerHttpResponse serverHttpResponse = exchange.getResponse();
            serverHttpResponse.setStatusCode(HttpStatus.OK);
            return exchange.getResponse().writeWith(Flux.just(buffer));
        }

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

自定义LoadBalanceRule

package com.example.demo;

import java.util.List;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
/**
 * @author woniu
 * @date 2019/10/12 16:20
 */
public class CustomerLoadBalanceRule extends AbstractLoadBalancerRule {

    private static final Log log = LogFactory.getLog(CustomerLoadBalanceRule.class);

    @Override
    public Server choose(Object key) {
        log.info("key is " + key);
        List<Server> servers = this.getLoadBalancer().getReachableServers();
        log.info("servers " + servers);
        if (servers.isEmpty()) {
            return null;
        }
        if (servers.size() == 1) {
            return servers.get(0);
        }
        return randomChoose(servers);
    }
    /**
     *
     * <p>随机返回一个服务实例 </p>
     * @param servers 服务列表
     */
    private Server randomChoose(List<Server> servers) {
        int randomIndex = RandomUtils.nextInt(servers.size());
        return servers.get(randomIndex);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}

application.properties 配置

logging.level.org.springframework.cloud.gateway: TRACE
logging.level.org.springframework.http.server.reactive: TRACE
logging.level.org.springframework.web.reactive: TRACE
logging.level.org.springframework.boot.autoconfigure.web: TRACE

spring.cloud.gateway.routes[0].id: 1bcd
spring.cloud.gateway.routes[0].uri:  lb://my-load-balanced-service
spring.cloud.gateway.routes[0].predicates[0].name: Path
spring.cloud.gateway.routes[0].predicates[0].args[0]: /rest/**

my-load-balanced-service.ribbon.listOfServers: http://woniu.com
my-load-balanced-service.ribbon.NFLoadBalancerRuleClassName: com.example.demo.CustomerLoadBalanceRule

pom.xml引入的dependency

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>

githup地址:https://github.com/baishi6582/wns/tree/master/springgatewaydemo

原文地址:https://www.cnblogs.com/woniu4/p/11663660.html

时间: 2024-08-29 21:44:58

Spring cloud gateway自定义filter以及负载均衡的相关文章

spring cloud gateway自定义过滤器

在API网关spring cloud gateway和负载均衡框架ribbon实战文章中,主要实现网关与负载均衡等基本功能,详见代码.本节内容将继续围绕此代码展开,主要讲解spring cloud gateway自定义过滤器的功能.本节内容的代码也会提交到GitHub上,注意提交的内容. 本节主要讲解全局过滤器和局部过滤器.注意下面的示例不能作为生产环境的代码,只是简单的演示自定义过滤器的使用方式,无需纠结实现的功能是否完善.下面主要针对不同的过滤器选择几种场景进行代码演示,不代表某个场景就必须

Spring Cloud:使用Ribbon实现负载均衡详解(下)

在上一篇文章(Spring Cloud:使用Ribbon实现负载均衡详解(上))中,我对 Ribbon 做了一个介绍,Ribbon 可以实现直接通过服务名称对服务进行访问.这一篇文章我详细分析一下如何使用 Ribbon 实现客户端的负载均衡. 1. 使用 Ribbon 实现负载均衡 要实现负载均衡,首先要有多个订单服务提供者,目前我们就一个 microservice-order-provider01,端口号 8001,我们可以仿照这个服务,再创建两个子模块,也是订单服务提供者,取名为 micro

Spring Cloud Ribbon源码分析---负载均衡实现

上一篇结合 Eureka 和 Ribbon 搭建了服务注册中心,利用Ribbon实现了可配置负载均衡的服务调用.这一篇我们来分析Ribbon实现负载均衡的过程. 从 @LoadBalanced入手 还记得前面配置 RestTemplate: @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } 在消费端使用Spring 提供的 RestTemplate 来发出请求,而Ribbon 在 Rest

Spring Cloud Feign服务通信与负载均衡机制

首先要知道一点Feign的负载均衡是Ribbon来实现的. Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单.Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数.格式.地址等信息.而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理.Feign整合了Ribbon和Hystrix(Hystrix熔断保护机制),可以让我们不再需要显式地使用这两个组件. Fe

Spring Cloud Ribbon 源码分析---负载均衡算法

上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* * choose one alive server from lb.allServers or * lb.upServers according to key * * @return choosen Server object. NULL is returned if none * server i

spring cloud gateway获取response body

网关发起请求后,微服务返回的response的值要经过网关才发给客户端.本文主要讲解在spring cloud gateway 的过滤器中获取微服务的返回值,因为很多情况我们需要对这个返回进行处理.网上有很多例子,但是都没有解决我的实际问题,最后研究了下源码找到了解决方案. 本节内容主要从如下几个方面讲解,首先需要了解我的博文的内容:API网关spring cloud gateway和负载均衡框架ribbon实战 和 spring cloud gateway自定义过滤器 本文也将根据上面两个项目

API网关spring cloud gateway和负载均衡框架ribbon实战

通常我们如果有一个服务,会部署到多台服务器上,这些微服务如果都暴露给客户,是非常难以管理的,我们系统需要有一个唯一的出口,API网关是一个服务,是系统的唯一出口.API网关封装了系统内部的微服务,为客户端提供一个定制的API.客户端只需要调用网关接口,就可以调用到实际的微服务,实际的服务对客户不可见,并且容易扩展服务. API网关可以结合ribbon完成负载均衡的功能,可以自动检查微服务的状况,及时剔除或者加入某个微服务到可用服务列表.此外网关可以完成权限检查.限流.统计等功能.下面我们将一一完

最全面的改造Zuul网关为Spring Cloud Gateway(包含Zuul核心实现和Spring Cloud Gateway核心实现)

前言: 最近开发了Zuul网关的实现和Spring Cloud Gateway实现,对比Spring Cloud Gateway发现后者性能好支持场景也丰富.在高并发或者复杂的分布式下,后者限流和自定义拦截也很棒. 提示: 本文主要列出本人开发的Zuul网关核心代码以及Spring Cloud Gateway核心代码实现.因为本人技术有限,主要是参照了 Spring Cloud Gateway 如有不足之处还请见谅并留言指出. 1:为什么要做网关 (1)网关层对外部和内部进行了隔离,保障了后台服

第二代微服务网关组件 - Spring Cloud Gateway

[TOC] 初识Spring Cloud Gateway 简介: Spring Cloud Gateway是Spring Cloud体系的第二代网关组件,基于Spring 5.0的新特性WebFlux进行开发,底层网络通信框架使用的是Netty,所以其吞吐量高.性能强劲,未来将会取代第一代的网关组件Zuul.Spring Cloud Gateway可以通过服务发现组件自动转发请求,默认集成了Ribbon做负载均衡,以及默认使用Hystrix对网关进行保护,当然也可以选择其他的容错组件,例如Sen