Ribbon 负载均衡服务调用

这篇具有很好参考价值的文章主要介绍了Ribbon 负载均衡服务调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


想要学习完整SpringCloud架构可跳转: SpringCloud Alibaba微服务分布式架构

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。

Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。

Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。

在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。

我们很容易使用Ribbon实现自定义的负载均衡算法。

1 SpringCloud Load Balance

LB负载均衡(Load Balance)是什么?

将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。常见的负载均衡有软件Nginx,LVS,硬件F5等。

集中式LB Load Balance

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,1如nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;

Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端实现的。

Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

2 总结:

Ribbon其实就是一个软负载均衡的客户端组件,

他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

Ribbon 负载均衡服务调用,分布式\微服务,ribbon,负载均衡,spring cloud

3 Ribbon工作流程:

Ribbon在工作时分成两步:

  • 第—步先选择EurekaServer ,它优先选择在同一个区域内负载较少的server.
  • 第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。
  • 其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

4 自定义Ribbon 负载均衡算法:

4.1 iRule接口:

Ribbon 负载均衡服务调用,分布式\微服务,ribbon,负载均衡,spring cloud

4.2 Ribbon自带的负载均衡算法:

com.netflix.loadbalancer.RoundRobinRule:

轮询

com.netflix.loadbalancer.RandomRule:

随机
com.netflix.loadbalancer.RetryRule:

先按照RoundRobinRule的策骼获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务

weightedResponseTimeRule:

对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择

BestAvailableRuleo:

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发是最小的服务

vailabilityFilteringRule:

先过滤掉故障实例,再选择并发较小的实例:

zoneAvoidanceRule

默认规则,复合判断server所在区域的性能和server的可用性选择服务器

官方文档明确给出了警告:

这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,
否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。

4.3 负载均衡算法替代:
4.3.1、在非启动类包及子包下创建配置类

Ribbon 负载均衡服务调用,分布式\微服务,ribbon,负载均衡,spring cloud

4.3.2、定义
/**
 * Myrule : Ribbon 自定义负载均衡算法配置类
 *
 * @author zyw
 * @create 2023/6/18
 */
@Configuration
public class Myrule {

    @Bean
    public IRule getIRule(){
        //定义为随机
        return new RandomRule();
    }
}
4.3.3、启动类增加RibbonClient注解

自定义需要指定的服务

/**
 * OderMain80 :
 *
 * @author zyw
 * @create 2023/6/16
 */
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOULD-PAYMENT-SERVICE",configuration = Myrule.class)
@MapperScan("com.zyw.springcloud.dao")
public class OderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OderMain80.class,args);
    }
}

5 Ribbon负载均衡算法

5.1 轮询算法原理:

Ribbon 负载均衡服务调用,分布式\微服务,ribbon,负载均衡,spring cloud

5.2 轮询算法源码:
public class RoundRobinRule extends AbstractLoadBalancerRule {
    
private AtomicInteger nextServerCyclicCounter;
    
public RoundRobinRule() {
   nextServerCyclicCounter = new AtomicInteger(0);
}


public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }

        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            //获取有正常运行的(可达的)服务集合
            List<Server> reachableServers = lb.getReachableServers();
            //获取可负载服务集合
            List<Server> allServers = lb.getAllServers();
            //获取有正常运行的(可达的)服务的数量
            int upCount = reachableServers.size();
             //获取可负载服务的数量 == 服务器集群总数量
            int serverCount = allServers.size();

            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                return null;
            }

            int nextServerIndex = incrementAndGetModulo(serverCount);
            server = allServers.get(nextServerIndex);

            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;
    }

    //自旋锁
    //rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启后rest接口计数从1开始。
        private int incrementAndGetModulo(int modulo) {
        for (;;) {
            //获取当前值
            int current = nextServerCyclicCounter.get();
            //计算下次值
            int next = (current + 1) % modulo;
            //比较并交换
            if (nextServerCyclicCounter.compareAndSet(current, next))
                //得到当前下标值
                return next;
        }
    }
    
}
5.3 手写负载均衡算法
/**
 * LoadBalancer : 自定义负载均衡算法
 *
 * @author zyw
 * @create 2023/6/20
 */
public interface LoadBalancer {

    //收集Eurek上所有活着的服务总数
    ServiceInstance instances(List<ServiceInstance> serviceInstances);

}
/**
 * MyLB : 自定义负载均衡算法实现类
 *
 * @author zyw
 * @create 2023/6/20
 */
@Component
public class MyLB implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement() {
        int currrnt;
        int next;
        do {
            currrnt = this.atomicInteger.get();
            //Integer.MAX_VALUE = 2147483647
            next = currrnt >= 2147483647 ? 0 : currrnt + 1;
            //自选锁,直到得到期望值
        } while (!this.atomicInteger.compareAndSet(currrnt, next));
        System.out.println("第" + next + "次访问");
        return next;
    }

    /**
     * rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务器重启后rest接口计数从1开始。
     * @param serviceInstances
     * @return
     */
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size();
        return serviceInstances.get(index);
    }
}

/**
 * OrderController : 订单系统控制层
 *
 * @author zyw
 * @create 2023/6/16
 */
@Slf4j
@RestController
@RequestMapping("consumer/orderController")
@Api(tags={"订单系统控制层"})
public class OrderController {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private LoadBalancer loadBalancer;

    @GetMapping("/lb")
    @ApiOperation(value = "获取负载服务的端口号", response = String.class)
    public String getPaymentBl(){
        List<ServiceInstance> serviceInstances = discoveryClient.getInstances("CLOULD-PAYMENT-SERVICE");
        if (serviceInstances == null || serviceInstances.size() <= 0){
            return null;
        }

        ServiceInstance serviceInstance = loadBalancer.instances(serviceInstances);

        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"paymentController/lb",String.class);
    }


}

Ribbon 负载均衡服务调用,分布式\微服务,ribbon,负载均衡,spring cloud文章来源地址https://www.toymoban.com/news/detail-579549.html

到了这里,关于Ribbon 负载均衡服务调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ribbon:Spring Cloud负载均衡与服务调用组件

    负载均衡? Ribbon实现服务调用? Ribbon实现负载均衡? 切换负载均衡策略? 定制负载均衡策略? 负载均衡 负载均衡(Load Balance),将用户的请求平分到多个服务器上运行,以扩展服务器带宽、增强数据处理能力、增加吞吐量、提高网络的可用性和灵活性的目的。 服务端负载

    2024年02月03日
    浏览(46)
  • 1.3 eureka+ribbon,完成服务注册与调用,负载均衡源码追踪

    本篇继先前发布的1.2 eureka注册中心,完成服务注册的内容 。 目录 环境搭建 采用eureka+ribbon的方式,对多个user服务发送请求,并实现负载均衡 负载均衡原理 负载均衡源码追踪 负载均衡策略 如何选择负载均衡策略? 饥饿加载 复制(补充) 给order模块和user模块建立独立的数

    2024年02月14日
    浏览(45)
  • SpringCloud学习笔记(上):服务注册与发现:Eureka、Zookeeper、Consul+负载均衡服务调用:Ribbon

    SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。 springboot版本选择: git源码地址:https://github.com/spring-projects/spring-boot/releases/ SpringBoot2.0新特性:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release springcloud版本选

    2024年02月08日
    浏览(43)
  • SpringCloud入门——微服务调用的方式 & RestTemplate的使用 & 使用nacos的服务名初步(Ribbon负载均衡)

    1.微服务调用的几种方式,异步消息传递,http调用,服务网关调用,服务发现调用nacos; 2.spring提供的restTemplate,发送HTTP请求的客户端工具类; 3.nacos使用服务名报错,需要加Ribbon负载均衡; RPC (Remote Procedure Call)远程过程调用协议,一种通过网络从远程计算机上请求服务,

    2024年02月10日
    浏览(39)
  • springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。 Eureka包含两个组件:Eureka Server和Eure

    2024年04月10日
    浏览(43)
  • 【Ribbon负载均衡调用】—— 每天一点小知识

                                                                                   💧 R i b b o n 负载均衡调用 color{#FF1493}{Ribbon负载均衡调用} R ibb o n 负载均衡调用 💧           🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞

    2024年02月15日
    浏览(31)
  • 【SpringCloud】Eureka基于Ribbon负载均衡的调用链路流程分析

    微服务间相互调用的基础上,服务间的调用更多是以调用某多实例服务下的某个实例的形式。而这就需要用到负载均衡技术。对于开发者而言,只要通过@LoadBalance注解就开启了负载均衡。如此简单的操作底层究竟是什么样的,我想你也很想知道。 在《SpringCloud集成Eureka并实现

    2024年02月05日
    浏览(36)
  • 【微服务】Ribbon负载均衡

    在上文的案例中我们添加了@LoadBalanced注解,即可实现负载均衡功能,这是什么原理呢? 我们这里的@LoadBalanced相当于是一个标记,标记这个RestTemplate发出的请求要被我们的Ribbon拦截和处理。 SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。 那么我们发

    2024年01月16日
    浏览(37)
  • 微服务-Ribbon(负载均衡)

    负载均衡的面对多个相同的服务的时候,我们选择一定的策略去选择一个服务进行 RoundRobinRule:简单的轮询服务列表来选择服务器 AvailabilityFilteringRule 对两种情况服务器进行忽略: 1.在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路状态”,短路状

    2024年02月12日
    浏览(32)
  • 微服务-Ribbon负载均衡

    流程 原理 @LoadBalanced 标记RestTemplate发起的http请求要被Ribbon进行拦截和处理 源码分析 ctrl+shift+N搜索LoadBalancerInterceptor,进入。发现实现了ClientHttpRequestInterceptor(客户端Http请求拦截器)的intercept方法 拦截方法 打一个断点,启动order-application,浏览器发送请求http://localhost:8080

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包