• SpringCloud-Ribbon和Feign快速上手


    Ribbon

    个人中心:https://blog.csdn.net/hello_list

    前情提要:

    首先我们要知道ribbon是什么,是来做负载均衡的(基于客户端),下面是介绍,可以看下

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

    • 简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 的客户端组件提供一系列完整的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出 LoadBalancer (简称LB:负载均衡) 后面所有的及其,Ribbon 会自动的帮助你基于某种规则 (如简单轮询,随机连接等等) 去连接这些机器。我们也容易使用 Ribbon 实现自定义的负载均衡算法!

    1、导入依赖,如果是跟着我这个走的,我这里使文章日期最新版,Eureka里面已经集成了Ribbon所以不用再去导入Ribbon单独的依赖,还会造成依赖冲突。我这里的是1.4.7.RELEASE,如果想要单独使用就导入这个包,并且排除Eureka

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
        <version>2.2.9.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、编写配置,我们知道ribbon是基于客户端,所以我们80里面配置下ribbon,配置下eureka,这里不用像注册中心注册自己,但是需要去注册中心发现服务

    #Eureka配置
    eureka:
      client:
        # 服务端不用向注册中心注册
        register-with-eureka: false
        #参考链接:https://blog.csdn.net/qq_45225798/article/details/120267548
        fetch-registry: true
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    开启负载均衡

    在这里插入图片描述

    3、开启功能,启动类,Eureka客户端

    在这里插入图片描述

    这里我们再修改下,我们之前rest是根据IP地址端口找找到服务,这里我们是通过注册中心服务发现,直接使用我们的服务名去调用服务

    在这里插入图片描述

    我们把注册中心7001或者都开启,反正开一个,然后8001服务开启,之后我们启动80客户端去调用服务,测试,这里的话我是都开了
    在这里插入图片描述

    我这里启动80报错了,不知道为什么,我在写文之前测试是可以的,现在已启动,报错了,是因为我在api里加了一个@TableId主键注解,但是写之前测试就没错

    在这里插入图片描述

    我们可以这样解决,排除下

    在这里插入图片描述

    启动成功,我们来看下注册中心,集群以及服务都注册了进来

    在这里插入图片描述

    我们来试着客户端从注册中心调用服务,调用成功,我才想起来这里我们是做负载均衡,当然负载均衡就实现了,但是因为我们服务提供者只有一个8001,我们再多来几个服务提供者,再来两个吧8002,8003

    在这里插入图片描述

    再开两个服务,应该会吧,可简单就是复制粘贴,那我么再来新建两个maven项目

    1、导入依赖

    2、编写配置

    1,3步是不是又可以省去,配置这里得改下,知道改哪里吗

    8002,这里我们改下

    在这里插入图片描述

    8003也改下

    在这里插入图片描述

    3、启动服务

    这次我们启动一个注册中心7001,然后开启8001,8002,8003服务,我们再开启80客户端去测试负载均衡,这里我们只访问一个服务,为了直观,我们这样修改下

    本来我是打算直接看控制台输出,但是为了不直观,想加一句话,但是发现我们用的是mybatis-plus自定义生成service,而且三个服务我们都已经测试好的,这个时候我们就想到了aop,可以帮我们切入,也不用修改现有代码

    这里我们临时加一个配置类

    1、导入aop依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-aopartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    2、编写配置

    package com.xuexi.config;
    
    
    // 表示当前的类是一个配置类
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    //该注解只能用在类上,作用:代表当前类是一个切面类,等价于spring.xml中的标签
    //所以现在有了切面,还需要  通知 + 切入点
    // 切面 == 通知 + 切面
    @Aspect
    public class MyAdviceConfig {
    
        /**
         * @param joinPoint
         * @Before:前置通知
         * value:切入点表达式  二者加起来构建成为一个切面
         * JoinPoint:连接点:可以理解为两个圆形的切点,从这个切点就可以获取到当前执行的目标类及方法
         * 前置通知和后置通知的参数的都是 JoinPoint, 前置后置通知都没有返回值
         */
        // 方法级别:具体到某个具体的方法
        // @Before(value = "execution(* com.xuexi.service.impl.*.*(..))")
        // 表示service包下的所有类所有方法都执行该前置通知
    /*    @Before(value = "within(com.liu.aop.service.*)")
        public void before(JoinPoint joinPoint) {
            System.out.println("before开始执行查询.......");
            System.out.println("正在执行的目标类是: " + joinPoint.getTarget());
            System.out.println("正在执行的目标方法是: " + joinPoint.getSignature().getName());
        }*/
    
        static int count = 1;
    
        /**
         * 后置通知,属性参数同上面的前置通知
         * @param joinPoint 前置通知和后置通知独有的参数
         */
        @After(value = "execution(* com.xuexi.service.impl.*.*(..))")
        public void after(JoinPoint joinPoint) {
            System.out.println("8001服务执行=========>>"+count+"次");
            count++;
        }
    
        /**
         * @param proceedingJoinPoint 环绕通知的正在执行中的连接点(这是环绕通知独有的参数)
         * @return 目标方法执行的返回值
         * @Around: 环绕通知,有返回值,环绕通知必须进行放行方法(就相当于拦截器),否则目标方法无法执行
         */
    /*    @Around(value = "execution(* com.xuexi.service.impl.*.*(..))")
        public Object aroud(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("aroud环绕通知开始.......");
            System.out.println("执行的目标类 = " + proceedingJoinPoint.getTarget());
            System.out.println("执行的目标方法 = " + proceedingJoinPoint.getSignature().getName());
            // 必须方法目标方法
            Object proceed = proceedingJoinPoint.proceed();
            System.out.println("aroud环绕通知结束.......");
            // 将目标方法的返回值进行返回,否则调用目标方法的方法无法获取到返回值
            return proceed;
        }*/
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    这是8001的编写,8002,8003就不用多说了吧,就是在执行方法后,在控制台打印信息

    8002

    在这里插入图片描述

    8003
    在这里插入图片描述

    开启测试,然后我们看后台控制台打印信息,下面是我们启动的

    在这里插入图片描述

    这样我们就都启动起来,并且服务注册上了

    在这里插入图片描述

    我们通过80客户端去测试,虽然我们实现了服务轮询,但是aop没有切入,我第一反应就是mybatisplus通用mapper和service并不在自己创建的方法中去执行sql,而这些只是通用方法的配置,留下来是为了保留mybaits的子定义

    同时我单独建了一个服务测试了下,确实和我想的一样。

    在这里插入图片描述

    我先是在网上搜了下方法,mybatisplus整合aop,没搜到,吃饭去了,也没怎么想吧,平常遇到bug最好的解决办法就是,那会别死较劲,证明你该去干别的事了,果然当我下午再打开电脑的时候,鼠标一点,我们可以对这个方法进行aop,如果外面是配置,这个里面就是具体的sql拼接实现方法。

    在这里插入图片描述

    我们修改,三个配置类都修改下

    在这里插入图片描述

    我们继续测试,可以看到三个服务都注册了进来

    在这里插入图片描述

    用客户端访问,访问服务成功

    在这里插入图片描述

    我们多敲几下,9下吧,我们敲了9下,然后加上最开始一下总共10下,再敲两下吧,我们看这三个服务的调用情况

    8001执行了4次

    在这里插入图片描述

    8002也是4次

    在这里插入图片描述

    8003也是四次

    在这里插入图片描述

    看到了吧。3*4=12,就是轮询对吧,平均轮询的负载均衡就实现了;

    自定义负载均衡策略

    虽然Eureka继承了Ribbon但是我一直搜不到自定义策略类,所以又加上了这个依赖

    1、导入依赖

    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
        <version>2.2.9.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里IRule,我们shift+shift搜一下这个类,我们可以看到这个类下面有很多自定义类,比如RandomRule随机、RoundRobinRule 轮询等;

    在这里插入图片描述

    这里我们试着改变负载均衡策略为随机,只需要这样即可;

    在这里插入图片描述

    我们再来测试下,服务都注册进来了

    在这里插入图片描述

    我们访问 ,直接连敲12下,看下效果,12次全到8001上了

    在这里插入图片描述

    再多敲几下,可能是连敲的太快,然后基本上都打到8001上了,慢点儿的话还是随机的

    8001

    在这里插入图片描述

    8002

    在这里插入图片描述

    8003

    在这里插入图片描述

    到这里呢,其实会有依赖问题,这里你如果没有那就可以了,如果有,可以这样换了依赖

    Feign

    feign也是用来做负载均衡的,但是与Ribbon不同,Ribbon是基于客户端,而Feign是社区的面向接口编程,看下面;

    Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端。

    废话不多说,直接上手体验,快速上手;

    我们新建一个项目,因为通过客户端去测试,我们把80复制下,修改下,我们这里不拿服务端测试,我们这里更改下api里面做一个service接口:

    1、导入依赖

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-feignartifactId>
        <version>1.4.7.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、编写配置,代码

    api中新建一个service接口

    在这里插入图片描述

    在我们新建的feign中,接口编程api中service类接口调用

    在这里插入图片描述

    3、开启功能

    在这里插入图片描述

    其实这里还是基于Ribbon的策略,但是社区认为这样的调用方法更符合java方式,调用接口service,我们现在的策略还是默认轮询,我们把7001打开,然后8001,8002,8003打开然后测试下:

    注册中心服务都注册进来了

    在这里插入图片描述

    我们通过80测试,然后连敲12下

    在这里插入图片描述

    我们看下,8001

    在这里插入图片描述

    8002

    在这里插入图片描述

    8003

    在这里插入图片描述

    其实只是认为java应该调用接口service然后去实现,所以只是变化了一个风格,还是依赖ribbon实现负载均衡

    小结

    看到这里了还不点个关注三连吗,收藏不等于学会,还是要亲自动手实践,bye~

  • 相关阅读:
    mmdetection用mmclassification的backbone
    Symfony多语言支持实现指南:打造国际化Web应用
    Python中Collections模块namedtuple用法
    13.3测试用例进阶
    cpolar内网穿透
    学3D建模要注意什么问题?入行好几年,踩过的坑后的经验
    Mock.js使用
    学习笔记|Pearson皮尔逊相关系数|Spearman斯皮尔曼相关系数|和Kendall肯德尔tau-b相关系数|分析流程|-SPSS中双变量相关性分析系数
    【Java面试】线程状态,BLOCKED和WAITING有什么区别
    记录nvm use node.js版本失败,出现报错: exit status 1: ��û���㹻��Ȩ��ִ�д˲�����
  • 原文地址:https://blog.csdn.net/hello_list/article/details/126569654