【微服务】Ribbon——客户端负载均衡器

Ribbon:客户端负载均衡器

在微服务架构中,负载均衡是将工作负载(如网络请求)合理分配到多个计算资源(如服务器)上的关键技术,它可以有效提升系统的可用性和扩展性。负载均衡的实现方式主要有两种:服务端负载均衡客户端负载均衡。本文将重点介绍基于 Ribbon 的客户端负载均衡。

一、负载均衡的类型

  1. 服务端负载均衡

    服务端负载均衡通常在客户端和服务端之间部署一个独立的负载均衡服务器,负载均衡服务器可以是硬件设备(如 F5)或者软件(如 Nginx)。该负载均衡服务器维护一个可用服务端的清单,并通过心跳机制定期检查服务实例的健康状态,确保清单中的服务节点是可用的。

    客户端发送请求时,负载均衡服务器负责选择一个服务实例并将请求转发过去。常见的负载均衡算法有轮询、随机等。

  2. 客户端负载均衡

    客户端负载均衡则将负载均衡逻辑封装到客户端。客户端通过与服务注册中心(如 Eureka)交互,获取可用服务实例的列表。客户端在发送请求前,通过负载均衡算法选择一个服务实例进行访问,确保请求分发的均衡。

    与服务端负载均衡不同,客户端负载均衡不需要额外部署负载均衡服务器,且每个客户端都维护一份服务实例的清单。这些实例列表通过心跳机制与服务注册中心同步更新,确保清单中的服务实例是健康的。

    心跳机制:用于定期检查服务实例的健康状态,负载均衡器通过向服务实例发送轻量级探测请求,根据响应判断实例的可用性。

二、Ribbon:基于 HTTP 和 TCP 的客户端负载均衡器

Ribbon 是 Spring Cloud 提供的一个客户端负载均衡器,能够与服务注册中心(如 Eureka)结合使用,从而为微服务间的通信提供负载均衡。通过 Ribbon,客户端可以从服务注册中心动态获取服务实例,并通过负载均衡算法(如轮询、随机等)将请求分发到合适的服务端实例上。

如何使用 Ribbon

与 RestTemplate 配合使用

RestTemplate 是 Spring 提供的一个用于发送 HTTP 请求的客户端模板工具。它封装了 HTTP 请求的细节,并提供了一些常用的方法,如 getForObject()postForObject() 等,用于访问远程 HTTP 服务。

使用 Ribbon 时,RestTemplate 可以与 Ribbon 集成,自动实现负载均衡。

示例代码

1. pom.xml 配置

pom.xml 中添加相关依赖:

<dependencies>
    <!-- Spring Cloud Eureka 客户端依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- Spring Cloud Ribbon 依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>
2. application.yml 配置

配置 Eureka 客户端与服务注册中心的信息:

server:
  port: 80  # 服务端口号
eureka:
  client:
    register-with-eureka: false  # 不将自己注册到 Eureka
    fetch-registry: true  # 向 Eureka 获取服务列表
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/
3. 配置 RestTemplate

创建一个配置类,注入 RestTemplate,并启用负载均衡:

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced  // 开启负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
4. 创建 Controller

在 Controller 中通过 RestTemplate 调用服务:

@RestController
public class DeptController_Consumer {

    private static final String REST_URL_PROVIDER_PREFIX = "http://MICROSERVICECLOUDPROVIDERDEPT"; // 通过服务名访问服务

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Integer id) {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/get/" + id, Dept.class);
    }

    @RequestMapping("/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PROVIDER_PREFIX + "/dept/list", List.class);
    }
}
5. 启动类

启用 Eureka 客户端:

@SpringBootApplication
@EnableEurekaClient
public class MicroServiceCloudConsumerDept80Application {

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

启动服务后,依次启动 Eureka 服务注册中心、服务提供者以及服务消费者。

切换负载均衡策略

默认情况下,Ribbon 使用轮询策略(RoundRobinRule)选择服务实例。不过,我们可以根据需求定制负载均衡策略。只需在配置类中注入不同的 IRule 实现类即可。

例如,切换到随机策略:

@Bean
public IRule myRule() {
    return new RandomRule();  // 使用随机策略
}

定制负载均衡策略

我们还可以实现自定义的负载均衡策略。例如,下面是一个自定义的 MyRandomRule,它保证每个服务实例最多调用 3 次,然后切换到下一个实例。

public class MyRandomRule extends AbstractLoadBalancerRule {
    private int total = 0;
    private int currentIndex = 0;

    @Override
    public Server choose(ILoadBalancer lb, Object key) {
        List<Server> upList = lb.getReachableServers();
        if (upList.isEmpty()) return null;

        if (total < 3) {
            total++;
            return upList.get(currentIndex);
        } else {
            total = 0;
            currentIndex++;
            if (currentIndex >= upList.size()) currentIndex = 0;
            return upList.get(currentIndex);
        }
    }
}

将自定义策略注入到容器中:

@Configuration
public class MySelfRibbonRuleConfig {

    @Bean
    public IRule myRule() {
        return new MyRandomRule();  // 使用自定义的随机规则
    }
}

最后,在主启动类中通过 @RibbonClient 注解激活自定义的负载均衡策略:

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "MICROSERVICECLOUDPROVIDERDEPT", configuration = MySelfRibbonRuleConfig.class)
public class MicroServiceCloudConsumerDept80Application {

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

总结

本文介绍了如何在 Spring Cloud 中使用 Ribbon 实现客户端负载均衡。通过与 Eureka 配合,Ribbon 可以动态获取服务实例并根据负载均衡策略选择合适的服务。你还可以定制自己的负载均衡策略,满足更复杂的需求。通过这些技术,微服务架构能够实现高可用、可扩展的服务调用模式。

#微服务#
微服务知识 文章被收录于专栏

微服务相关知识详解

全部评论

相关推荐

03-21 12:43
已编辑
香港科技大学 C++
谢谢。那desheng呢?desheng:就是我个人觉得算法岗位和其他岗位不太一样的一个点,就是算法在你一开始接触这份工作的时候,你需要看的特别细,就是你对整个产品,你对整个行业的了解,可能是从非常细的底层的细节开始开始的。就举个例子,像我刚接触广告的时候,那我可能真的会一花一天的时间去看,为什么这个广告主今天花了1000块钱,他本来想买200个转发,但是最终只转只买到了100个转发,那他到底是哪一块出了问题?如果某一个信号不是下午3点钟传回来,是上午10点钟传回来,那这个效果没有多少改善。就是我们会去看一些detail的case,但是就是随随着你的做的事情越来越多,你就你就会对整个事情会有更高的视角的了解,就是可能有像战略或者说运营,他并不需要去一开始就了解很么多细节。但是想做好算法工作或者说做好工程工作,一定是从底层非常细节的地方去开始抠的。那么关于职业发展的方向呢,就是我认为字节它也就是不设限。就是昨天我还在跟我的老板去聊这件事(指绩效沟通),就是说并不是说你是算法,你就只能去做算法相关的工作,那我其实也有也有认识很多人,他其实是从算法转成了产品,包括现在可能整个中国区的增长负责人。那他之前其就是做做算法的,然后我身边也有同事,他从算法出身,他设计了新一代的广告系统。这个广告系统可能现在大家也比较常见,就是我给你一个奖励,比如说一个优惠券,然后你去看一看广告,就是这个广告系统这种广告形式其实是有一个算法同学最初设计出来的。那么就是说,我觉得,大家可能不是说非常非常受限。就是我做了算法,或者我做了工程,那我以后只能做这方面的事。就是更合适的一个思维方式,是说我的算法和思维能力,或者说工程方面的思维能力能够帮助公司去解决什么样的问题。刚刚Weier也提到了他,他可能觉得现在有一个算法leader的是在DS的团队更合适,那这完全也是有可能的。所以就是说在纵向的纵向包括横向的途径上,就是并不是说算法一定以后你只能做算法。其实不是的重点是做算法过程中培养出的这些能力。然后,具体的如果说你真的就是想在算法上一直去发展的,那就可以举一个例子,就是最初级的算法。比如说,大家刚入职或者是做实习生的时候,就有点像一个例子,就是你的Mentor会告诉你有一片树林,这片树林也不是很大,然后里面有一只死兔子。你的工作职责就是去把这只死兔子给解决来就就行了,这里的兔子就是拿到业务收益的意思。然后随着你渐渐的熟了之后呢,你可能能够自己去发现某一地方有一片树林,然后大概百分之八十百分之90的可能性,你能够在里面打猎到兔子,然后你然后你就去思考我怎么去用什么样的猎物更合适呀,什么什么天气过去,你会自己思考一些问题。那随着你在进一步的进阶,你可能就需要去决策。那我这个方向有不同的树林,然后每个树林里面也有可能有不同的猎物种类。我怎么去安排哪一些森林,我要去探索哪一些不去探索,然后我安排什么样的团队组织什么样的猎人去攻打哪一片,哪一片森林更加的合适,而这就是TeamLeader的这个层面需要去解决的问题。以广告为例,那如果说某一个季度的表现不好,那就要去拆解我们下一个优化的卡点到底在哪?是在模型的优先级更高呢,还是说信号归因做的不好呢,还是说素材有问题呢?这个是到了更高阶的层面需要去考虑的一些问题,就是总之你的视角是会越来越高的。说话人2谢谢desheng,谢谢前面三位。那最后呢,也请zonghao给大家讲讲,而且,很多同学可能就是现在有很多经常在校招的场所都在参加,招职能框架的。然后正好来分享一下。zonghao:我主要分两个方面。其实我还挺怀疑会不会真的会有人问这样的问题的,因为我有一时候跟我同学交流,就说我现在正在做什么,什么,他们都会问说,你一个北大毕业的为什么现在要来做这种事?然后,就我坦白的讲,我说这个其实是跟这个字节整体的人才观是非常相关的。然后,刚才我也有介绍说,我们要穷尽各类领域最优秀的人才。不瞒大家说,就是抛开这个HR、财务还有法务,这个这种专业服务的职能可能会有非常很多名校的毕业生,就即便是在企业服务,可以和大家说字节的企业服务。清华北大的一抓一大把,然后我们还有很多Harvard,Upenn,然后包括南洋理工这类,就是海外名校毕业的同学,也是在校招之后,就硕士或者本科毕业就加入了直接字节跳动的企业服务部。然后为什么这么多人这么多优秀的人才现在会加入我们企业服务部呢?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务