3.负载均衡-LoadBalance

1.背景引入

1.1问题描述

java 复制代码
List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
 //服务可能有多个, 获取第⼀个
EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);

针对某个服务,我们启动多个实例进行观察

访问eureka后,可以看到注册的实例

但是发现一个问题,每次进行数据访问时,都是同一台机器

我们启动多个实例, 是希望可以分担其他机器的负荷

1.2负载均衡

负载均衡(Load Balance) , 是⾼并发, ⾼可⽤系统必不可少的关键组件.当服务流量增⼤时, 通常会采⽤增加机器的⽅式进⾏扩容, 负载均衡就是⽤来在多个机器或者其他资源中, 按照⼀定的规则合理分配负载

1.3服务端负载均衡

在服务端进⾏负载均衡的算法分配.

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

1.4客户端负载均衡

在客⼾端进⾏负载均衡的算法分配.

把负载均衡的功能以库的⽅式集成到客⼾端, ⽽不再是由⼀台指定的负载均衡设备集中提供.

⽐如Spring Cloud的Ribbon, 请求发送到客⼾端, 客⼾端从注册中⼼(⽐如Eureka)获取服务列表, 在发

送请求前通过负载均衡算法选择⼀个服务器,然后进⾏访问.

2.Spring Cloud LoadBalancer

2.1使⽤Spring Cloud LoadBalancer实现负载均衡

(1)给 RestTemplate 这个Bean添加 @LoadBalanced 注解

java 复制代码
@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

(2)修改IP端⼝号为服务名称

java 复制代码
    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);

        String url="http://product-service/product/"+orderInfo.getProductId();

        log.info("远程调用url{}",url);
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }

2.2负载均衡策略

负载均衡策略是⼀种思想, ⽆论是哪种负载均衡器, 它们的负载均衡策略都是相似的. Spring Cloud LoadBalancer 仅⽀持两种负载均衡策略: 轮询策略 和 随机策略

  • 轮询: 轮询策略是指服务器轮流处理⽤⼾的请求. 这是⼀种实现最简单, 也最常⽤的策略. ⽣活中也有类似的场景, ⽐如学校轮流值⽇, 或者轮流打扫卫⽣.
  • 随机选择: 随机选择策略是指随机选择⼀个后端服务器来处理新的请求.

Spring Cloud LoadBalancer 默认负载均衡策略是轮询策略,如果服务的消费者如果想采⽤随机的负载均衡策略, 也⾮常简单

(1)定义随机算法对象, 通过 @Bean 将其加载到 Spring 容器中

java 复制代码
public class CustomLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

(2)使⽤ @LoadBalancerClient 或者 @LoadBalancerClients 注解

在 RestTemplate 配置类上⽅, 使⽤ @LoadBalancerClient 或 @LoadBalancerClients 注解, 可以对不同的服务提供⽅配置不同的客⼾端负载均衡算法策略

java 复制代码
//name指定这个配置针对的服务名称是"product-service",configuration指定自定义的负载均衡配置类
@LoadBalancerClient(name = "product-service",configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

2.3LoadBalancer原理

LoadBalancer 的实现, 主要是 LoadBalancerInterceptor , 这个类会对 RestTemplate 的请求进⾏拦截, 然后从Eureka根据服务id获取服务列表,随后利⽤负载均衡算法得到真实的服务地址信息,替换服务id

3.服务部署(Linux)

3.1准备数据

  • 安装mysql
  • 数据初始化
  • 修改配置文件,主要包括用户名和密码

3.2服务构建打包

采用Maven打包,对所以服务进行打包

3.3启动服务

java 复制代码
#后台启动eureka-server, 并设置输出⽇志到logs/eureka.log
nohup java -jar eureka-server.jar >logs/eureka.log &
#其他服务同理

#再多启动两台实例
#启动实例, 指定端⼝号为9091
nohup java -jar product-service.jar --server.port=9091 >logs/product-9091.log &
#启动实例, 指定端⼝号为9092
nohup java -jar product-service.jar --server.port=9092 >logs/product-9092.log &

3.4开放端口号

对于不同的服务厂商,开放端口号的方法不同,这里以阿里云为例

相关推荐
不做无法实现的梦~2 分钟前
PX4 机载电脑 Linux 环境安装、串口、网络、ROS 完整配置
linux·运维·网络
嵌入式×边缘AI:打怪升级日志2 分钟前
嵌入式Linux开发(了解交叉编译工具链的组成)
java·linux·运维
IT界的老黄牛5 分钟前
停电后 Redis 集群两节点起不来:fix 完还报 Bad file format?多部分 AOF 修复的正确姿势
运维·redis·缓存
接着奏乐接着舞7 分钟前
3D Tiles tileset.jso 数据格式
运维·服务器·3d
李小白202002029 分钟前
RK3568 linux6.1 死机
linux·运维·服务器
FreeGo~11 分钟前
Linux 系统编程 进程篇 (五)
java·linux·服务器
杨云龙UP22 分钟前
Oracle数据库启动失败:ORA-29701、ORA-01565、ORA-17503故障处理记录_20260429
linux·运维·数据库·oracle·centos
Agent产品评测局27 分钟前
离散制造业生产流程优化,AI落地实操步骤详解:从传统自动化到企业级智能体的技术范式跃迁
运维·人工智能·ai·自动化
phltxy28 分钟前
Spring Cloud入门到实战:微服务架构一站式学习
spring cloud·微服务·架构
XiYang-DING31 分钟前
【Java EE】定时器
java·python·java-ee