Spring Cloud(Finchley版本)系列教程(二) 客户端负载均衡Ribbon

Spring Cloud(Finchley版本)系列教程(二) 客户端负载均衡Ribbon

目前主流的负载均衡方案有两种,一种是集中式均衡负载,在消费者与服务提供者之间使用独立的代理方式进行负载,比如F5、Nginx等。另一种则是客户端自己做负载均衡,根据自己的请求做负载,Ribbon就属于客户端自己做负载。

一、引入Ribbon依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

二、在消费方增加@LoadBalanced负载均衡

其实在上一节中我们已经增加了@LoadBalanced注解了。

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaClientConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientConsumerApplication.class, args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

三、服务提供方提供多台机器

因为我把服务部署到了一台远程的机器上,而机器上的8000端口被别的应用占用了,因此把eurekaClient项目的端口改成了8008。部署eureka到ubuntu22.04的步骤请参考ubuntu22.04开机自启动Eureka服务。我这里开放给大家使用eureka的外网注册地址:www.huerpu.cc:1678 ,和大家交流学习。

我们把eurekaClient项目的接口修改一下,加上自己的Server信息from server:eurekaServer:8008

package cc.huerpu.eurekaserver.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @RequestMapping("/getUserById")
    public String getUserById(){
        return "{id:1,name:jason,age:23} from server:eurekaServer:8008";
    }
}

复制eurekaClient项目,重命名为eurekaClientSecond,并把端口改成8009,因此现在我们有8008和8009两台服务提供者了。

eurekaClientSecond的接口调用打印信息改成from server:eurekaServer:8009

package cc.huerpu.eurekaserver.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @RequestMapping("/getUserById")
    public String getUserById(){
        return "{id:1,name:jason,age:23} from server:eurekaServer:8009";
    }
}

为了方便查看,在服务消费方增加一个打印语句System.out.println(res)

@RequestMapping("/consumerEurekaClient")
public String consumerEurekaClient(){
    String res = restTemplate.getForObject("http://eurekaClient/getUserById",String.class);
    System.out.println(res);
    return "consumerEurekaClient:" + res;
}

启动项目eurekaClienteurekaClientSecondeurekaClientConsumer,查看eureka是否注册上这几个服务。

image-20230908121354914

可以看到服务注册上来了。

四、服务调用负载验证

调用http://eurekaclientconsumer:8001/consumerEurekaClient,查看是否有交替调用8008和8009两个,因为默认为轮询,也就是RoundRobinRule

image-20230908145032190

五、切换负载均衡策略

5.1 Ribbon均衡策略

Spring Cloud Ribbon提供了一个 IRule 接口,该接口主要用来定义负载均衡策略,它有 7 个默认实现类,每一个实现类都是一种负载均衡策略。

实现类负载均衡策略
RoundRobinRule按照线性轮询策略,即按照一定的顺序依次选取服务实例
RandomRule随机选取一个服务实例
RetryRule按照 RoundRobinRule(轮询)的策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试(重试时获取服务的策略还是 RoundRobinRule 中定义的策略),如果超过指定时间依然没获取到服务实例则返回 null 。
WeightedResponseTimeRuleWeightedResponseTimeRule 是 RoundRobinRule 的一个子类,它对 RoundRobinRule 的功能进行了扩展。 根据平均响应时间,来计算所有服务实例的权重,响应时间越短的服务实例权重越高,被选中的概率越大。刚启动时,如果统计信息不足,则使用线性轮询策略,等信息足够时,再切换到 WeightedResponseTimeRule。
BestAvailableRule继承自 ClientConfigEnabledRoundRobinRule。先过滤点故障或失效的服务实例,然后再选择并发量最小的服务实例。
AvailabilityFilteringRule先过滤掉故障或失效的服务实例,然后再选择并发量较小的服务实例。
ZoneAvoidanceRule默认的负载均衡策略,综合判断服务所在区域(zone)的性能和服务(server)的可用性,来选择服务实例。在没有区域的环境下,该策略与轮询(RandomRule)策略类似。
5.2 设置全局生效

设置负载均衡策略为随机,只需在启动类EurekaClientConsumerApplication上注入一个IRule的bean。

package cc.huerpu.eurekaserver;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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
@EnableDiscoveryClient
public class EurekaClientConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientConsumerApplication.class, args);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    @Bean
    public IRule rule(){
        return new RandomRule();
    }
}

重启项目eurekaClientConsumer,调用http://eurekaclientconsumer:8001/consumerEurekaClient,可以看到是随机调用的。

image-20230908150231419

5.3 针对特定服务生效

创建一个并注入一个RibbonConfiguration类。

package cc.huerpu.eurekaserver.configuration;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RibbonConfiguration {
    @Bean
    public IRule ribbonRule() {
        // 负载均衡规则,改为随机
        return new RandomRule();
    }
}

创建一个空类TestConfiguration ,使用注解@RibbonClient,name属性指定要去调用的服务名称,由spring.pplication.name指定的那个名称。

package cc.huerpu.eurekaserver.configuration;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;

@Configuration
@RibbonClient(name = "eurekaClient", configuration = RibbonConfiguration.class)
public class TestConfiguration {
}

重启项目eurekaClientConsumer,调用http://eurekaclientconsumer:8001/consumerEurekaClient,可以看到是也是随机调用的。

5.4 配置文件方式配置

更推荐的一种方式是使用配置文件进行设置。

eurekaClient:   #远程服务名称,我们这里是eurekaClient,根据自己的进行调整
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

如果你只想看到负载均衡调用的效果,我们来写一个接口看一下吧,这样更直观一些。

@Autowired
private LoadBalancerClient loadBalancerClient;

@RequestMapping("/eurekaClientConsumerChooseInstance")
public String eurekaClientConsumerChooseInstance() {
    ServiceInstance serviceInstance = loadBalancerClient.choose("eurekaClient");
    String server = serviceInstance.getServiceId()+":"
            +serviceInstance.getHost()+":"
            +serviceInstance.getPort();
    System.out.println(server);
    return server;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

勤奋的凯尔森同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值