您当前的位置:首页 > 电脑百科 > 站长技术 > 服务器

你要的负载均衡Ribbon,来了

时间:2020-08-26 10:35:03  来源:  作者:

大家好,我是阿七。

在上一篇文章中,我们已经实现了内容中心总能够调用用户中心,那如何实现负载均衡呢?请听阿七为你娓娓道来。(没看到上篇文章的同学请戳这里:实战(一)nacos注册与发现

一、负载均衡的两种方式

众所周知,在负载均衡领域一般有两种方式去实现,分别是:

1、服务器端负载均衡;

2、客户端侧负载均衡;

在单体架构时代,我们一般会部署多个实例在服务器上,然后使用Nginx做负载均衡(nginx也是部署在服务器上的)。请求全部打在nginx上,nginx根据负载均衡策略将请求转发到不同的实例上。如下面这幅图所示:

你要的负载均衡Ribbon,来了

 

有同学会疑问了,为什么nginx可以抗住这么多的请求呢?因为它异步,非阻塞,使用了epoll 和大量的底层代码优化,哈哈跑题了,阿七后面再专门写文章说说nginx。

说完了服务器端负载均衡,那么什么是客户端负载均衡呢?且看下图:

你要的负载均衡Ribbon,来了

 

在这幅图中,内容中心是要调用用户中心的,那么内容中心相对于用户中心就是客户端,对吧,这个应该可以理解。现在我们已经可以通过DiscoveryClient来获取用户中心的多个实例,如果我们在内容中心自己写一个负载均衡规则,然后交给RestTemplate来请求一个用户中心实例,这样就实现了客户端负载均衡了。说干就干,咱这就来写一个负载均衡策略。

二、手写一个客户端负载均衡器

第一步,修改代码:之前是调用findFirst()默认返回第一个用户中心实例,现在注释掉了,改成随机获取一个用户中心实例。

public ShareDTO findById(Integer id) {

        Share share = this.shareMApper.selectByPrimaryKey(id);

        Integer userId = share.getUserId();

        //用户中心的所有实例信息

        List<ServiceInstance> instances = discoveryClient.getInstances("user-center");

//        String targetUrl = instances

//                .stream()

//                .map(instance -> instance.getUri().toString() + "/users/{id}")

//                .findFirst()

//                .orElseThrow(() -> new IllegalArgumentException("当前没有实例对象"));

        List<String> targetUrls = instances

                .stream()

                .map(instance -> instance.getUri().toString() + "/users/{id}")

                .collect(Collectors.toList());

        //随机算法

        int i = ThreadLocalRandom.current().nextInt(targetUrls.size());

        String targetUrl = targetUrls.get(i);

        log.info("请求的目标地址:{}",targetUrl);

        //根据userId查询用户信息

        UserDTO userDTO = this.restTemplate.getForObject(targetUrl, UserDTO.class, userId);

        ShareDTO shareDTO = new ShareDTO();

        BeanUtils.copyProperties(share, shareDTO);

        shareDTO.setWxNickname(userDTO.getWxNickname());

        return shareDTO;

    }

第二步,测试:

1、我们先启动一个用户中心实例,端口为8888;然后修改端口号为8887,点击Edit Configurations,勾选Allow parallel run,保存,再启动一次项目,这样就可以启动两个用户中心实例。如下图:

你要的负载均衡Ribbon,来了

 

2、启动内容中心实例,打开nacos看看

你要的负载均衡Ribbon,来了

 

3、接口测试,访问http://localhost:8889/shares/1

你要的负载均衡Ribbon,来了

 

这时,我们去控制台看看:

你要的负载均衡Ribbon,来了

 

哎,我们会发现,内容中心在随机调用用户中心的实例。说白了,负载均衡器就是给你一个list,你随机从中获取一个实例来调用。 但是我们这个代码还是比较简单的,只是模拟一下。如果我们每次进行服务调用都写这么一堆代码肯定也是不现实的。

那么下面我们就要ribbon进行重构咯,同学们继续往下看。

三、整合ribbon

在使用ribbon进行重构之前,我们肯定得了解什么是ribbon对吧。一句话阐述ribbon是Netflix开源的客户端侧负载均衡器。 其实,ribbon就是我们刚刚写的代码的一个组件,但是它封装的更好,提供了更多的负载均衡策略。

下面我们就来整合ribbon到我们的项目中。还记得三步骤吗?

第一步加依赖:因为nacos-discovery中已经集成了netflix-ribbon,所以这里就不要在单独集成了。

你要的负载均衡Ribbon,来了

 

第二步加注解:在RestTemplate上加注解@LoadBalanced

@MapperScan("com.seven")

@SpringBootApplication

public class ContentCenterApplication {

    public static void main(String[] args) {

        SpringApplication.run(ContentCenterApplication.class, args);

    }

    @Bean

    @LoadBalanced

    public RestTemplate restTemplate(){

        return new RestTemplate();

    }

}

第三步写配置:在yml文件中写配置,这里不需要写。

第四步修改代码:ribbon会根据user-center去nacos中找到请求的真是路径。

public ShareDTO findById(Integer id) {

        Share share = this.shareMapper.selectByPrimaryKey(id);

        Integer userId = share.getUserId();

        //根据userId查询用户信息

        UserDTO userDTO = this.restTemplate

                .getForObject("http://user-center/users/{userId}", UserDTO.class, userId);

        ShareDTO shareDTO = new ShareDTO();

        BeanUtils.copyProperties(share, shareDTO);

        shareDTO.setWxNickname(userDTO.getWxNickname());

        return shareDTO;

    }

ok,到这里ribbon就整合完了。那有人会问,到这就结束了吗?那显然不是,阿七不是浮于表面的人,咱学习一个东西就要刨根问底。

四、ribbon组成

ribbon组件虽小,但是五脏俱全,它的组成都有哪些呢?贴心的我已经为大家准备好了。

你要的负载均衡Ribbon,来了

 

同时,ribbon支持8种负载均衡策略,如下所示:

你要的负载均衡Ribbon,来了

 

这里的Zone本意为地区、地带的意思,这里作机房的架子,也就是放服务器的机架。那我们实际上没有Zone的,也就是说默认采用的负载均衡策略是RoundRibonRule(轮训策略)。我们看一下源码,找到RoundRobinRule.JAVA类,其中最主要的就是这一段,实际上就是取余得到访问的server的index。

private int incrementAndGetModulo(int modulo) {

        int current;

        int next;

        do {

            current = this.nextServerCyclicCounter.get();

            next = (current + 1) % modulo;

        } while(!this.nextServerCyclicCounter.compareAndSet(current, next));

        return next;

}

compareAndSet是AtomicInteger的方法,其实类似参数列表compareAndSwapInt(var1, var2, var5, var4),作为base的var1加上偏移量var2之后和var5比较是不是值相同,相同就update为var4. valueOffset是native的C的方法指针找到的地址。

public final boolean compareAndSet(int expect, int update) {

    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

}

五、细粒度配置ribbon

那我们如何细粒度、自定义配置负载均衡策略呢?比如,内容中心想指定一种负载均衡策略来获取用户中心的实例。很简单,我们只需要加一下yml配置文件即可。

#指定服务名

user-center:

  ribbon:

    #负载均衡策略的全路径

    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

这样我们就修改ribbon负载均衡策略为RandomRule,也就是随机获取一个实例。

六、ribbon解饿加载

在实际代码运行中发现,当我们第一次请求http://localhost:8889/shares/1这个接口时,运行结果是很慢的,为什么呢?因为ribbon默认是懒加载。只有在下面代码第一次执行的时候,才会创建一个名叫user-center的ribbon client。

//根据userId查询用户信息

        UserDTO userDTO = this.restTemplate

                .getForObject("http://user-center/users/{userId}", UserDTO.class, userId);

我们可以通过修改yml配置文件来解决这个问题。

ribbon:

  eager-load:

    enabled: true

    #多个用逗号隔开 user-center,xxx,yyy

    clients: user-center

这样就可以第一次请求也变得很快啦。

好了ribbon就学习到这里了。但是,我们的代码还是存在很多问题的,那么下一篇我们将一起学习声明式http客户端--feign,一起将代码优化的更好吧。

喜欢的朋友记得点个关注吧,一起探讨,共同进步。



Tags:负载均衡   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server。其中有好几个种经典的算法,下面我们用Java实现这几种算法。 轮询算法轮询算法按顺序把每个新的连接请求...【详细内容】
2021-09-27  Tags: 负载均衡  点击:(51)  评论:(0)  加入收藏
什么是NginxNginx(engine x)是一个高性能的HTTP和反向代理服务器,具有内存少,高并发特点强。1、处理静态文件,索引文件以及自动检索打开文件描述符缓冲2、无缓冲的反向代理加速...【详细内容】
2021-09-02  Tags: 负载均衡  点击:(70)  评论:(0)  加入收藏
1.安装依赖环境yum -y install wget gcc-c++ ncurses ncurses-devel cmake make perl bison openssl openssl-devel gcc* libxml2 libxml2-devel curl-devel libjpeg* libpn...【详细内容】
2021-08-03  Tags: 负载均衡  点击:(63)  评论:(0)  加入收藏
域名解析是客户端访问系统的第一步。在架构设计中,DNS Server除了解析域名,还能干点什么呢?又有哪些“挖坑”的用法需要避免呢?典型的互联网架构中,我们通过nginx的反向代理来做...【详细内容】
2021-07-29  Tags: 负载均衡  点击:(258)  评论:(0)  加入收藏
均衡算法也是多种多样,常见的两大类:即静态负载均衡法和动态负载均衡法。静态算法也是比较简单,主要有有一般轮询算法,基于比例的加权轮询算法,以及基于优先级的轮询算法。动态算...【详细内容】
2021-07-27  Tags: 负载均衡  点击:(71)  评论:(0)  加入收藏
今天总结一下负载均衡中LVS与Nginx的区别,好几篇博文一开始就说LVS是单向的,Nginx是双向的,我个人认为这是不准确的,LVS三种模式中,虽然DR模式以及TUN模式只有请求的报文经过Director,但是NAT模式,Real Server回复的...【详细内容】
2021-06-08  Tags: 负载均衡  点击:(112)  评论:(0)  加入收藏
之前有很多朋友问关于 Nginx 的 upstream 模块中 max_fails 及 fail_timeout,这两个指令,分别是配置关于负载均衡过程中,对于上游(后端)服务器的失败尝试次数和不可用时间,很多...【详细内容】
2021-04-15  Tags: 负载均衡  点击:(206)  评论:(0)  加入收藏
需求在Linux SMP(对称多处理器)环境下,每个CPU对应一个run_queue(可执行队列)。如果一个进程处于TASK_RUNNING状态(可执行状态),则它会被加入到其中一个run_queue(且同一时刻仅会被加...【详细内容】
2021-04-01  Tags: 负载均衡  点击:(225)  评论:(0)  加入收藏
分层模型,每一层实现各自的功能和协议,并完成与相邻层的接口通讯。OSI 的服务定义详细说明了各层所提供的服务,某一层的服务就是该层及其下各层的一种能力,通过接口提供给更高一层。各层所提供的服务与这些服务是怎么实现...【详细内容】
2021-03-16  Tags: 负载均衡  点击:(257)  评论:(0)  加入收藏
Nginx的安装及负载均衡配置在安装完分布式文件系统之后,就可以在应用程序中进行调用了。注意需要在 Web端的页面上进行访问,还必须借助Nginx 提供访问服务。使用Nginx 不仅可...【详细内容】
2021-03-11  Tags: 负载均衡  点击:(158)  评论:(0)  加入收藏
▌简易百科推荐
阿里云镜像源地址及安装网站地址https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b111kK44P更新源之前把之前的国外的镜像先备份一下 切换到yumcd...【详细内容】
2021-12-27  干程序那些事    Tags:CentOS7镜像   点击:(1)  评论:(0)  加入收藏
前言在实现TCP长连接功能中,客户端断线重连是一个很常见的问题,当我们使用netty实现断线重连时,是否考虑过如下几个问题: 如何监听到客户端和服务端连接断开 ? 如何实现断线后重...【详细内容】
2021-12-24  程序猿阿嘴  CSDN  Tags:Netty   点击:(12)  评论:(0)  加入收藏
一. 配置yum源在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repovim /etc/yum.repos.d/google-chrome.repo按i进入编辑模式写入如下内容:[google-chrome]name=googl...【详细内容】
2021-12-23  有云转晴    Tags:chrome   点击:(7)  评论:(0)  加入收藏
一. HTTP gzip压缩,概述 request header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据 response body,同时加入以下header:Content-Encoding: gzip:表明bo...【详细内容】
2021-12-22  java乐园    Tags:gzip压缩   点击:(8)  评论:(0)  加入收藏
yum -y install gcc automake autoconf libtool makeadduser testpasswd testmkdir /tmp/exploitln -s /usr/bin/ping /tmp/exploit/targetexec 3< /tmp/exploit/targetls -...【详细内容】
2021-12-22  SofM    Tags:Centos7   点击:(7)  评论:(0)  加入收藏
Windows操作系统和Linux操作系统有何区别?Windows操作系统:需支付版权费用,(华为云已购买正版版权,在华为云购买云服务器的用户安装系统时无需额外付费),界面化的操作系统对用户使...【详细内容】
2021-12-21  卷毛琴姨    Tags:云服务器   点击:(6)  评论:(0)  加入收藏
参考资料:Hive3.1.2安装指南_厦大数据库实验室博客Hive学习(一) 安装 环境:CentOS 7 + Hadoop3.2 + Hive3.1 - 一个人、一座城 - 博客园1.安装hive1.1下载地址hive镜像路径 ht...【详细内容】
2021-12-20  zebra-08    Tags:Hive   点击:(9)  评论:(0)  加入收藏
以下是服务器安全加固的步骤,本文以腾讯云的CentOS7.7版本为例来介绍,如果你使用的是秘钥登录服务器1-5步骤可以跳过。1、设置复杂密码服务器设置大写、小写、特殊字符、数字...【详细内容】
2021-12-20  网安人    Tags:服务器   点击:(7)  评论:(0)  加入收藏
项目中,遇到了一个问题,就是PDF等文档不能够在线预览,预览时会报错。错误描述浏览器的console中,显示如下错误:nginx代理服务报Mixed Content: The page at ******** was loaded...【详细内容】
2021-12-17  mdong    Tags:Nginx   点击:(7)  评论:(0)  加入收藏
转自: https://kermsite.com/p/wt-ssh/由于格式问题,部分链接、表格可能会失效,若失效请访问原文密码登录 以及 通过密钥实现免密码登录Dec 15, 2021阅读时长: 6 分钟简介Windo...【详细内容】
2021-12-17  LaLiLi    Tags:SSH连接   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条