SpringCloud プロジェクトの構築方法を説明します (9) OpenFeign サービス インターフェイス呼び出しの統合

マイクロサービスとは何ですか? シリーズが一目でわかる!

1. SpringCloudプロジェクトのビルド方法を教えます (1) 写真とテキストで詳しく説明、アホのような操作

2. SpringCloud プロジェクトの構築方法を教える (2) プロデューサーとコンシューマー

3. SpringCloudプロジェクトの構築方法を教えます (3) Eurekaサービス登録センターの統合

4. SpringCloudプロジェクトの構築方法を教えます (4) Eurekaクラスタのバージョン構築

5. SpringCloudプロジェクトのビルド方法を教えます (5) プロデューサークラスターバージョンをビルドします

6. SpringCloudプロジェクトの構築方法を教えます (6) Eurekaはサービスディスカバリを実現します

7. SpringCloudプロジェクトの構築方法を教える (7) Consulサービス登録センターを統合する

8. SpringCloudプロジェクトの構築方法を教えます (8) 統合リボンロードバランサ

9. SpringCloud プロジェクトの構築方法を説明します (9) OpenFeign サービス インターフェイス呼び出しの統合

10. SpringCloud プロジェクトの構築方法を教えます (10) Hystrix サービスのダウングレードの統合

11. SpringCloud プロジェクトの構築を教える (11) Hystrix のサービス ヒューズの統合

12. SpringCloud プロジェクトの構築方法を教える (12) Hystrix のグラフィカル ダッシュボードのリアルタイム モニタリングを統合する

13. SpringCloud プロジェクトの構築方法を教える (13) 新世代のゲートウェイを統合する

14. SpringCloudプロジェクトの構築方法を教えます (14) Integrated Config Distributed Configuration Center

15. SpringCloudプロジェクトの構築方法を教えます (15) Integrated Busメッセージバス

16. SpringCloud プロジェクトの構築方法を説明します (16) 統合された Stream メッセージ ドライバー

17. SpringCloud プロジェクトの構築方法を説明します (17) Sleuth 分散リンク追跡の統合

これからも更新していきますので、いいねやフォロー大歓迎です!

1. OpenFeign の概要

フェインとは何ですか?

    Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单。它的使用方法是定义一个服务接口然后在上面添加注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用支持负载均衡。 

フェイグには何ができるでしょうか?

    Feign旨在使编写Java Http客户端变得更容易。前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发过程中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它,(以前是Dao接口上面标准Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可)即可完成对服务提供方的接口绑定,简化了Spring  Cloud Ribbon时,自动封装服务调用客户端的开发量。

    **Feign集成了Ribbon,利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign值需要定义服务绑定接口且一声明式的方法,优雅而简单的实现了服务调用。**

Feign と OpenFeign の違い

ここに画像の説明を挿入

2. Openfeign は負荷分散を実装します

Cloud-consumer-feign-order という名前の新しいモジュールを作成し、pom.xml ファイルを変更します。

<?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>mcroservice</artifactId>
        <groupId>com.study.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
 
    <artifactId>cloud-consumer-feign-order</artifactId>
    <description>订单消费者之feign</description>
 
    <dependencies>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--hystrix-->
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.study.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
</project>

新しい application.yml 構成ファイルを作成します

server:
  port: 80
#eureka集群
eureka:
  client:
    register-with-eureka: false
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

新しいメインスタートアップクラス

package com.buba.springcloud;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
 
@SpringBootApplication
@EnableFeignClients//激活Feign的注解  需要加到主启动类上
public class OrderFeignMain {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderFeignMain.class,args);
    }
}

新しいビジネス クラスを作成するには、プロデューサーのサービスのビジネス インターフェイスをコピーし、それを直接使用します。

package com.buba.springcloud.service;
 
import com.buba.springcloud.pojo.CommonResult;
 
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
 
 
@ComponentScan
@FeignClient(value ="mcroservice-payment")//使用Feign
public interface PaymentService {
    
    
    @GetMapping("/payment/get/{id}")
    public CommonResult queryById(@PathVariable("id") Long id);
  
}

新しい制御層コントローラーを作成する

package com.buba.springcloud.controller;
 
 
import com.buba.springcloud.pojo.CommonResult;
import com.buba.springcloud.pojo.Payment;
import com.buba.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@Slf4j
public class OrderFeignController {
    
    
    @Autowired
    private PaymentService paymentService;
    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
    
    
        CommonResult result = paymentService.queryById(id);
        return result;
    }
   
}

次に、eureka7001 と 7002 を今すぐ起動し、次にサーバー サービス 8001 と 8002 を起動して、まず起動が成功するかどうかをテストします。OpenFeignで設定したプロデューサーサービス80を起動し、パス80にアクセスしhttp://localhost/consumer/payment/get/1、割り当てバランスの機能があるか確認してください。
ここに画像の説明を挿入

要約すると、Openfeign は、以下に示すように、マイクロサービス呼び出しインターフェイス + @FeignClient アノテーションです。
ここに画像の説明を挿入
ここに画像の説明を挿入

3. Openfeign はタイムアウト制御を実装します

弊社のサービスはプロデューサーとコンシューマーに分かれているため、コンシューマーサービスがプロデューサーサービスを呼び出すと応答に時間がかかり、接続タイムアウトが発生し、長時間応答がない場合は非常に悪い結果になります。経験上、この時点でタイムアウトの実装を設定できます。たとえば、コンシューマ サービスがプロデューサー サービスを呼び出すとき、プロデューサー サービスにアクセスしたときに 2 秒以上応答がない場合に、プロンプトが表示されるように設定できます。接続がタイムアウトしました。後でアクセスしてください。生産者サービスと消費者サービスの両方で規制を設ける必要があります。

次に、次のコードはタイムアウト設定を示しています。これにより、直感的に理解して学習することが容易になります。次の図に示すように、プロデューサ ポートが 8001 であるサービスのインターフェイスを作成し、プログラムを 3 秒間一時停止させ、意図的にタイムアウトを設定してエラー状況を示します。

//模拟业务接口延时3秒
@GetMapping("/payment/feign/timeout")
public String PaymentFeignTimeOut() throws InterruptedException {
    
    
     TimeUnit.SECONDS.sleep(3);
     return serverPort;
}

次の図に示すように、コンシューマ サービス ビジネス レイヤーにタイムアウト インターフェイスを追加します。

package com.buba.springcloud.service;
 
import com.buba.springcloud.pojo.CommonResult;
 
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
 
 
@ComponentScan
@FeignClient(value ="mcroservice-payment")//使用Feign,使用哪个微服务
public interface PaymentService {
    
    
    //调用生产者微服务名称为mcroservice-payment下边的接口
    @GetMapping("/payment/get/{id}")
    public CommonResult queryById(@PathVariable("id") Long id);
    //调用生产者微服务名称为mcroservice-payment下边的模拟超时的接口
    @GetMapping("/payment/feign/timeout")
    public String PaymentFeignTimeOut() throws InterruptedException;
 
}

次の図に示すように、コンシューマ サービス コントロール層にタイムアウト インターフェイスを追加します。

package com.buba.springcloud.controller;
 
 
import com.buba.springcloud.pojo.CommonResult;
import com.buba.springcloud.pojo.Payment;
import com.buba.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@Slf4j
public class OrderFeignController {
    
    
    @Autowired
    private PaymentService paymentService;
    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
    
    
        CommonResult result = paymentService.queryById(id);
        return result;
    }
    @GetMapping("/consumer/feign/timeout")
    public String PaymentFeignTimeOut() throws InterruptedException{
    
    
        return paymentService.PaymentFeignTimeOut();
    }
}

http://localhost:8001/payment/feign/timeout以下の図に示すように、まずマイクロサービスと、ポートが 8001 であるプロデューサーのアクセス インターフェイスをセルフテストしてみましょう。
ここに画像の説明を挿入

コンシューマのサービスにアクセスするためのセルフテストに合格すると、インターフェイスは となりhttp://localhost/consumer/feign/timeout、次のエラー インターフェイスが表示され、インターフェイス アクセスがタイムアウトしたことを示します。
ここに画像の説明を挿入

その理由は、Openfeign はデフォルトで 1 秒待機し、それを超えるとエラーを報告するためです。ただし、プロデューサー サービスは複雑なビジネスを処理する必要があり、処理時間が 1 秒を超えるため、Openfeign のデフォルトの待ち時間を変更する必要があります。コンシューマーサービスのymlファイルに設定する必要があります。Feign はリボンを統合しているため、リボン関連の設定が必要です。以下に示すように:

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
 
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  # 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间,设置等待5000为5秒时间
  ReadTimeout: 5000
  # 指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

コンシューマ サービスを再起動し、ttp://localhost/consumer/feign/timeout に再度アクセスすると、次の成功インターフェイスが表示されます。

ここに画像の説明を挿入

4. Openfeign はログ出力を実装します

Openfeign はログ出力機能を提供します。たとえば、コンシューマ サービスがプロデューサーのサービスを呼び出してインターフェイスを呼び出す場合、情報ヘッダー、ステータス コード、時間、インターフェイスなどのより詳細な情報が必要になる場合があります。Openfeign のログ出力機能を使用することができ、Feign の Http リクエストの詳細を理解するために設定を通じてログ レベルを調整できます。それは、Feign インターフェースの通話状態を監視し、出力することです。

ロガーには 4 つのタイプがあります。

NONE: デフォルトでは、ログは表示されません。

BASIC: リクエストメソッド、URL、レスポンスステータス、実行時間のみを記録します。

HEADERS: BASIC で定義された情報に加えて、リクエストとレスポンスに関する情報があります。

FULL: BASIC で定義された情報に加えて、リクエストおよびレスポンスのボディとメタデータがあります。

Beanを登録してロギングレベルを設定してください。

Log Bean の構成を開始します。新しい構成ファイル FeignConfig を作成します。@Configuration を忘れずに追加してください。

package com.buba.springcloud.config;
 
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class FeignConfig
{
    
    
    /**
     * feignClient配置日志级别
     *
     * @return
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
    
    
        // 请求和响应的头信息,请求和响应的正文及元数据
        return Logger.Level.FULL;
    }
}

yml ファイルでは、ログの Feign クライアントを開き、PaymentService ビジネス クラスの完全修飾クラス名を記述する必要があります。

logging:
  level:
      # feign日志以什么级别监控哪个接口
    com.buba.springcloud.service.PaymentService: debug

コンシューマ サービスを再起動し、インターフェイスにアクセスし、コンソールに出力されるログ情報を確認します。
ここに画像の説明を挿入

OpenFeign はここで学びました、とても簡単です!

ここに画像の説明を挿入

次の記事でも、Hystrixを続けてアヒルを応援していきましょう!

おすすめ

転載: blog.csdn.net/weixin_39570655/article/details/131810328