Spring gateway 源码解析之负载均衡和熔断07

  •  首先gateway的负载均衡需要是通过Ribbon组件来实现的,默认是轮询策略,通过全局filter: LoadBalancerClientFilter 来关联的
  •  默认情况下,假如找不到服务实例,lb 是返回 503,但是你可以通过设置成其他的: spring.cloud.gateway.loadbalancer.use404=true
  • LoadBalancerClientFilter 是阻塞的. 官方建议使用 ReactiveLoadBalancerClientFilter 通过设置 spring.cloud.loadbalancer.ribbon.enabled to false.

 1.LoadBalancerClientFilter 类代码

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
		String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
		if (url == null
				|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
			return chain.filter(exchange);
		}
		// preserve the original url
		addOriginalRequestUrl(exchange, url);

		if (log.isTraceEnabled()) {
			log.trace("LoadBalancerClientFilter url before: " + url);
		}

		//从loadbalace按照配置的规则拿到 服务用例
		final ServiceInstance instance = choose(exchange);

		if (instance == null) {
			throw NotFoundException.create(properties.isUse404(),
					"Unable to find instance for " + url.getHost());
		}

		URI uri = exchange.getRequest().getURI();

		// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
		// if the loadbalancer doesn't provide one.
		String overrideScheme = instance.isSecure() ? "https" : "http";
		if (schemePrefix != null) {
			overrideScheme = url.getScheme();
		}

		URI requestUrl = loadBalancer.reconstructURI(
				new DelegatingServiceInstance(instance, overrideScheme), uri);

		if (log.isTraceEnabled()) {
			log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
		}

		exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
		return chain.filter(exchange);
	}

2.负载均衡的Ribbon配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8083/eureka


spring:
  application:
    name: spring-gateway
  jmx:
    enabled: false
  cloud:
    gateway:
      default-filters:
      - PrefixPath=/
      - AddResponseHeader=X-Response-Default-Foo, Default-Bar
      routes:
      - id: order
        uri: lb://EUREKA-CLIENT
        predicates:
        - Path=/**
        filters:
          - name: Hystrix
            args:
              name: fallbackCommand
              fallbackUri: forward:/fallback/message
EUREKA-CLIENT:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule //配置的是随机策略

3.Ribbon负载均衡知识扩展

4.负载均衡策略说明

  • RoundRobinRule    通过轮询的方式,选择过程会有最多10次的重试机制    
  • RandomRule    随机方式,从列表中随机挑选一个服务    
  • ZoneAvoidanceRule    基于ZoneAvoidancePredicate断言和AvailabilityPredicate断言的规则。ZoneAvoidancePredicate计算出哪个Zone的服务最差,然后将此Zone的服务从服务列表中剔除掉;而AvaliabitiyPredicate是过滤掉正处于熔断状态的服务;上述两个断言过滤出来的结果后,再通过RoundRobin轮询的方式从列表中挑选一个服务    
  • BestAvailableRule    最优匹配规则:从服务列表中给挑选出并发数最少的Server    
  • RetryRule    采用了装饰模式,为Rule提供了重试机制    
  • WeightedResponseTimeRule    基于请求响应时间加权计算的规则,如果此规则没有生效,将采用 RoundRobinRule的的策略选择服务实例

5.例子说明

5.1.测试环境

   代码地址:https://github.com/zhaoliuzeng/spring-boot-eureka-example-master

5.2.负载均衡运行效果

5.3.Spring Cloud Gateway 添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

5.4.Spring Cloud Gateway 添加配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8083/eureka


spring:
  application:
    name: spring-gateway
  jmx:
    enabled: false
  cloud:
    gateway:
      default-filters:
      - PrefixPath=/
      - AddResponseHeader=X-Response-Default-Foo, Default-Bar
      routes:
      - id: order
        uri: lb://EUREKA-CLIENT
        predicates:
        - Path=/**
        filters:
          - name: Hystrix
            args:
              name: fallbackCommand
              fallbackUri: forward:/fallback/message
EUREKA-CLIENT:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule //配置的是随机策略

注意:假如报jdk 11的错误,添加下面依赖

<dependency>
   <groupId>com.sun.xml.bind</groupId>
   <artifactId>jaxb-impl</artifactId>
   <version>2.3.0</version>
</dependency>
<dependency>
   <groupId>org.glassfish.jaxb</groupId>
   <artifactId>jaxb-runtime</artifactId>
   <version>2.3.0</version>
</dependency>
<dependency>
   <groupId>javax.activation</groupId>
   <artifactId>activation</artifactId>
   <version>1.1.1</version>
</dependency>
<!-- jaxb模块引用 - end -->
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值