一、前置知识
1.1 负载均衡定义
负载均衡指的是将网络请求通过不同的算法分配到不同的服务器上的技术,从而提升系统的性能。
1.2 负载均衡工具
负载均衡工具可以分分为客户端负载均衡工具和服务端负载均衡工具,它们的区别如下。
表1-1 负载均衡工具分类[1]
维度 | 客户端负载均衡工具 | 服务端负载均衡工具 |
---|---|---|
决策位置 | 客户端代码中实现 | 中间层(如Nginx、负载均衡器) |
灵活性 | 高(支持自定义算法,如业务哈希) | 较低(依赖中间层配置) |
性能开销 | 客户端需计算实例选择,可能增加延迟 | 额外网络跳转,可能成为瓶颈 |
容错性 | 客户端需处理重试/降级 | 中间层自动剔除故障节点 |
服务发现 | 强依赖注册中心(如Eureka) | 可静态配置或动态集成 |
适用协议 | HTTP、gRPC、RPC | HTTP、TCP、UDP |
1.3 负载均衡算法
表1-2 负载均衡算法[2]
算法 | 工作原理 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
轮询(Round Robin) | 按顺序依次分配请求(如A->B->C->A->B) | 服务器性能相近、无状态服务(如静态资源) | 简单公平,易于实现 | 忽略服务器负载差异,性能不均时效率低 |
加权轮询(Weighted RR) | 根据服务器性能分配权重(如5:3:2),高权重服务器获得更多请求 | 服务器性能差异明显(如新旧硬件混合) | 按能力分配资源,优化利用率 | 需手动配置权重,无法动态响应负载变化 |
最少连接(Least Connections) | 优先选择当前连接数最少的服务器 | 长连接服务(数据库、视频流) | 动态适应负载,避免服务器过载 | 忽略服务器处理能力差异 |
加权最少连接(Weighted LC) | 结合服务器权重和当前连接数,选择(连接数/权重)最小的服务器 | 高性能异构集群(如混合云环境) | 兼顾性能与实时负载,资源利用率高 | 算法复杂,需实时监控服务器状态 |
源IP哈希(IP Hash) | 根据客户端IP计算哈希值,固定分配到同一服务器 | 需会话保持的应用(如购物车、登录状态) | 保证会话一致性 | 服务器故障时关联用户受影响 |
随机(Random) | 完全随机分配请求 | 测试环境或简单负载场景 | 实现简单,无状态依赖 | 分配不可控,可能造成负载不均 |
最快响应时间(Fastest Response) | 选择响应时间最短的服务器 | 对延迟敏感的应用(如金融交易) | 提升用户体验 | 需持续监控服务器响应时间 |
一致性哈希(Consistent Hashing) | 哈希环映射请求,服务器扩容/缩容时仅影响少量请求 | 分布式缓存(Redis集群) | 减少节点变动的影响 | 实现复杂度较高 |
动态性能分配(Dynamic Ratio) | 根据CPU、内存等实时指标动态调整流量分配 | 服务器性能波动大的场景 | 精准匹配当前负载 | 需高性能监控系统支持 |
二、Ribbon实战
2.1 项目结构
本项目使用Eureka作为注册中心,使用方法参见:Ereka实战。
图2-1 项目结构
服务列表如下。其中SpringCloudEurekaProductApplication02和SpringCloudEurekaProductApplication为product服务的实例,创建步骤见:IDEA中一个服务创建多个实例。
图2-2 服务实例
2.2 order模块新建以下代码
创建RestTemplate对象,并添加@LoadBalanced注解开启负载均衡。
@Configuration
public class LoadBalanceConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}
创建控制器访问product服务。
@RestController
@RequestMapping("/loadBalance")
public class LoadBalanceController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/test")public String test(){String url = String.format("http://%s/loadTest", "spring-cloud-eureka-product");ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);return forEntity.getBody();}
}
2.2 product模块新建代码
@RequestMapping
@RestController
public class LoadBalanceController {// order在配置文件中设置@Value("${order}")private Integer order;@RequestMapping("/loadTest")public String loadTest(){return "服务器:" + order;}
}
2.3 运行
分别启动server、product、product02、order服务,启动成功后,访问注册中http://localhost:8080/,结果如下图所示。
图2-3 注册中心
访问两次http://localhost:9003/loadTest,分别得到以下结果。后面的数字是两个product服务激活的配置文件中配置的order的值,分别为1和2。
图2-4 访问结果
三、总结
核心点就是创建RestTemplate,然后添加@LoadBalance注解,使用RestTemplate对象方法时自动实现负载均衡。
参考
[1][2] 腾讯元宝