这篇文章,主要介绍微服务组件之OpenFeign服务调用组件及其使用方法【源代码】。
目录
一、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服务调用组件及其使用方法。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134540.html