在SpringCloud2023中使用openfeign进行远程调用

21stCenturyM101_ap160122.jpg

你好,这里是codetrend专栏“SpringCloud2023实战”。

前言

feign之前是Netflix的一个子项目,由于停止了维护,spring继续维护了一个openfeign作为替代。Spring Cloud OpenFeign 具有以下优点:

  • 简化微服务之间的调用,屏蔽冗余代码,基于注解开发远程调用。
  • 提供负载均衡、降级等配套的微服务开发体验。

远程调用的重要性

在 Spring Cloud 2023 中,远程调用的重要性主要体现在微服务架构中。微服务架构将应用程序划分为一组小型、松耦合的服务,每个服务都运行在自己的进程中,并通过轻量级的通信机制进行通信。远程调用在微服务架构中扮演着重要的角色,主要有以下几个方面的重要性:

  • 服务间通信:微服务架构中的服务通常分布在不同的主机、容器或云环境中,它们需要通过远程调用进行通信。远程调用使得各个服务可以相互协作、交换数据,并实现系统的功能。
  • 服务发现与注册:远程调用需要知道其他服务的位置和接口信息,而不是直接硬编码在代码中。因此,服务发现与注册成为微服务架构中的关键组件,它使得服务能够动态地注册和发现其他服务,从而进行远程调用。
  • 解耦服务:远程调用可以帮助将微服务之间的耦合度降到最低。每个微服务都可以专注于特定的业务功能,通过远程调用与其他服务交互,而无需了解对方的内部实现细节。
  • 水平扩展:微服务架构支持水平扩展,即通过增加实例来处理更多的请求负载。远程调用使得新的服务实例可以被动态地添加到系统中,并与其他服务进行通信,从而实现系统的水平扩展。
  • 容错与负载均衡:远程调用可以通过负载均衡和容错机制来提高系统的可用性和可靠性。负载均衡可以将请求分发到多个服务实例中,从而避免单点故障和请求过载,而容错机制则可以在服务失败时进行故障转移或重试。

生产者集成

无需特殊的集成和配置,需要注册到注册中心,这里以应用名为 client1 举例说明生产者。

生产者配置

spring.application.name: client1
spring:
  cloud:
    zookeeper:
      connect-string: localhost:2181
server:
  port: 10101
  servlet:
    context-path: /client1

生产者启动类

package io.rainforest.banana.client1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

生产者对外接口提供

  • control层代码。
package io.rainforest.banana.client1.web.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class HelloWorld {
    @GetMapping("/")
    public String hello(String hello){
        return hello+" world";
    }

    @GetMapping("/hello2")
    @ResponseBody
    public List<String> hello2(String hello){
        List<String> res = new ArrayList<>();
        res.add("test1");
        res.add("test2");
        res.add(hello);
        return res;
    }
}

消费者集成

客户端引入pom.xml

  • 引入openfeign主要是引入 <artifactId>spring-cloud-starter-openfeign</artifactId>
<?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>
        <groupId>io.rainforest</groupId>
        <artifactId>banana</artifactId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>banana-client3</artifactId>
    <description>spring cloud banana-client3</description>
    <packaging>jar</packaging>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <!--注册中心客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>
        <!--配置中心客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!--引入openfeign主要引入 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- LB 扩展 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

        <!-- 工具包依赖 -->
        <dependency>
            <groupId>io.rainforest</groupId>
            <artifactId>banana-common-core</artifactId>
        </dependency>

        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

客户端修改配置

  • 新增配置文件 application.yml,配置中心配置主要是 spring.cloud.openfeign 下面的配置。
spring:
  application:
    name: client3
  cloud:
    config:
      profile: dev
      name: ${spring.application.name}
#      uri: http://localhost:10110
      discovery:
        enabled: true
        service-id: config
    zookeeper:
      connect-string: 127.0.0.1:2181
    openfeign:
      httpclient:
        enabled: false
      okhttp:
        enabled: true

通过引入 feign-okhttp 替换默认的httpurlconnection,以及修改配置 spring.cloud.openfeign.okhttp.enabled 实现。

客户端修改启动类

  • 启动类不需要特殊修改。
package io.rainforest.banana.client3;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

远程调用demo

  • 假设注册中心已经注册服务 clent1
  • 编写openfeign客户端调用代码。
package io.rainforest.banana.client3.web.demo;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient(name = "client1",value = "client1",contextId = "client1",path = "/client1")
public interface Client1 {
    @RequestMapping(method = RequestMethod.GET,value = "/hello2")
    List<String> hello2(@RequestParam("hello") String hello);

    @GetMapping(value = "/")
    String hello(@RequestParam("hello") String hello);
}
  • 在control层使用openfeign客户端。
package io.rainforest.banana.client3.web.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HelloWorld {
    @Autowired
    private Client1 client1;

    @GetMapping("/")
    public String hello(String hello){
        return hello+" world";
    }

    @GetMapping("/hello2")
    public List<String> hello2(String hello){
        return client1.hello2(hello);
    }
    @GetMapping("/hello")
    public String hello1(String hello){
        return client1.hello(hello);
    }
}

完整源码信息查看 https://gitee.com/r0ad/spring-cloud-example

关于作者

来自一线全栈程序员nine的探索与实践,持续迭代中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容