【负载均衡】LoadBalance场景演示

服务端⾼并发分布式结构演进之路-CSDN博客文章浏览阅读976次,点赞11次,收藏9次。在进行技术学习过程中,由于大部分读者没有经历过一些中大型系统的实际经验,导致无法从服务端⾼并发分布式结构演进之路-----在进行技术学习过程中,由于大部分读者没有经历过一些中大型系统的实际经验,导致无法从全局理解一些概念,所以本文以一个"电子商务"应用为例,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,方便大家对后续知识做深入学习时有一定的整体视野。https://blog.csdn.net/qq_45875349/article/details/139639760?spm=1001.2014.3001.5501对于负载均衡的概念还不了解的可以我的上面这篇博客的 2.3 小节去了解一下。

负载均衡(Load Balancing)是一种将网络流量或计算任务分配到多个服务器或资源上的技术,目的是优化资源使用、最大化吞吐量、减少响应时间、提高系统的可靠性和可用性。通过平衡工作负载,负载均衡可以避免单个服务器或资源过载,从而提高整个系统的性能和稳定性。

1问题描述

我们的订单服务每次被调用的时候,都会通过Eureka的服务发现去获取到商品服务的实例列表。如果仅仅单纯获取某一个商品服务,那么流量就一直压在一台服务器之上。如果⼀个服务对应多个实例呢? 流量是否可以合理的分配到多个实例呢?

2场景复现

为了更好的演示效果,我们可以多启动几个product-service的实例。【不修改代码,修改修改配置,调整端口号并启动服务】  项目名名称和端口号可以自己设定,两者最好有对应关系,方便观察。

apply之后,现在IDEA的Service窗⼝就会多出来⼀个启动配置, 右键启动服务就可以,同样的操作, 再启动1个实例, 共启动3个服务。启动后观察Eureka,可以看到product-service下有三个实例:

现在我们来访问订单服务,然后订单服务远程调用商品服务。

结果发现,都是请求多次访问, 都是同⼀台机器.

这肯定不是我们想要的结果, 我们启动多个实例, 是希望可以分担其他机器的负荷, 那么如何实现呢?

3 解决方案

先来看看现在的带代码,为什么会出现这样的现象,也就是我们再去获取服务的时候,使用的方式是不对的,这样每次获取到的服务大概率是相同的。

 

好的,那么我就来来写代码。修改远程调用的逻辑

package com.guan.order.service;

import com.guan.order.mapper.OrderMapper;
import com.guan.order.model.OrderInfo;
import com.guan.product.model.ProductInfo;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Resource
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    private static AtomicInteger atomicInteger = new AtomicInteger(1);

    private static List<ServiceInstance> instances;

    @PostConstruct
    public void init() {
        //根据应⽤名称获取服务列表
        instances = discoveryClient.getInstances("product-service");
    }

    public OrderInfo selectOrderByID(Integer orderID) {
        OrderInfo orderInfo = orderMapper.selectOrderById(orderID);
        // 从Eureka获取服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
        //有多个服务,根据轮询获取
        int index = atomicInteger.getAndIncrement() % instances.size();
        String uri = instances.get(index).getUri().toString();
        String url = uri + "/product/" + orderInfo.getProductId();
        log.info("远程调用url:{}", url);
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

现在在来观察服务。

通过⽇志可以看到, 请求被均衡的分配在了不同的实例上, 这就是负载均衡

4 什么是负载均衡

负载均衡(Load Balance,简称 LB) , 是⾼并发, ⾼可⽤系统必不可少的关键组件.
当服务流量增⼤时, 通常会采⽤增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载
⼀个团队最开始只有⼀个⼈, 后来随着⼯作量的增加, 公司⼜招聘了⼏个⼈. 负载均衡就是: 如何把⼯作量均衡的分配到这⼏个⼈⾝上, 以提⾼整个团队的效率

5 负载均衡的一些实现

上面的例子中,我们只是简单的对实例进行了轮询,但真实的业务场景会更加复杂,比如根据机器的配置进行负载分配,配置高的分配的流量高,配置低的分配流量低等.也就是“能者多劳”。

服务多机部署时,开发人员都需要考虑负载均衡的实现,所以也出现了一些负载均衡器,来帮助我们实现负载均衡.

负载均衡分为服务端负载均衡和客户端负载均衡

服务端负载均衡

在服务端进行负载均衡的算法分配.
比较有名的服务端负载均衡器是Nginx.请求先到达Nginx负载均衡器,然后通过负载均衡算法,在多个服务器之间选择一个进行访问.

客户端负载均衡

在客户端进行负载均衡的算法分配.
把负载均衡的功能以库的方式集成到客户端,而不再是由一台指定的负载均衡设备集中提供,比如Spring Cloud的Ribbon,请求发送到客户端,客户端从注册中心(比如Eureka)获取服务列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问.Ribbon是Spring Cloud早期的默认实现,由于不维护了,所以最新版本的Spring Cloud负载均衡集成的是Spring Cloud LoadBalancer(Spring Cloud官方维护)

客⼾端负载均衡和服务端负载均衡最⼤的区别在于服务清单所存储的位置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小小小关同学

你的支持就是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值