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

本文涉及的产品
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 分布式微服务学习总结——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有助于把接口写到一起,这样负责不同服务的人调用其其他人服务时也会更加方便。


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


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

以此为记,与君共勉!


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
2月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
|
3月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
677 3
|
1月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
7月前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
272 5
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
10月前
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
796 1
|
11月前
|
存储 运维 数据可视化
如何为微服务实现分布式日志记录
如何为微服务实现分布式日志记录
686 1
|
消息中间件 存储 负载均衡
微服务与分布式系统设计看这篇就够了!
【10月更文挑战第12天】 在现代软件架构中,微服务和分布式系统设计已经成为构建可扩展、灵活和可靠应用程序的主流方法。本文将深入探讨微服务架构的核心概念、设计原则和挑战,并提供一些关于如何在分布式系统中实现微服务的实用指导。
483 2
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
654 6

热门文章

最新文章

下一篇
oss云网关配置