分布式微服务学习总结——Ribbon和Feign

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 分布式微服务学习总结——Ribbon和Feign

前言

最近刚看完springcloud、dubbo的学习视频,但感觉不是那么扎实,所以打算写一个系列的博客来巩固自身所学。

当然有些内容是参考了别的博客,毕竟我也是初探分布式微服务的,并不是所谓的大神,只是一个新手在初探分布式微服务后写下的一些自己的理解和总结。


在了解了概述和Eureka之后,我们对于分布式微服务架构有了初步的认识,本文将介绍Netflix系列的另一大“神兽”——Ribbon,以及通过其封装的Feign,我将会详细介绍两者以及使用方式,希望能给各位一个较为清晰的认识。


一、Ribbon是什么?

1.思考一个问题

在回答Ribbon是什么之前,我们先来思考一个问题。


假设我们有很多服务(设有集群),并且服务端都已经注册到Eureka中,接下来就是客户端调用服务。


那么问题来了,我们该怎么调用?


理论上来说写上服务的地址确实是可以调用的。


但是同一个服务如果有多个服务器,即同一个服务设有集群,那么我们又该调用哪个。你如果把地址写死,那么设置集群便没有了意义。


我们必须有一种策略,让它能自动选择合适的服务去调用。


Ribbon就是解决这个问题而生的!


2.Ribbon简介

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。


二、Ribbon和Feign区别

其实两者差别就在于使用的方式,Ribbon是通过服务名字去调用,而Feign通过接口和注解来达到类似Controller调用Service的效果。


因为有部分使用者认为Ribbon的使用方式很不习惯,所有才有了Feign的出现。


Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。


在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。


Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。


Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。


Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。


Spring Cloud Feign具备可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。


简而言之,Feign就是在Ribbon的基础上进一步封装,换了一种使用方式,其底层还是使用Ribbon。


q1.png

如上图看到,我们在feign依赖里找到了ribbon的依赖。


三、Ribbon使用步骤(Ribbon+RestTemplate )

1.导入依赖

<!--消费端做负载均衡用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>


2.将创建配置类,将RestTemplate 加入Spring容器

@Configuration
public class ConfigBean {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }


RestTemplate 其实spring框架里的类,加上@LoadBalanced后Ribbon会对其进行处理,达到负载均衡的效果。


如果对源码实现感兴趣的同学可以去看这篇文章Spring Cloud Feign使用详解,它里面讲的挺详细的,不过关看可能看不懂(反正我是这样的)。


3.设置负载均衡策略

方法其实有很多种,这里介绍一种最简单的方法:


创建配置类,将规则放入Spring容器中


package com.dreamchaser.myrule;
import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 规定负载均衡的方法
 * 不要写在主应用程序的上下文中,否则它会被所有RibbonClient共享
 * 要自定义算法
 */
@Configuration
public class RibbonRule {
    @Bean
    public IRule getRule(){
        return new AvailabilityFilteringRule();
    }
//    自定义负载均衡算法
//    @Bean
//    public IRule getMyRule(){
//        return new MyRule();
//    }
}

这里可以返回它自己附带的负载均衡算法,也可以是自定义的方法。


注意:此配置文件不在主应用程序上下文,这点在官方文档里也有说明

q1.png

这里意思就是因为后面会配置多个RibbonClient,如果在主应用程序上下文配置,它就不在@ComponentScan中。这时,它由所有@RibbonClients共享。


我们可以在项目外面创建一个新包,就像这样,


q1.png


当然你也可以自定义负载均衡算法,只要你继承了AbstractLoadBalancerRule类即可,如下面:


package com.dreamchaser.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
public class MyRule extends AbstractLoadBalancerRule {
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
    @Override
    public Server choose(Object o) {
        return null;
    }
}

4.在启动类上加上@RibbonClient注解

在启动类上配置@RibbonClient注解


@RibbonClient(name ="SPRINGCLOUD-PROVIDER-TAG",configuration = RibbonRule.class)

这里name写你要配置策略的服务名字,configuration 写你上面配置负载均衡策略时写的配置类的class


如果有多个RibbonClient,可以写多个。


5.结合Eureka使用

这里我给出一个例子:


import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
    public class TagConsumerController {
        @Autowired
        //提供多种便捷访问远程http服务的方法,简单的restful服务模板
        private RestTemplate restTemplate;
        /*private static final String REST_URL_PREFIX="http://localhost:8001";*/
        //通过Ribbon来实现负载均衡,这时就得写服务名称
        private static final String REST_URL_PREFIX="http://SPRINGCLOUD-PROVIDER-TAG";
        @GetMapping("/consumer/tag")
        public @ResponseBody List<Tag> getTags(){
            return restTemplate.getForObject(REST_URL_PREFIX+"/tag",List.class);
        }
        @PostMapping("/consumer/tag")
        public @ResponseBody String addTag(Tag tag){
        return restTemplate.getForObject(REST_URL_PREFIX+"/tag",String.class);
    }
}


我们可以看到调用远程的方法,只要写上http://+服务名即可,至于其中它会如何选择,Ribbon内部会帮你去干。


这里我演示一下效果:


启一下进程,然后看一下Eureka

q1.png


我们看到我们启了一个服务提供者,两个提供相同服务的“实例”(作为集群演示),这里我为了显示出负载均衡的效果,我在两者返回数据时做出了点小修改,如下图:


q4.png

q3.png

这样,返回数组时,第一个就会显示实例的端口号。


现在访问消费端localhost:80/consumer/tag

q2.png

刷新一下

q1.png



这样就可以让客户端按照既定的负载均衡策略来访问服务端,达到负载均衡的效果!


四、Feign使用步骤

1.在接口工程中加入Service层

所谓接口工程就是一个作为所有模块依赖的模块,里面包含公共的实体类,和规定好的接口。我们在其下面创建service包,包里创建远程调用所需的接口


package com.dreamchaser.service;
import com.dreamchaser.pojo.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
//服务名称
@FeignClient(value = "SPRINGCLOUD-PROVIDER-TAG")
@Component
public interface TagClientService {
    @GetMapping(value = "/tag",produces = "application/json;charset=UTF-8")
    public @ResponseBody List<Tag> findTags();
    @PostMapping("/tag")
    public @ResponseBody String insertTag(Tag tag);
}


加上@FeignClient(value = “SPRINGCLOUD-PROVIDER-TAG”)注解,value值表示你要访问的服务名字,接口方式与服务提供者一致。


2.设置负载均衡策略

这一步参照Ribbon使用,因为Feign底层还是借助Ribbon的。


3.在客户端上加上@EnableFeignClients注解

@EnableFeignClients({"com.dreamchaser"})

1

里面填包名,Feign回去扫描接口工程中包里的接口,并且注入到spring容器中


4.调用接口

package com.dreamchaser.springcloud.controller;
import com.dreamchaser.pojo.Tag;
import com.dreamchaser.service.TagClientService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
public class TagConsumerController {
    @Resource
    private TagClientService tagClientService;
    //通过Ribbon来实现负载均衡,这时就得写服务名称
    @GetMapping("/consumer/tag")
    public @ResponseBody List<Tag> getTags(){
        return tagClientService.findTags();
    }
    @PostMapping("/consumer/tag")
    public @ResponseBody String addTag(Tag tag){
        return tagClientService.insertTag(tag);
    }
}




使用起来还是蛮简单的!


5.访问消费者


q1.png

与原来效果一致!


总结

Ribbon和Feign都有实现负载均衡的功能,Feign是在Ribbon的基础上进行封装,使用上变得更便捷,但同样的,效率会比用原来的Ribbon稍微差一点。


至于使用哪个,看个人喜好吧。我个人可能会喜欢Feign一点,因为我觉得Feign有助于把接口写到一起,这样负责不同服务的人调用其其他人服务时也会更加方便。


如果随着我的学习发现自己所写的有所纰漏或者错误,我会第一时间来修正博客,当然如果有什么错误,欢迎大家评论区评论指正,不胜感激。


愿我们都能以梦为马,不负人生韶华!

以此为记,与君共勉!


相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
4月前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
3月前
|
机器学习/深度学习 分布式计算 算法
联邦学习是保障数据隐私的分布式机器学习方法
【6月更文挑战第13天】联邦学习是保障数据隐私的分布式机器学习方法,它在不暴露数据的情况下,通过在各设备上本地训练并由中心服务器协调,实现全局模型构建。联邦学习的优势在于保护隐私、提高训练效率和增强模型泛化。已应用于医疗、金融和物联网等领域。未来趋势包括更高效的数据隐私保护、提升可解释性和可靠性,以及与其他技术融合,有望在更多场景发挥潜力,推动机器学习发展。
63 4
|
3月前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
199 0
|
2月前
|
负载均衡 Java API
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
60 11
|
2月前
|
负载均衡 Java API
通用快照方案问题之Feign添加请求拦截器如何解决
通用快照方案问题之Feign添加请求拦截器如何解决
19 1
|
2月前
|
负载均衡 算法 Java
通用快照方案问题之Ribbon和RestTemplate的结合使用如何解决
通用快照方案问题之Ribbon和RestTemplate的结合使用如何解决
26 0
|
3月前
|
JSON Java 程序员
马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(2)
马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(2)
41 3
|
3月前
|
程序员 测试技术 Docker
黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day3 全网最全
黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day3 全网最全(1)
292 1
|
3月前
|
SQL Java 程序员
马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(1)
马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day1最快 最全(1)
175 1
|
4月前
|
并行计算 算法 物联网
LLM 大模型学习必知必会系列(七):掌握分布式训练与LoRA/LISA微调:打造高性能大模型的秘诀进阶实战指南
LLM 大模型学习必知必会系列(七):掌握分布式训练与LoRA/LISA微调:打造高性能大模型的秘诀进阶实战指南
LLM 大模型学习必知必会系列(七):掌握分布式训练与LoRA/LISA微调:打造高性能大模型的秘诀进阶实战指南