Bootstrap

spring cloud Alibaba --- Ribbon负载均衡

什么是Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法

客户端和服务端的负载均衡

spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配
在这里插入图片描述
Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配。
在这里插入图片描述

常用的负载均衡算法

随机,通过随机选择服务进行执行,一般这种方式使用较少;
轮询,负载均衡默认实现方式,请求来之后排队处理;
加权轮询,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。 ip —>hash
最小链接数,即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上。 最小活跃数

nacos使用ribbon

nacos-discovery依赖了ribbon,不需要再引入ribbon依赖
添加@LoadBalanced注解到resttemplate构造方法上

@Configuration
public class RestConfig {
 @Bean
 @LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

修改相应的controller

@Autowired
private 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;
// 添加@LoadBalanced
String url = "http://mall‐order/order/findOrderByUserId/"+id;
R result = restTemplate.getForObject(url,R.class);
return result;
}

修改默认负载均衡策略

1.基于配置类修改负载均衡策略

 @Configuration
public class RibbonConfig {
/**
* 全局配置
* 指定负载均衡策略
* @return
*/
 @Bean
 public IRule iRule() {
 // 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机权重)
 return new NacosRule();
}
}

不能写在@SpringbootApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的
RibbonClients共享。 不建议这么使用,推荐yml方式

@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);
}}

2.基于配置文件修改负载均衡策略
配置文件:调用指定微服务提供的服务时,使用对应的负载均衡算法

修改application.yml
# 被调用的微服务名
mall‐order:
ribbon:
# 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

饥饿加载
Ribbon默认懒加载,意味着只有在发起调用的时候才会创建客户端。
开启饥饿加载,解决第一次调用慢的问题

ribbon:
  eager‐load:
    # 开启ribbon饥饿加载
    enabled: true
    # 配置mall‐user使用ribbon饥饿加载,多个使用逗号分隔
    clients: mall‐order

什么是spring cloud Load balance

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。
Spring官方提供了两种负载均衡的客户端:
RestTemplate
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问
远程Http服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTemplate默认依赖
jdk的HTTP连接工具。
WebClient
WebClient是从Spring WebFlux 5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请
求的客户端工具。它的响应式编程的基于Reactor的。WebClient中提供了标准Http请求方式对
应的get、post、put、delete等方法,可以用来发起相应的请求。

RestTemplate整合LoadBalancer

1.引入依赖

 <!‐‐ 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-discovery中引入了ribbon,需要移除ribbon的包
如果不移除,也可以在yml中配置不使用ribbon

 spring:
  application:
  name: mall‐user‐loadbalancer‐demo
  cloud:
  nacos:
  discovery:
  server‐addr: 127.0.0.1:8848
  # 不使用ribbon
  loadbalancer:
  ribbon:
  enabled: false

使用@LoadBalanced注解配置RestTemplate

 @Configuration
 public class RestConfig {
  @Bean
  @LoadBalanced
 public RestTemplate restTemplate() {
 return new RestTemplate();
 }
 }

使用

@RestController
 @RequestMapping("/user")
 public class UserController {
  @Autowired
 private 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;
 }
 }
;