负载均衡的原理

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 发起请求
相关推荐
Z21-X1 天前
云原生运维学习笔记:ECShop全链路容器化部署与Docker底层资源隔离深度剖析
运维·笔记·学习·云原生
进击的荆棘1 天前
Linux系统——线程同步与互斥之线程池和安全
linux·运维·服务器·安全·单例模式·线程
瑞雪兆丰年兮1 天前
JavaWeb-day11-SpringBootWeb案例(文件上传)
java·运维·服务器·javaweb·oss
那明眸似水1 天前
云原生项目三:Docker秒级启动NextCloud个人网盘存储办公系统
linux·运维·docker·云原生·容器
小南家的青蛙1 天前
微服务体系下DevOps运维岗位面试方案设计
运维·面试·职场和发展·devops
知已难寻2 天前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
Alluxio2 天前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
Sayai2 天前
Neo4j 图数据质量检查实战:环路检测、孤立节点与连通分量,两条 Cypher 引出的数据体检清单(含变长路径性能陷阱)
运维·neo4j·图数据库·数据质量·cypher
Elastic 中国社区官方博客2 天前
更少的位数,相同的召回率:DiskBBQ 更保守的自动校准扫描
大数据·运维·开发语言·人工智能·elasticsearch·搜索引擎
方便面不加香菜2 天前
Docker Volume -- 管理卷Volume详解
运维·docker·容器