iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >springcloud gateway怎么实现路由和负载均衡
  • 892
分享到

springcloud gateway怎么实现路由和负载均衡

2023-06-20 13:06:37 892人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关SpringCloud gateway怎么实现路由和负载均衡,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。简介:gateway主要是做路由 负载,过滤 主要是替代zuul 1.

这篇文章将为大家详细讲解有关SpringCloud gateway怎么实现路由和负载均衡,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

简介:

gateway主要是做路由 负载,过滤 主要是替代zuul 1.x 性能比zuul好 zuul是基于

Servlet ,gateway是基于spring-WEBflux 用的Netty+Reactor

yml文件

实现路由 负载 的配置 亲自测试

spring:  application:    name: xgyx_gateway  cloud:    discovery:      locator:        enabled: true    gateway:       routes:       - id: a  #随便定义不重复就好         uri: lb://xgyx-welfareservice-x  #服务名称         predicates:         - Path=/m@Deprecatedpublic class LoadBalancerClientFilter implements GlobalFilter, Ordered {    public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100;    private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class);    protected final LoadBalancerClient loadBalancer;    private LoadBalancerProperties properties;     public LoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {        this.loadBalancer = loadBalancer;        this.properties = properties;    }     public int getOrder() {        return 10100;    }     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);        if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {            ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);            if (log.isTraceEnabled()) {                log.trace("LoadBalancerClientFilter url before: " + url);            }             ServiceInstance instance = this.choose(exchange);            if (instance == null) {                throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());            } else {                URI uri = exchange.getRequest().getURI();                String overrideScheme = instance.isSecure() ? "https" : "Http";                if (schemePrefix != null) {                    overrideScheme = url.getScheme();                }                 URI requestUrl = this.loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);                if (log.isTraceEnabled()) {                    log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);                }                 exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);                return chain.filter(exchange);            }        } else {            return chain.filter(exchange);        }    }     protected ServiceInstance choose(ServerWebExchange exchange) {        return this.loadBalancer.choose(((URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR)).getHost());    }}

说明:默认使用该类,可通过下述方法使用ReactiveLoadbalancerClientFilter

"You already have RibbonLoadBalancerClient on your classpath. It will be used by default.
As spring cloud Ribbon is in maintenance mode. We recommend switching to " + BlockingLoadBalancerClient.class.getSimpleName() + " instead.
In order to use it, set the value of `spring.cloud.loadbalancer.ribbon.enabled` to `false`
or remove spring-cloud-starter-netflix-ribbon from your project."

ReactiveLoadBalancerClientFilter负载均衡拦截器

public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {    private static final Log log = LogFactory.getLog(ReactiveLoadBalancerClientFilter.class);    private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150;    private final LoadBalancerClientFactory clientFactory;    private LoadBalancerProperties properties;     public ReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {        this.clientFactory = clientFactory;        this.properties = properties;    }     public int getOrder() {        return 10150;    }     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);        if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {                            //url不为null且协议为lb,或者url以lb开头             ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);            if (log.isTraceEnabled()) {                log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);            }             return this.choose(exchange).doOnNext((response) -> {                            //获取ServiceInstance实例,进行一些处理                 if (!response.hasServer()) {                            //如果没有serviceInstance,直接抛出异常                     throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());                } else {    //如果有serviceInstance,进行相关处理                    URI uri = exchange.getRequest().getURI();                    String overrideScheme = null;                    if (schemePrefix != null) {                        overrideScheme = url.getScheme();                    }                     DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance((ServiceInstance)response.getServer(), overrideScheme);                    URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);                    if (log.isTraceEnabled()) {                        log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);                    }                     exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);                }            }).then(chain.filter(exchange));        } else {            return chain.filter(exchange); //如果获取不到serviceInstance,直接进行后续过滤        }    }     private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {        URI uri = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        ReactorLoadBalancer<ServiceInstance> loadBalancer = (ReactorLoadBalancer)this.clientFactory.getInstance(uri.getHost(), ReactorLoadBalancer.class, new Class[]{ServiceInstance.class});        if (loadBalancer == null) {            throw new NotFoundException("No loadbalancer available for " + uri.getHost());        } else {            return loadBalancer.choose(this.createRequest());        }    }//选择服务实例     private Request createRequest() {        return ReactiveLoadBalancer.REQUEST;    }}

ReactorLoadBalancer:负载均衡接口

public interface ReactorLoadBalancer<T> extends ReactiveLoadBalancer<T> {    Mono<Response<T>> choose(Request request);     default Mono<Response<T>> choose() {        return this.choose(REQUEST);    }} *********************** public interface ReactorServiceInstanceLoadBalancer extends ReactorLoadBalancer<ServiceInstance> {}

RoundRobinLoadbalancer:负载均衡使用轮询

public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {    private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class);    private final AtomicInteger position;     private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;    private final String serviceId; ************构造方法     public RoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {    public RoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId, int seedPosition) { ************普通方法     public Mono<Response<ServiceInstance>> choose(Request request) {        if (this.serviceInstanceListSupplierProvider != null) {            ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);            return ((Flux)supplier.get()).next().map(this::getInstanceResponse);        } else {            ServiceInstanceSupplier supplier = (ServiceInstanceSupplier)this.serviceInstanceSupplier.getIfAvailable(NoopServiceInstanceSupplier::new);            return ((Flux)supplier.get()).collectList().map(this::getInstanceResponse);        }    }     private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {        if (instances.isEmpty()) {            log.warn("No servers available for service: " + this.serviceId);            return new EmptyResponse();        } else {            int pos = Math.abs(this.position.incrementAndGet());            ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());            return new DefaultResponse(instance);        }    }//使用轮询获取实例}

示例:

参数id为偶数时,输出hello new version

网关

配置文件

spring:  application:    name: hello-gateway  cloud:    consul:      host: 172.18.0.20      port: 8500    loadbalancer:      ribbon:        enabled: false    gateway:      routes:        - id: myRoute          uri: lb://hello-service          predicates:            - Path=/hello

自定义过滤器

@Componentpublic class CustomLoadBalancerClientFilter implements GlobalFilter, Ordered {    private static final Log log = LogFactory.getLog(org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.class);     @Resource    private final LoadBalancerClientFactory clientFactory;     @Resource    private LoadBalancerProperties properties;     public CustomLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {        this.clientFactory = clientFactory;        this.properties = properties;    }     public int getOrder() {        return 10149;    }     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);        if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {            ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);            if (log.isTraceEnabled()) {                log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);            }             return this.choose(exchange).doOnNext((response) -> {                if (!response.hasServer()) {                    throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());                } else {                    URI uri = exchange.getRequest().getURI();                    String overrideScheme = null;                    if (schemePrefix != null) {                        overrideScheme = url.getScheme();                    }                     int id=Integer.parseInt(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("id")));                    if (id%2==0){                        while (!"new".equals(response.getServer().getMetadata().get("version"))){                            try {                                response=this.choose(exchange).toFuture().get();                            }catch (Exception e){                                System.out.println(e.getMessage());                            }                        }                    }                     DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(), overrideScheme);                     System.out.println(exchange.getRequest().getQueryParams().getFirst("id")+"对应server的version为:"+serviceInstance.getMetadata().get("version"));                    URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);                    if (log.isTraceEnabled()) {                        log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);                    }                     exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);                }            }).then(chain.filter(exchange));        } else {            return chain.filter(exchange);        }    }     private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {        URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);        assert uri != null;        ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance(uri.getHost(), ReactorLoadBalancer.class, new Class[]{ServiceInstance.class});        if (loadBalancer == null) {            throw new NotFoundException("No loadbalancer available for " + uri.getHost());        } else {            return loadBalancer.choose(this.createRequest());        }    }     private Request createRequest() {        return ReactiveLoadBalancer.REQUEST;    }}

同名应用hello-service1

配置文件

spring:  application:    name: hello-service  cloud:    consul:      host: 172.18.0.20      port: 8500      discovery:        instance-id: ${spring.application.name}-${random.int}        tags: version=old

controller 层

@RestControllerpublic class HelloController {     @RequestMapping("/hello")    public String hello(){        return "hello old version";    }}

同名应用hello-service2

配置文件

spring:  application:    name: hello-service  cloud:    consul:      host: 172.18.0.20      port: 8500      discovery:        instance-id: ${spring.application.name}-${random.int}        tags: version=new

controller 层

@RestControllerpublic class HelloController {     @RequestMapping("/hello")    public String hello(){        return "hello new version";    }}

测试输出

consul注册的应用

springcloud gateway怎么实现路由和负载均衡

参数测试

springcloud gateway怎么实现路由和负载均衡

当id为偶数时,输出为hello new version

关于“sprinGCloud gateway怎么实现路由和负载均衡”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: springcloud gateway怎么实现路由和负载均衡

本文链接: https://www.lsjlt.com/news/297057.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • springcloud gateway怎么实现路由和负载均衡
    这篇文章将为大家详细讲解有关springcloud gateway怎么实现路由和负载均衡,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。简介:gateway主要是做路由 负载,过滤 主要是替代zuul 1....
    99+
    2023-06-20
  • springcloud gateway如何实现路由和负载均衡
    简介: gateway主要是做路由 负载,过滤 主要是替代zuul 1.x 性能比zuul好 zuul是基于 Servlet ,gateway是基于spring-webflux 用的...
    99+
    2024-04-02
  • springcloud负载均衡怎么实现
    Spring Cloud提供了多种方式来实现负载均衡,常用的有以下几种方式:1. Ribbon:Ribbon是Spring Clou...
    99+
    2023-09-02
    springcloud 负载均衡
  • springcloud怎么实现负载均衡
    Spring Cloud中实现负载均衡,可以使用Ribbon和Feign两种方式。1. Ribbon负载均衡:Ribbon是一个客户...
    99+
    2023-08-26
    springcloud
  • SpringCloud怎么实现Ribbon负载均衡
    这篇文章主要讲解了“SpringCloud怎么实现Ribbon负载均衡”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringCloud怎么实现Ribbon负载均衡”吧!Ribbon使用R...
    99+
    2023-06-30
  • springcloud负载均衡策略怎么实现
    在Spring Cloud中,负载均衡策略的实现主要依赖于Ribbon和Eureka。Ribbon是Netflix开源的负载均衡组件...
    99+
    2023-09-27
    springcloud
  • SpringCloud Gateway详细分析实现负载均衡与熔断和限流
    目录环境准备1.pom依赖2.yaml配置3.路由转发和负载均衡测试user服务暴露接口返回结果输出4.gateway熔断实现4.1 熔断代码4.2 测试5.gateway限流5.1...
    99+
    2024-04-02
  • 静态路由如何实现负载均衡
    静态路由是一种简单的路由方式,它是通过手动配置路由表来实现路由转发的。静态路由并不具备负载均衡的能力,它只能将特定的流量转发到预先配...
    99+
    2023-09-07
    负载均衡
  • springcloud负载均衡怎么搭建
    要搭建Spring Cloud负载均衡,你可以使用Ribbon作为负载均衡器。下面是搭建Spring Cloud负载均衡的步骤:1....
    99+
    2023-09-01
    springcloud 负载均衡
  • SpringCloud Zuul怎么实现负载均衡和熔断机制
    小编给大家分享一下SpringCloud Zuul怎么实现负载均衡和熔断机制,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、场景Zuul网关下实现其负载均衡与熔...
    99+
    2023-06-20
  • springcloud负载均衡怎么配置
    Spring Cloud提供了多种负载均衡的方式,可以通过在配置文件中配置相关参数来进行配置。 使用Ribbon负载均衡器: 在...
    99+
    2023-10-26
    springcloud
  • 两个路由器怎么做负载均衡
    要实现路由器的负载均衡,可以通过以下几种方法来实现:1. 静态路由:在路由表中手动配置多条路由路径,并将流量分配到不同的路径上。这种...
    99+
    2023-09-01
    负载均衡
  • SpringCloud如何实现Zuul集群(负载均衡)
    目录前言:一、使用 Nginx+Zuul 实现网关集群1.创建Eurek注册中心、会员服务、订单服务 (略)2. 创建Zuul服务3. 下载Nginx服务器二、 测试三、补充Ngin...
    99+
    2024-04-02
  • SpringCloud怎么实现微服务间负载均衡访问
    本篇内容介绍了“SpringCloud怎么实现微服务间负载均衡访问”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Nacos简介Nacos 提...
    99+
    2023-07-02
  • SpringCloud Zuul实现负载均衡和熔断机制方式
    一、场景 笔者就Zuul网关下实现其负载均衡与熔断机制(雪崩)进行实践,前提是已经导入zuul相关依赖 springboot版本:1.5.9.RELEASE springcloud版...
    99+
    2024-04-02
  • php负载均衡怎么实现
    在PHP中实现负载均衡的方式有多种,以下是其中几种常见的方法:1. 使用负载均衡器:负载均衡器是一个专门的服务器,它将请求分发给多个...
    99+
    2023-08-15
    php
  • mac负载均衡怎么实现
    在mac上实现负载均衡可以通过以下几种方式:1. 使用NAT(Network Address Translation)路由器:将多个...
    99+
    2023-09-01
    负载均衡
  • SpringCloud中如何利用Ribbon实现负载均衡
    SpringCloud中如何利用Ribbon实现负载均衡,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。首先在pom文件添加Fegin的依赖包。  <d...
    99+
    2023-06-05
  • dubbo负载均衡怎么实现
    Dubbo负载均衡可以通过以下方式实现:1. 随机负载均衡(Random Load Balance):每次从可用的服务提供者中随机选...
    99+
    2023-10-20
    dubbo
  • CDN怎么实现负载均衡
    CDN(内容分发网络)可以通过多种方式实现负载均衡,其中一些常见的方法包括: DNS轮询:CDN服务提供商可以利用DNS轮询来分...
    99+
    2024-04-24
    CDN
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作