欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springcloud gateway如何實現(xiàn)路由和負載均衡

 更新時間:2021年07月03日 14:32:46   作者:cuixinzhou  
這篇文章主要介紹了springcloud gateway如何實現(xiàn)路由和負載均衡的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

簡介:

gateway主要是做路由 負載,過濾 主要是替代zuul 1.x 性能比zuul好 zuul是基于

Servlet ,gateway是基于spring-webflux 用的netty+reactor

yml文件

實現(xiàn)路由 負載 的配置 親自測試

spring:
  application:
    name: xgyx_gateway
  cloud:
    discovery:
      locator:
        enabled: true
    gateway:
       routes:
       - id: a  #隨便定義不重復就好
         uri: lb://xgyx-welfareservice-x  #服務名稱
         predicates:
         - Path=/m/**  #前端訪問需加入例如 http:ip:port/m
         filters:
         - StripPrefix=1 #訪問后端服務過濾掉m 必填否則找不到后端服務也可以在服務加上統(tǒng)一路徑
         - name: Hystrix  #熔斷
           args:
             name: default
             fallbackUri: forward:/defaultfallback  #熔斷后訪問路徑
       - id: b
         uri: lb://xgyx-welfareservice
         predicates:
         - Path=/welfare/**
         filters:
         - StripPrefix=1
         - name: Hystrix
           args:
             name: default
             fallbackUri: forward:/fallback
#熔斷時間
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy:  SEMAPHORE
          thread:
            timeoutInMilliseconds: 300000  #熔斷時間

上面是用了兩天時間根據(jù)官網(wǎng)上的demo和說明自己測的可以使用 上面 stripPrefix 用的是 PrefixPath 過濾器 其他過濾器使用可以看官網(wǎng)

springcloud gateway 自定義負載均衡

相關類及接口

LoadbalancerClientFilter:使用ribbon負載均衡,默認使用該類(已不推薦使用)

/** @deprecated */
@Deprecated
public 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且協(xié)議為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,直接進行后續(xù)過濾
        }
    }
 
    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);
        }
    }//使用輪詢獲取實例
}

示例:

參數(shù)id為偶數(shù)時,輸出hello new version

網(wǎng)關

配置文件

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

自定義過濾器

@Component
public 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 層

@RestController
public 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 層

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

測試輸出

consul注冊的應用

參數(shù)測試

當id為偶數(shù)時,輸出為hello new version

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot框架實現(xiàn)支付和轉賬功能

    SpringBoot框架實現(xiàn)支付和轉賬功能

    在 Spring Boot 框架中實現(xiàn)支付和轉賬功能時,涉及到多個細節(jié)和注意點,這些功能通常需要高度的安全性、穩(wěn)定性和可擴展性,本文介紹了實現(xiàn)支付和轉賬功能的一些關鍵點,需要的朋友可以參考下
    2024-08-08
  • 關于SpringBoot的@ConfigurationProperties注解和松散綁定、數(shù)據(jù)校驗

    關于SpringBoot的@ConfigurationProperties注解和松散綁定、數(shù)據(jù)校驗

    這篇文章主要介紹了關于SpringBoot的@ConfigurationProperties注解和松散綁定、數(shù)據(jù)校驗,@ConfigurationProperties主要作用就是將prefix屬性指定的前綴配置項的值綁定到這個JavaBean上?,通過指定的前綴,來綁定配置文件中的配置,需要的朋友可以參考下
    2023-05-05
  • Springboot 自定義校驗代碼實例

    Springboot 自定義校驗代碼實例

    這篇文章主要介紹了Springboot 自定義校驗代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java實現(xiàn)XML格式與JSON格式互相轉換的方法

    Java實現(xiàn)XML格式與JSON格式互相轉換的方法

    這篇文章主要介紹了Java實現(xiàn)XML格式與JSON格式互相轉換的方法,方法通過實例代碼給大家介紹的非常詳細,選擇使用哪種格式通常取決于項目的需求和上下文,所以格式轉換就成了我們必備的技能,具體實現(xiàn)代碼跟隨小編一起看看吧
    2023-10-10
  • Java幸運28系統(tǒng)搭建數(shù)組的使用實例詳解

    Java幸運28系統(tǒng)搭建數(shù)組的使用實例詳解

    在本篇文章里小編給大家整理了關于Java幸運28系統(tǒng)搭建數(shù)組的使用實例內(nèi)容,有需要的朋友們可以參考學習下。
    2019-09-09
  • springboot中的Application.properties常用配置

    springboot中的Application.properties常用配置

    這篇文章主要介紹了springboot中的Application.properties常用配置,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • SpringCloud Nacos集群搭建過程詳解

    SpringCloud Nacos集群搭建過程詳解

    Nacos集群不僅僅是服務注冊中心,還在微服務架構中發(fā)揮著關鍵的角色,支持多種場景下的服務治理和協(xié)調(diào),本文介紹了如何在SpringCloud環(huán)境中搭建Nacos集群,為讀者提供了一份清晰而詳盡的指南,通過逐步演示每個關鍵步驟,讀者能夠輕松理解并操作整個搭建過程
    2024-02-02
  • Mybatis核心配置文件加載流程詳解

    Mybatis核心配置文件加載流程詳解

    本文將介紹MyBatis在配置文件加載的過程中,如何加載核心配置文件、如何解析映射文件中的SQL語句以及每條SQL語句如何與映射接口的方法進行關聯(lián),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Java數(shù)據(jù)結構之LinkedList從鏈表到實現(xiàn)

    Java數(shù)據(jù)結構之LinkedList從鏈表到實現(xiàn)

    LinkedList是Java中常用的數(shù)據(jù)結構之一,實現(xiàn)了鏈表的特性,支持快速添加、刪除元素,可以用于實現(xiàn)隊列、棧、雙向隊列等數(shù)據(jù)結構。LinkedList的內(nèi)部實現(xiàn)采用了雙向鏈表,其中每個節(jié)點都包含前驅節(jié)點和后繼節(jié)點的引用,可以直接訪問鏈表的頭尾元素
    2023-04-04
  • Java獲取Jar、War包路徑并生成可編輯修改的本地配置文件

    Java獲取Jar、War包路徑并生成可編輯修改的本地配置文件

    這篇文章主要給大家介紹了關于Java如何獲取Jar、War包路徑并生成可編輯修改的本地配置文件,文中通過代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01

最新評論