负载均衡的原理

SpringCloud 中负载均衡的原理

前情 : 启动了两个 UserService 客户端和一个 OrderService 客户端,且都已经注册到 Eureka 中。

服务消费者OrderService,使用注册中心的名字代替 ip 和端口,设置负载均衡策略 ,直接调用了其中

之一的服务提供者。

java 复制代码
    /**
     *  创建 RestTemplate 并注入 Spring 容器
     *  RestTemplate 是Spring Cloud框架中的一个HTTP客户端工具,
     *  用于发送HTTP请求并与远程服务进行通信。
     *  它封装了常见的HTTP操作,使得在微服务架构中进行服务间通信更加方便。
     */
    @Bean
    @LoadBalanced   
    // order-service(服务消费者) 在调用多个 user-service(服务提供者) 时,使用负载均衡算法
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
  1. 通过LoadBalancerInterceptor 负载均衡拦截器拦截到请求
java 复制代码
@Override
   public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
   		final ClientHttpRequestExecution execution) throws IOException {
   	final URI originalUri = request.getURI();
   	String serviceName = originalUri.getHost();
   	Assert.state(serviceName != null,
   			"Request URI does not contain a valid hostname: " + originalUri);
   	return this.loadBalancer.execute(serviceName,
   			this.requestFactory.createRequest(request, body, execution));
   }
  1. 通过 RibbonLoadBalancerClient 获取url 中的服务 id
java 复制代码
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
			throws IOException {
	ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
	Server server = getServer(loadBalancer, hint);
	if (server == null) {
		throw new IllegalStateException("No instances available for " + serviceId);
	}
	RibbonServer ribbonServer = new RibbonServer(serviceId, server,
			isSecure(server, serviceId),
			serverIntrospector(serviceId).getMetadata(server));
	
	return execute(serviceId, ribbonServer, request);
}
  1. 从 eureka 注册中心拉取 user-service,返回服务列表
  2. 通过 IRule 接口选择一种负载均衡策略,拉取某个服务
java 复制代码
public Server chooseServer(Object key) {
    if (this.counter == null) {
        this.counter = this.createCounter();
    }
    this.counter.increment();
    if (this.rule == null) {
        return null;
    } else {
        try {
            return this.rule.choose(key);
        } catch (Exception var3) {
            logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", new Object[]{this.name, key, var3});
            return null;
        }
    }
}
  1. 修改 url 发起请求
相关推荐
我要见SA姐110 小时前
告别 Copilot?Codex 本地化部署指南
运维·数据库·机器学习·oracle·回归
Elastic 中国社区官方博客11 小时前
列式存储并不等同于列式数据库。Columnar 模式为 Elasticsearch 带来了什么
大数据·运维·数据库·elasticsearch·搜索引擎
fengkai454512 小时前
八、Docker详解4-5
运维·docker
智恒百亿13 小时前
RTX 5090 八卡服务器 vs RTX PRO 6000 整机:AI 推理、微调与渲染选型部署指南
运维·服务器·rtx5090
蓝胖的四次元口袋14 小时前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
懂软件的胡子个哥15 小时前
微信 API 消息回调怎么设计,才能避免丢消息和重复处理
运维·微信·架构·wechatapi·个人微信号二次开发
吉甫作诵15 小时前
Redis 常用命令大全:11 大类命令速查手册
运维·数据库·redis·缓存·nosql
Acrellea17 小时前
告别粗放式能耗管理!安科瑞EIOT平台助力产业园区智慧低碳运营
运维·安全·能源
Databuff17 小时前
五款主流 SSH 免费工具介绍
运维·ssh·运维开发
菜鸟学编程o17 小时前
Linux常见指令
linux·运维·服务器