负载均衡Ribbon

本文详细介绍了SpringCloud中Ribbon的使用,包括如何搭建Eureka服务、创建服务提供者和服务消费者,并展示了如何通过Ribbon实现负载均衡。通过启动多个服务实例,观察Eureka监控面板中的服务注册情况。同时,文章还探讨了Ribbon的默认负载均衡策略——简单轮询,并展示了如何修改负载均衡策略为随机。
摘要由CSDN通过智能技术生成


一、负载均衡Ribbon

Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。

1.1 什么是Ribbon

在这里插入图片描述

1.2 Service-Eureka服务搭建

  • 依赖
	<parent>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.1.RELEASE</version>
        <artifactId>spring-boot-starter-parent</artifactId>
    </parent>

    <!--版本管理:只管理坐标,所有的子工程都会默认继承该管理中的版本号,但是管理是只负责管理不负责下载-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
  • 配置
server:
  # 端口
  port: 9000
spring:
  application:
    # 应用名称
    name: service-eureka
# 注册中心提供的让其他服务注册的地址
eureka:
  client:
    service-url:
      # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:9000/eureka
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 10000
  • 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
//开启eureka的服务
@EnableEurekaServer
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

1.3 Service-Provider服务搭建

  • 依赖
	<parent>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.1.RELEASE</version>
        <artifactId>spring-boot-starter-parent</artifactId>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
  • 配置
server:
  port: 8001
spring:
  application:
    name: service-provider
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka
  instance:
    lease-expiration-duration-in-seconds: 10
    lease-renewal-interval-in-seconds: 5
  • 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
//开启Eureka客户端
@EnableDiscoveryClient
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class,args);
    }
}
  • 控制层
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {

    @GetMapping("provider")
    public String provider(){
        return "hello service-provider ";
    }
}

1.4 Service-Consumer服务搭建

  • 依赖
	<parent>
        <groupId>org.springframework.boot</groupId>
        <version>2.0.1.RELEASE</version>
        <artifactId>spring-boot-starter-parent</artifactId>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
  • 配置
server:
  port: 7000
spring:
  application:
    name: service-consumer
# 注册中心
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka
  • 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
//开启Eureka客户端
@EnableDiscoveryClient
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }

    @Bean
    //Ribbon负载均衡
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
  • 控制层
@RestController
public class ConsumerController {
	@Autowired
    private RestTemplate restTemplate;
   
	@GetMapping("ribbonConsumer")
    public String ribbonConsumer() {
        String url = "http://service-provider/provider";
        String body  = restTemplate.getForObject(url, String.class);
        return "consumer || " + body;
    }
}

二、Ribbon详解

1.1 启动两个服务实例

  • 1)启动第一个Service-Provider,配置为:
server:
  port: 8001
spring:
  application:
    name: service-provider
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka
  instance:
    lease-expiration-duration-in-seconds: 10
    lease-renewal-interval-in-seconds: 5
  • 2)启动第二个Service-Provider,配置为:
server:
  port: 8002
spring:
  application:
    name: service-provider
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka
  instance:
    lease-expiration-duration-in-seconds: 10
    lease-renewal-interval-in-seconds: 5

第一个设置完成后启动,然后修改配置,复制启动器再启动一次。

在这里插入图片描述

  • 3)访问注册中心,localhost:9000

    再Eureka监控面板中,Service-Provider有两个服务提供者,Service-Provider:8001Service-Provider:8002

1.2 开启负载均衡

因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖,直接修改代码。

修改Service-Consumer的引导类,在RestTemplate的配置方法上添加@LoadBalanced注解:

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

修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用:

@RestController
public class ConsumerController {
	@Autowired
    private RestTemplate restTemplate;
   
	@GetMapping("ribbonConsumer")
    public String ribbonConsumer() {
        String url = "http://service-provider/provider";
        String body  = restTemplate.getForObject(url, String.class);
        return "consumer || " + body;
    }
}

1.3 负载均衡策略

Ribbon默认的负载均衡策略是简单的轮询

在刚才的源码中我们看到拦截中是使用RibbonLoadBalanceClient来进行负载均衡的,其中有一个choose方法,找到choose方法的接口方法,是这样介绍的:

在这里插入图片描述

现在这个就是负载均衡获取实例的方法。
我们注入这个类的对象,然后对其测试:
测试内容:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = yhServiceConsumerApplication.class)
public class LoadBalanceTest {

    @Autowired
    private RibbonLoadBalancerClient client;

    @Test
    public void testLoadBalance(){
        for (int i = 0; i < 100; i++) {
            ServiceInstance instance = this.client.choose("service-provider");
            System.out.println(instance.getHost() + ":" +instance.getPort());
        }
    }
}

继续跟踪源码,发现这么一段代码:
在这里插入图片描述
我们看看这个rule是谁:

在这里插入图片描述
这里的rule默认值是一个RoundRobinRule,看类的介绍:

在这里插入图片描述
定义负载均衡的规则接口。
它有以下实现:
在这里插入图片描述

SpringBoot也帮我们提供了修改负载均衡规则的配置入口,在Service-Consumer的application.yml中添加如下配置:

server:
  port: 7000
spring:
  application:
    name: service-consumer
# 注册中心
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9000/eureka
# 负载均衡
service-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 设置负载均衡的规则,默认为轮询

格式是{服务名称}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的实现类。
再次测试,发现结果变成了随机。


每日一点点进步
不进则退

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

璃尔 °

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值