Spring Cloud Ribbon的应用

一、负载均衡简介

在软件项目中,当系统的访问量过大负载过高时,单个节点已经承受不住这样的流量冲击,在这样的节骨眼儿上,我们通常会增加服务器数量来进行服务的横向扩展,让服务由单节点变成多节点。但是变成多节点后,为了让访问流量平均分配到各个节点上,以免出现服务器负载不均衡的情况,这时候就会用到负载均衡器,从而增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

负载均衡分为软件负载和硬件负载。软件负载是利用独立的负载均衡模块、负载均衡程序或负载均衡软件来完成,硬件负载是直接在服务器和外部网络间安装负载均衡器设备(例如:F5)。因为我们是从事软件研发的,这里主要讲解软件负载均衡之Spring Cloud Netflix中的Ribbon。当然,软件负载软件由很多,例如Nginx/HAProxy+Keepalived组合。

二、Ribbon介绍

Ribbon是Spring Cloud核心组件之一,它主要提供的负载均衡功能,与Nginx等软件不同的是它采用的是客户端负载均衡方式。客户端负载均衡与服务端负载均衡最大的区别在于服务端地址列表的存储位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端地址列表,这些地址列表是从配置文件或注册中心中获取的(一般采用注册中心,利用配置文件获取服务地址列表扩展性很差,因为在服务实例上线或下线的情况下,需要手动修改配置文件,配置不灵活,扩展性很低,一个健壮的微服务系统会采用注册中心的方式维护服务的上下线)。

三、Ribbon的使用方式

在Spring Boot和Spring Cloud生态中,Ribbon可以和RestTemplate以及OpenFeign一起使用,这里我们演示一下和RestTemplate结合使用的方式,因为OpenFeign中默认集成了Ribbon,无需进行任何配置就可以进行负载均衡。

四、Ribbon在Spring Cloud中的使用方式

现在我这里有两个服务,一个是用户服务(user-service),一个是订单服务(order-service),用户服务需要调用订单服务,因此将订单服务在本地启动两个实例以演示负载均衡效果。下面演示两种方式在不使用注册中心的前提下使用Ribbon实现负载均衡。

1、配置文件加编程式实现负载

#用户服务配置文件
server.port=8080
spring.application.name=user-service
order-service.ribbon.listOfServers=http://localhost:9092,http://localhost:9093
//RestTemplateConfig
@Configuration(proxyBeanMethods = false)
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

//用户服务Controller
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;
    
    @GetMapping
    public String order() {
        ServiceInstance serviceInstance = loadBalancerClient.choose("order-service");
        String url = String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort());
        log.info("order-service url is {}" + url);
        String order = restTemplate.getForObject(url + "/order", String.class);
        return order;
    }
}

//order-service 忽略

2、配置文件加@LoadBalance注解实现负载

#用户服务配置文件
server.port=8080
spring.application.name=user-service
order-service.ribbon.listOfServers=http://localhost:9092,http://localhost:9093
//RestTemplateConfig
@Configuration(proxyBeanMethods = false)
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}


//用户服务Controller
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping
    public String order() {
        String order = restTemplate.getForObject("http://order-service/order", String.class);
        return order;
    }
}

//order-service 忽略

五、配置负载均衡策略

Ribbon中实现的负载均衡策略如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YEyW8fXI-1643293333043)(/Users/liuliya/Desktop/note/思考笔记/技术相关截图/RIbbon负载均衡策略.png)]

Ribbon默认的负载均衡策略使用的是轮询,对应的实现类是com.netflix.loadbalancer.RoundRobinRule,我们还可以通过配置文件指定相应的负载均衡策略,例如配置一个随机负载:

#配置负载均衡策略
order-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

六、实现服务健康检测

在不使用注册中心的情况下,通过配置文件维护服务列表存在很多缺陷,其中一个就是不能动态感知服务的上下线,一个服务挂掉后,客户端通过Ribbon会调用到挂掉的服务,这时系统就出现了问题。那么在这种情形下,我们如何让客户端感知到哪个服务可用,哪个服务不可用呢?这时候可以通过自定义健康检查类来实现,Ribbon是通过Ping的方式感知服务是否还存活,我们只需要实现IPing接口,如下所示代码:

public class HealthChecker implements IPing {

    @Override
    public boolean isAlive(Server server) {
        String url = "http://" + server.getId() + "/healthCheck";
        boolean isAlive = true;
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpUriRequest request = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(request);
            isAlive = response.getStatusLine().getStatusCode() == 200;
        } catch (IOException e) {
            e.printStackTrace();
            isAlive = false;
        } finally {
            request.abort();
        }
        return isAlive;
    }
}

然后还需要在配置文件中配置一下:

#配置ping的实现
order-service.ribbon.NFLoadBalancerPingClassName=com.lly.mall.portal.HealthChecker
#配置ping的时间间隔 3s
order-service.ribbon.NFLoadBalancerPingInterval=3

当然Ping的Http调用需要服务提供者返回相应的内容。

综上,本篇主要讲解了负载均衡的一些概念和Ribbon的简单使用,下篇我们继续研究在使用注册中心(Eureka)的前提下,OpenFeign是如何利用Ribbon实现负载均衡的,使用注册中心相对于使用配置文件维护服务列表有哪些好处,下篇我们见分晓。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值