Spring Cloud Gateway Ribbon 自定义负载均衡

时间:2022-04-12 09:43:28

在微服务开发中,使用Spring Cloud Gateway做为服务的网关,网关后面启动N个业务服务。但是有这样一个需求,同一个用户的操作,有时候需要保证顺序性,如果使用默认负载均衡策略,同一个用户的请求可能会转发到不同的服务实例上面。所以需要实现一个负载均衡规则。

1,重写LoadBalancerClientFilter


import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import java.net.URI;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.web.server.ServerWebExchange; public class UserLoadBalancerClientFilter extends LoadBalancerClientFilter { public UserLoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
super(loadBalancer, properties);
} @Override
protected ServiceInstance choose(ServerWebExchange exchange) {
//这里可以拿到web请求的上下文,可以从header中取出来自己定义的数据。
String userId = exchange.getRequest().getHeaders().getFirst("userId");
if (userId == null) {
return super.choose(exchange);
}
if (this.loadBalancer instanceof RibbonLoadBalancerClient) {
RibbonLoadBalancerClient client = (RibbonLoadBalancerClient) this.loadBalancer;
String serviceId = ((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost();
//这里使用userId做为选择服务实例的key
return client.choose(serviceId, userId);
}
return super.choose(exchange);
} }

2,添加自定义的负载规则



import java.util.List;
import org.apache.commons.lang.math.RandomUtils;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server; /**
*
* @ClassName: GameCenterBalanceRule
* @Description: 根据userId对服务进行负载均衡。同一个用户id的请求,都转发到同一个服务实例上面。
* @author: wgs
* @date: 2019年3月15日 下午2:17:06
*/
public class GameCenterBalanceRule extends AbstractLoadBalancerRule { @Override
public Server choose(Object key) {//这里的key就是过滤器中传过来的userId List<Server> servers = this.getLoadBalancer().getReachableServers();
if (servers.isEmpty()) {
return null;
}
if (servers.size() == 1) {
return servers.get(0);
}
if (key == null) {
return randomChoose(servers);
}
return hashKeyChoose(servers, key);
}
/**
*
* <p>Description:随机返回一个服务实例 </p>
* @param servers
* @return
* @author wgs
* @date 2019年3月15日 下午2:25:23
*
*/
private Server randomChoose(List<Server> servers) {
int randomIndex = RandomUtils.nextInt(servers.size());
return servers.get(randomIndex);
}
/**
*
* <p>Description:使用key的hash值,和服务实例数量求余,选择一个服务实例 </p>
* @param servers
* @param key
* @return
* @author wgs
* @date 2019年3月15日 下午2:25:36
*
*/
private Server hashKeyChoose(List<Server> servers, Object key) {
int hashCode = Math.abs(key.hashCode());
if (hashCode < servers.size()) {
return servers.get(hashCode);
}
int index = hashCode % servers.size();
return servers.get(index); } @Override
public void initWithNiwsConfig(IClientConfig config) { } }

3.  添加Bean

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate; @Configuration
public class LoadBalancedBean { @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} @Bean
public UserLoadBalancerClientFilter userLoadBalanceClientFilter(LoadBalancerClient client, LoadBalancerProperties properties) {
return new UserLoadBalancerClientFilter(client, properties);
}
}

Spring Cloud Gateway Ribbon 自定义负载均衡


欢迎添加QQ交流群:398808948,677464431

Spring Cloud Gateway Ribbon 自定义负载均衡的更多相关文章

  1. Spring Cloud - 切换Ribbon的负载均衡模式

    Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现.通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模 ...

  2. 2&period;【Spring Cloud Alibaba】实现负载均衡-Ribbon

    负载均衡的两种方式 如何实现负载均衡 目前已经实现让A总能找到B,如何实现负载均衡 负载均衡的两种方式 服务器端负载均衡 客户端负载均衡 使用Ribbo实现负载均衡 Ribbon是什么 ==Netfl ...

  3. 4&period;Spring Cloud初相识--------Feign负载均衡

    前言: 在上一节里,我们学习了ribbon的使用. 我们了解到ribbon是一个客户端负载均衡机制. 而我们今天要讲的Feign呢,也是一款客户端负载均衡机制. 或者这样说,Feign封装了ribbo ...

  4. 【Spring Cloud学习之三】负载均衡

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 主流的负载均衡技术有nginx.LVS.HAproxy.F5,Spring Clou ...

  5. Spring Cloud 客服端负载均衡 Ribbon

    一.简介   Spring Cloud Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的.它不像服务注册中心.配置中心.API网关那样独立部署, ...

  6. Spring Cloud ---- 服务消费与负载均衡(Rest &plus; Ribbon )

    上一篇主要写了基于Eurake的服务的注册,主要就是创建注册中心,创建服务者,将服务者注册到注册中心,完成服务的暴露.这一篇主要写服务的消费与服务消费的负载均衡. 服务的调用方式有两种,Rest + ...

  7. SpringCloud的Ribbon自定义负载均衡算法

    1.Ribbon默认使用RoundRobinRule策略轮询选择server 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailab ...

  8. Spring Cloud ---- 服务消费与负载均衡(feign)

    feign是一个声明式的伪客户端,只需要创建一个接口并且注解,它具有可插拔的特性.feign集合了Ribbon,再与Eurake结合实现服务的注册发现与负载均衡.结合Hystrix,具有熔断功能. 1 ...

  9. Ribbon自定义负载均衡策略,在网关实现类似Ip&lowbar;hash的负载均衡,ribbon给单个服务配置属性

    背景: 我需要在网关实现一种功能,某个用户的请求永远打在后台指定的服务,也就是根据ip地址进行负载均衡 原理: 在ribbon的配置类下: 那我们自己创建一个IRule的实现类,模仿ZoneAvoid ...

随机推荐

  1. 【Swift 2&period;1】为 UIView 添加点击事件和点击效果

    前言 UIView 不像 UIButton 加了点击事件就会有点击效果,体验要差不少,这里分别通过自定义和扩展来实现类似 UIButton 的效果. 声明 欢迎转载,但请保留文章原始出处:) 博客园: ...

  2. &period;NET Nancy 详解&lpar;一&rpar; 初识

    Nancy 是一个轻量级的,简单粗暴的framework用来构建基于HTTP的各种服务,兼容.Net和Mono.Nancy的整套设计理念是基于"super-duper-happy-path& ...

  3. 判断UserAgent是否来自微信

    iso: Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko ...

  4. 如果设置Keil从C代码编译出来的hex文件地址从0x8000开始

    和MON51的设置一样,这样作:1.把Startup.a51拷贝到工程目录加入工程,修改125行的      CSEG    AT      0  为   CSEG    AT      0X8000 ...

  5. Android Studio项目构建常见问题解决

    1. 创建或导入项目后编译时一直在等待 问题: 原因:AS连网去下载gradle了,但是网络不好或不通 解决:禁用网络,AS就会立即自动终止下载进入到主界面了.此时再去指定离线的gradle版本进行编 ...

  6. AX&lowbar;CreateAndPostPurch

    static void CreateAndPostPurch(Args _args) { List il = new List(Types::Record); DocumentNum Document ...

  7. RecyclerView&plus;SwpieRefreshLayout(转载)

    开源库BaseRecyclerViewAdapterHelperhttp://blog.csdn.net/xiangzhihong8/article/details/52138669http://ww ...

  8. 论坛:排序 &gt&semi;&gt&semi;case&period;&period;when&period;&period;then &period;&period;end的妙用

    a.主题列表按 最后更新时间 进行排序 数据库SQL语句中没有if..else的判断语句,但是oracle中有decode()函数可以实现这种判断语句,但是还可以用case..when..then . ...

  9. 鸟哥的Linux私房菜——第九章

    视频链接,推荐看B站 土豆网:http://www.tudou.com/programs/view/XmMDbjJHJC8 B站:http://www.bilibili.com/video/av966 ...

  10. Explorer内存占用偶尔变高导致卡顿

    症状: 打开 "这台电脑",加载缓慢.此时查看任务管理器,explorer内存可能飙升到几G.cpu也很高 创建和删除文件缓慢,删除单个文件也会出现进度条.此时查看任务管理器,会出 ...