zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【微服务笔记04】微服务组件之OpenFeign服务调用组件的介绍及其使用方法

方法组件笔记服务 介绍 调用 及其 04
2023-09-14 09:13:55 时间

这篇文章,主要介绍微服务组件之OpenFeign服务调用组件及其使用方法【源代码】。

目录

一、OpenFeign组件

1.1、微服务调用方式

(1)HttpUtil调用服务

(2)Ribbon + RestTemplate调用服务

1.2、什么是OpenFeign

1.3、OpenFeign的使用

(1)环境准备

(2)引入依赖

(3)创建service-provider子工程

(4)创建service-consumer子工程

(5)启动工程测试


一、OpenFeign组件

1.1、微服务调用方式

前面几篇文章,介绍了微服务中的第一个组件,即:Eureka注册中心,该组件主要是解决微服务之间如何发现和注册的问题。微服务之间既然已经能够互相发现了,那么要如何进行服务调用呢???

微服务之间的调用其实是两个应用程序之间通信问题,而目前大多数的应用都是基于HTTP方式进行通信的,所以这个时候就可以采用HTTP方式进行服务之间的调用。

(1)HttpUtil调用服务

最简的的方式是利用HttpUtil工具类,从注册中心里面获取到需要调用的微服务地址,实现服务的调用,大致代码如下所示:

// 从注册中心获取服务调用地址
String url = "XXXX";
// 利用HttpUtil工具类调用对端服务
Str json = HttpUtil.post(url, json, 6000);
// TODO 处理接口返回数据
.....

(2)Ribbon + RestTemplate调用服务

通过HttpUtil虽然可以实现微服务的调用,但是每次都要写一些重复的代码,能不能将这些重复的封装起来呢???这个时候,我们就想起了Spring中提供的RestTemplate对象啦,这个RestTemplate就是基于HTTP方式调用服务的一个封装工具类。使用RestTemplate对象进行微服务的调用,大致代码如下所示:

// 注入 RestTemplate 对象
@Bean
// 开启 Ribbon 实现负载均衡
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}


@Autowired
private RestTemplate restTemplate;

@GetMapping("/getUserInfoByRestTemplate")
public Map<String, String> getUserInfoByRestTemplate(String username) {
    // 获取调用微服务地址
    String url = "http://service-provider/api/service/provider/getUserInfo";
    // 通过 RestTemplate 调用接口
    Map resultMap = restTemplate.postForObject(url, null, Map.class, username);
    return resultMap;
}

前面这两种方式虽然都可以实现微服务之间的调用,但是都带有一些缺点,那就是需要自己编写调用服务的逻辑代码,如果接口很多的时候,那么就会编写很多重复的服务调用代码,有没有什么办法可以解决这个问题呢???这个时候出现了OpenFeign组件啦,下面具体介绍一下什么是OpenFeign。

1.2、什么是OpenFeign

OpenFeign是Spring Cloud微服务中的一个服务调用组件和负载均衡组件,OpenFeign是起源于Feign的,Feign是最开始的一个服务调用组件,但是由于Feign组件的功能单一,并且它不能够和SpringMVC注解一起使用,所以这个时候就出现了OpenFeign,OpenFeign组件不仅可以很方便的使用SpringMVC注解实现服务的调用,而且由于OpenFeign集成了Ribbon、Hystrix组件,所以OpenFeign也具备了负载均衡和服务熔断、服务降级的功能。

  • OpenFeign是源自于Feign组件。
  • OpenFeign可以和SpringMVC注解结合使用,实现声明式的服务调用
  • OpenFeign集成了Ribbon组件,实现了负载均衡的功能(注意:不知道Ribbon没关系,后面的文章我会继续介绍Ribbon组件)。
  • OpenFeign集成了Hystrix组件,实现了服务熔断、服务降级等功能(注意:不知道Hystrix没关系,后面的文章我会继续介绍Hystrix组件)。

OpenFeign在微服务中的大致流程如下图所示(不一定正确,我是按照我理解画的图,仅供参考):

1.3、OpenFeign的使用

理论已经介绍了,那就要通过实践来检验一下啦,下面搭建一个OpenFeign的demo练练手。

(1)环境准备

这里搭建的demo是采用单机eureka注册中心的,并且这个工程中需要搭建以下几个子工程:

  • eureka注册中心服务端工程。
  • service-provider服务提供者工程(用于对外提供接口服务)。
  • servce-consumer服务消费者工程(用于调用服务提供者,获取接口数据)。

(2)引入依赖

  • 父工程中,需要引入Spring Cloud和SpringBoot依赖。
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gitee.code</groupId>
    <artifactId>openfeign-demo</artifactId>
    <version>1.0.0</version>

    <name>openfeign-demo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- 引入SpringBoot依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencyManagement>
        <!-- 使用 dependencyManagement 依赖管理,统一管理组件的版本 -->
        <dependencies>
            <!-- 引入 SpringCloud 微服务依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR12</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 子工程中,需要引入:spring-boot-starter-web、spring-cloud-starter-netflix-eureka-client、spring-cloud-starter-openfeign依赖。
<dependencies>
    <!-- 引入 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-netflix-eureka-client</artifactId>
    </dependency>
    <!-- 引入 OpenFeign 依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
</dependencies>

(3)创建service-provider子工程

  • service-provider子工程主要是用于对外提供服务的,所以这里需要编写一个提供接口的Controller代码。
package com.gitee.code.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0.0
 * @Date: 2023/1/7 21:54
 * @Copyright (C) ZhuYouBin
 * @Description:
 */
@RestController
@RequestMapping("/api/service/provider")
public class ApiController {

    @PostMapping("/getUserInfo")
    public Map<String, String> getUserInfo(String username) {
        Map<String, String> map = new HashMap<>();
        map.put("id", "1001");
        map.put("username", username);
        map.put("pass", "123456");
        return map;
    }

}

(4)创建service-consumer子工程

  • service-consumer子工程,主要是采用OpenFeign组件,去调用service-provider微服务提供的接口,所以这里需要编写【声明式的OpenFeign客户端接口】实现微服务的调用。
package com.gitee.code.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

/**
 * @version 1.0.0
 * @Date: 2023/1/7 22:03
 * @Copyright (C) ZhuYouBin
 * @Description: OpenFeign 的调用接口
 */
// 声明当前接口采用 OpenFeign 进行调用 service-provider 微服务
@FeignClient(value = "service-provider")
public interface ApiProviderFeign {

    // 定义调用的接口
    @PostMapping("/api/service/provider/getUserInfo")
    Map<String, String> getUserInfo(@RequestParam("username") String username);

}
  • 编写测试控制器,通过上面声明式的service去调用接口。
package com.gitee.code.controller;

import com.gitee.code.service.ApiProviderFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @version 1.0.0
 * @Date: 2023/1/7 22:00
 * @Copyright (C) ZhuYouBin
 * @Description:
 */
@RestController
@RequestMapping("/api/service/consumer")
public class DemoController {

    @Autowired
    private ApiProviderFeign apiProviderFeign;

    @GetMapping
    public Map<String, String> getUserInfo(String username) {
        // 通过 OpenFeign 调用接口
        return apiProviderFeign.getUserInfo(username);
    }

}

(5)启动工程测试

  • 第一步:启动eureka-server注册中心服务端工程。
  • 第二步:启动service-provider服务提供者工程。
  • 第三步:启动service-consumer服务消费者工程。
  • 第四步:访问eureka注册中心,查看工程是否正常注册到eureka注册中心。
  • 第五步:浏览器服务【http://localhost:7070/api/service/consumer/getUserInfo?username=root】,查看是否调用接口成功。

此时浏览器访问服务消费者的接口,返回数据如下所示:

到此,OpenFeign组件的基础使用就介绍完啦。

综上,这篇文章结束了,主要介绍微服务组件之OpenFeign服务调用组件及其使用方法。