【JAVA企业级开发】SpringCloud微服务调用组件Feign,OpenFeign,Ribbon相互之间的区别,以及这三个微服务调用组件单独使用其中一种和两种相互组合一起使用的效果和特点

一级目录

二级目录

三级目录

一Feign和OpenFeign

在springcloud中,openfeign是取代了feign作为服务调用组件的,feign最早是netflix提供的,他是一个轻量级的支持RESTful的http服务调用框架,内置了ribbon,而ribbon可以提供负载均衡机制,因此feign可以作为一个负载均衡的远程服务调用框架使用。feign后来不升级了,被github的openfeign取代,openfeign在feign的基础上,又支持springmvc注解的功能。

二Ribbon和OpenFeign

OpenFeign包含了Ribbon。
Ribbon和OpenFeign我个人为其实算是两个东西,虽然都是用作服务调用的组件,但是Ribbon侧重于做服务调用时的负载均衡,而OpenFeign侧重于面向接口进行服务调用。

1在只引入Ribbon依赖的时候,可以使用Ribbon+restTemplate来进行服务调用。

restTemplate配置类

package fengbo.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * Created by @author LiuChunhang on 2020/7/21.
 */
@Configuration
public class RestTemplateBean {
    /**该注解用于在消费者客户端实现负载均衡*/
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

controller层

package fengbo.controller;

import fengbo.service.FeignOpenServiceFace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created by @author LiuChunhang on 2020/7/21.
 */
@Controller
public class AccountController {
    @Autowired
    public RestTemplate restTemplate;

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    @ResponseBody
    @RequestMapping(value = "account/login")
    public Object index() {
        return restTemplate.getForObject("http://accountprovider/login", Object.class);
    }
}

启动类

package fengbo;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import ribbonbalance.IndividualBalance;

/**
 * Created by @author LiuChunhang on 2020/7/21.
 */
@SpringBootApplication
@EnableEurekaClient
/**此注解的属性用于服务定制化负载均衡,且负载均衡配置类不能在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊化定制的目的了。*/
@RibbonClient(name = "accountprovider",configuration = IndividualBalance.class)
public class AccountSystem {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(AccountSystem.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }
}

具体Ribbon+restTemplate的微服务调用和负载均衡流程详见我的上一篇文章https://blog.csdn.net/liuchunhang/article/details/107563003

2 引入openFeign情况下的执行流程:

***OpenFeign相比Ribbon在代码实现上是在客户端多了一层接口,之前用ribbon的时候客户端只有controller层,
通过restTemplate请求服务端的controller层。Openfeign需要在客户端创建一个service层,并创建一个service接口(要用到@FeignClient注解),其方法和服务端的controller里的方法相对应,之后客户端的controller调这个接口就行了


引入依赖时,只用引入OpenFeign即可。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

不再需要引入Ribbon依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

三 OpenFeign(Ribbon)项目的搭建

1pom依赖

只用引入OpenFeign即可,不再需要引入Ribbon依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>FengboSoft</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-system-account</artifactId>

    <dependencies>
        <!--公共实体类API-->
        <dependency>
            <artifactId>eureka-common-entity</artifactId>
            <groupId>org.example</groupId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--Web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!--eureka启动配置依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
      <!--  &lt;!&ndash;微服务负载均衡调用&ndash;&gt;
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>-->
        <!--微服务组件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--服务调用Feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

2修改启动类

package fengbo;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import ribbonbalance.IndividualBalance;

/**
 * Created by @author LiuChunhang on 2020/7/21.
 */
@SpringBootApplication
@EnableEurekaClient
/**此注解的属性用于服务定制化负载均衡,且负载均衡配置类不能在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊化定制的目的了。*/
@RibbonClient(name = "accountprovider",configuration = IndividualBalance.class)
@EnableFeignClients(basePackages = "fengbo.service")
public class AccountSystem {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(AccountSystem.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }
}

在这里插入图片描述

3 Feigen的service调用接口

被 @FeignClient 注解修饰到的接口能被 @EnableFeignClients 注解扫描到,就会基于 java.lang.reflect.Proxy 根据这个接口生成一个代理类,生成代理类之后,会被注入到 ApplicationContext 中,直接 AutoWired 就能使用,使用的时候调用fengbo方法就相当于是发起一个 Restful 请求。

package fengbo.service;

import fengbo.entity.Account;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * Created by @author LiuChunhang on 2020/7/27.
 */

/**使用feign,定制化服务*/
@FeignClient(value = "accountprovider")
public interface FeignOpenServiceFace {
    @ResponseBody
    @RequestMapping(value = "login")
    public List<Account> fengbo();
}

需要注意,@RequesMapping不能在类名上与@FeignClient同时使用

4 Controller类

无需再使用RestTemplate类去调用服务

package fengbo.controller;

import fengbo.service.FeignOpenServiceFace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created by @author LiuChunhang on 2020/7/21.
 */
@Controller
public class AccountController {
    /*@Autowired
    public RestTemplate restTemplate;

    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }*/

    @Autowired
    public FeignOpenServiceFace feignOpenServiceFace;

    public FeignOpenServiceFace getFeignOpenServiceFace() {
        return feignOpenServiceFace;
    }

    public void setFeignOpenServiceFace(FeignOpenServiceFace feignOpenServiceFace) {
        this.feignOpenServiceFace = feignOpenServiceFace;
    }

    @ResponseBody
    @RequestMapping(value = "account/login")
    public Object index() {
        //return restTemplate.getForObject("http://accountprovider/login", Object.class);
        return feignOpenServiceFace.fengbo();
    }
}

5负载均衡配置类

package ribbonbalance;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by @author LiuChunhang on 2020/7/27.
 */
@Configuration
public class IndividualBalance {
    @Bean
    public IRule getRule(){
        //指定负载均衡算法
        return  new RoundRobinRule();
    }

}

6 不再需要resttemplate配置类和,Ribbon的@LoadBalanced注解了,直接删掉就好。

在这里插入图片描述

四测试

1分别按照顺序启动 注册中心 ,服务提供者,服务消费者

在这里插入图片描述

2访问注册中心

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3请求三次服务消费者,测试open feign服务调用和 ribbon的负载均衡

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五 总结,我们从Springboot开始,到SpringCloud的组件应用微服务调用的模式的变化为: SpringbootModule+RestTemplate+URL》》》》Eureka+RestTemplate+appname》》》》》》》Eureka+Ribbon+RestTemplate+appname》》》》》》》》Eureka+OpenFeign(Ribbon)+接口调用+接口方法》》》》》

OpenFeign的引入直接砍掉了restTemplate,客户端controller在调用服务端时不需要再关注请求的方式、地址以及是forObject还是forEntity,完全面向接口调用,层次结构更加明了,而且OpenFeign自身集成Ribbon,所以默认开启轮询的负载均衡。(虽然Eureka也集成了ribbon,但大概是eureka已经停更了,所以openFeign集成了ribbon)。而且还可以和hystrix相结合,写一个类实现service接口,其中实现的方法的方法体便是降级或熔断的fallback方法(需要在接口中指定该实现类)。这样结构更清晰,耦合也更低。我们不用过多去研究ribbon,它只是一个提供负载均衡的,大多时候只是更改负载均衡的算法。我们只需要编写好feign的接口以及其降级实现类即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牵牛刘先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值