作用
负载均衡
用于客户端负载均衡
集中式负载均衡:消费者与服务提供方中间使用独立方式负载,如F5, NGINX
客户端负载均衡
服务端负责均衡、
客户端,也就是调用方调用负载中心插件,负载中心决定调用哪个服务提供者
常见负载均衡算法
- 轮询
- 随机
- 加权轮询
- 地址hash
- 最小连接数
ribbon模块
| 名 称 | 说 明 | | —- | —- | | ribbon-loadbalancer | 负载均衡模块,可独立使用,也可以和别的模块一起使用。 | | Ribbon | 内置的负载均衡算法都实现在其中。 | | ribbon-eureka | 基于 Eureka 封装的模块,能够快速、方便地集成 Eureka。 | | ribbon-transport | 基于 Netty 实现多协议的支持,比如 HTTP、Tcp、Udp 等。 | | ribbon-httpclient | 基于 Apache HttpClient 封装的 REST 客户端,集成了负载均衡模块,可以直接在项目中使用来调用接口。 | | ribbon-example | Ribbon 使用代码示例,通过这些示例能够让你的学习事半功倍。 | | ribbon-core | 一些比较核心且具有通用性的代码,客户端 API 的一些配置和其他 API 的定义。 |
spring cloud 整合ribbon
依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency>
nacos-discovery依赖ribbon
配置使用
@Configurationpublic class RestConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
调用
@Autowiredprivate RestTemplate restTemplate;@RequestMapping(value = "/findOrderByUserId/{id}")public R findOrderByUserId(@PathVariable("id") Integer id) {// RestTemplate调用//String url = "http://localhost:8020/order/findOrderByUserId/"+id;//模拟ribbon实现//String url = getUri("mall-order")+"/order/findOrderByUserId/"+id;// 添加@LoadBalancedString url = "http://mall-order/order/findOrderByUserId/"+id;R result = restTemplate.getForObject(url,R.class);return result;}
内核原理
拦截器 LoadBalancerInterceptor
原理就是 拦截调用,把对应服务名替换成对应ip ,端口
@LoadBanlanced注解原理
LoadBalancerAutoConfiguration
Ribbin 相关接口
RibbonClientConfiguration
IClientConfig:ribbon客户端,默认DefaultClientConfigImpl实现
IRule:负责均衡策略默认采用ZoneAvoidanceRule实现
IPing :实例检查策略 DummyPing实现
ServerList 服务实例列表,ConfigurationBasedServerList实现
ServerListFilter:服务实例过滤机制,优先过滤出于请求方同一区域的服务实例
ILoadBalancer :负载均衡ZoneAwareLoadBalancer 实现

负载均衡策略

- RandomRule:
- RetryRule:
- RoundRobinRule:
- AvailabilityFilteringRule:
- BestAvailableRule: 。
- WeightedResponseTimeRule:
- ZoneAvoidanceRule:默认的负载均衡策略,
- NacosRule:
自定义负载均衡策略
实现 IRule接口可以自定义负载均衡策略,重新choose方法
@Slf4jpublic class NacosRandomWithWeightRule extends AbstractLoadBalancerRule {@Autowiredprivate NacosDiscoveryProperties nacosDiscoveryProperties;@Overridepublic Server choose(Object key) {DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();String serviceName = loadBalancer.getName();NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();try {//nacos基于权重的算法Instance instance = namingService.selectOneHealthyInstance(serviceName);return new NacosServer(instance);} catch (NacosException e) {log.error("获取服务实例异常:{}", e.getMessage());e.printStackTrace();}return null;}@Overridepublic void initWithNiwsConfig(IClientConfig clientConfig) {}
配置application.yml
# 被调用的微服务名mall-order:ribbon:# 自定义的负载均衡策略(基于随机&权重) 对应方法全路径名NFLoadBalancerRuleClassName: com.NacosRandomWithWeightRule
利用@RibbonClient指定微服务的放回寺配置负载均衡
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,DruidDataSourceAutoConfigure.class})//@RibbonClient(name = "mall-order",configuration = RibbonConfig.class)//配置多个 RibbonConfig不能被@SpringbootApplication的@CompentScan扫描到,否则就是全局配置的效果@RibbonClients(value = {// 在SpringBoot主程序扫描的包外定义配置类@RibbonClient(name = "mall-order",configuration = RibbonConfig.class),@RibbonClient(name = "mall-account",configuration = RibbonConfig.class)})public class MallUserRibbonDemoApplication {public static void main(String[] args) {SpringApplication.run(MallUserRibbonDemoApplication.class, args);}}
注意
不能写在compentScan扫描到的地方,不让会被所有的ribbonClients共享,最好还是yml配置
饥饿加载
只有在调起的时候才会创建客户端
需要在配置文件中配置
ribbon:eager-load:# 开启ribbon饥饿加载enabled: true# 配置mall-order使用ribbon饥饿加载,多个使用逗号分隔clients: mall-order
源码类: RibbonEagerLoadProperties
LoanBalancer
spring cloud LoadBalancer spring cloud 提供的客户端负载均衡,用来替代Ribbon的
Spring官方两种客户端
- RestTemplate
访问rest 服务的客户端,访问http的,依赖jdk的http工具 - WebClient
Spring webFlux 5.0提供,非阻塞的基于响应式变成的http,j
基于Reactor,
引入依赖
<!-- LoadBalancer --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!-- 提供了RestTemplate支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- nacos服务注册与发现 移除ribbon支持--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><exclusions><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></exclusion></exclusions></dependency>
注意点: nacos-discory 引入了ribbon,需要排除
原因是:RibbonLoadBalancerClient和BlockingLoadBalancerClient会倾向使用前者
所以需要排除RibbonLoadBalancerClient
也可以在yml配置中排除
#yml中排除ribbonspring:application:name: mall-user-loadbalancer-democloud:nacos:discovery:server-addr: 127.0.0.1:8848# 不使用ribbonloadbalancer:ribbon:enabled: false
client的继承关系
使用@LoadBalanced 配置RestTemplate
@Configurationpublic class RestConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}}
客户端使用
@RestController@RequestMapping("/user")public class UserController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping(value = "/findOrderByUserId/{id}")public R findOrderByUserId(@PathVariable("id") Integer id) {String url = "http://mall-order/order/findOrderByUserId/"+id;R result = restTemplate.getForObject(url,R.class);return result;}}
