6

Feign Client を動作させることができません。最初に POST で試してみました。タイプが正しくないというエンコーダー/デコーダーに関連するエラーが発生し続けました。次に、github で単純な GET API を呼び出す例を最終的に見つけ、試してみることにしました。それでも失敗する

Github とオンラインで、Feign Client Spring-Cloud、OpenFeign、Netflix.feign の複数のバージョンが異なるバージョンで表示されています。本番環境で使用する必要がある、最適で安定した Feign クライアントを説明できる人はいますか?

package com.paa.controllers;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient (name="test-service",url="https://www.reddit.com/r")
public interface GetFeignClient {

     @RequestMapping(method = RequestMethod.GET, value = "/java.json")
     public String posts();
}

Controller:

@RestController
@RequestMapping("/some/api")
public class TestWLCController {

  @Autowired
  private GetFeignClient getFeignClient;

  .. some stuff


    @RequestMapping(value="/postSomething",method = RequestMethod.POST)
    @ApiOperation(value = "Configures something",
            notes = "basic rest controller for testing feign")

    public ResponseEntity<SomeResponse> feignPost(
            UriComponentsBuilder builder,
            @ApiParam(name = "myRequest", 
            value = "request for configuring something", 
            required = true)
            @Valid @RequestBody SomeRequest someRequest) {

        String resp = null;
        try {
            resp = getFeignClient.posts();
        } catch (Exception er) {
            er.printStackTrace();
        }

    }
}

応用:

AutoWire の問題を解決できると考えて、注釈のすべての可能な順列を試しましたが、それでも失敗します

@Configuration
@ComponentScan
@EnableAutoConfiguration
//@EnableEurekaClient
@EnableFeignClients

//@SpringBootApplication
//@EnableFeignClients
//@EnableFeignClients(basePackages = {"com.paa.xenia.controllers", "com.paa.xenia.services"})
public class ServiceApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

        return application.sources(XeniaServiceApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(ServiceApplication.class, args);
    }
}

2016-07-20 18:15:42.406[0;39m [31mERROR[0;39m [35m32749[0;39m [2m---]0;39m [2m[メイン]][0;39m [36mo.s.boot .SpringApplication [0;39m [2m:[0;39m アプリケーションの起動に失敗しました

org.springframework.beans.factory.BeanCreationException: 「testWLCController」という名前の Bean の作成中にエラーが発生しました: 自動配線された依存関係の注入に失敗しました。ネストされた例外は org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; です。ネストされた例外は org.springframework.beans.factory.BeanCreationException: 'com.aa..controllers.GetFeignClient' という名前の Bean の作成中にエラーが発生しました: FactoryBean がオブジェクトの作成時に例外をスローしました。ネストされた例外は、org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] で java.lang.NullPointerException です。組織 run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] at com.paa.ServiceApplication.main(ServiceApplication.java:44) [bin/:na] 原因: org.springframework.beans.factory.BeanCreationException: フィールドを自動配線できませんでした: プライベート com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; ネストされた例外は org.springframework.beans.factory.BeanCreationException: 'com.paa.controllers.GetFeignClient' という名前の Bean の作成中にエラーが発生しました: FactoryBean がオブジェクトの作成時に例外をスローしました。ネストされた例外は、org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) で java.lang.NullPointerException です ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE ] org.springframework.beans で。

4

3 に答える 3

4

あなたが最終的に自分でそれを理解したかどうかはわかりませんが、このスレッドに出くわす可能性のある他の人のために、あなたがやろうとしていたことの実際の例を以下に示します. 最初に、間違っている点、またはコードで望ましくない点をいくつか指摘してから、動作するコードを示します。

  1. urlこの属性を使用しないようにしてください。<feign client name>.ribbon.listOfServers代わりに、 in bootstrap.yml(または)を使用してサーバーのリストを設定しますbootstrap.propertieslistOfServersこれにより、コンマ区切りのリストを指定できるため、クライアント側の負荷分散が可能になります。
  2. HTTPS 接続にリボンを使用する場合、HTTP 接続には不要な 2 つのことを指定する必要があります。listOfServersおよびの一部であるポート<feign client name>.ribbon.IsSecure: true。ポートがない場合はポート 80 に接続され、 がないIsSecure場合は HTTP が使用されます。
  3. を使用してテストしcurlたところ、Reddit の応答に非常に時間がかかることがわかりました。リクエストとレスポンスのサイクルにかかる合計時間を分析する方法の詳細については、この SO投稿を参照してください。

    $ curl -v -H "User-Agent: Mozilla/5.0" -w "@curl-format.txt" -o /dev/null -s "https://www.reddit.com/r/java/top.json?count=1"
    { [2759 bytes data]
    * Connection #0 to host www.reddit.com left intact
    time_namelookup:     0.527
    time_connect:        0.577
    time_appconnect:     0.758
    time_pretransfer:    0.758
    time_redirect:       0.000
    time_starttransfer: 11.189
                      ----------
    time_total:         11.218
    

Netflix Wikiによると、デフォルトの読み取りと接続のタイムアウトは 3000 ミリ秒であるため、変更しない限り常にタイムアウトします。

  1. リクエストでUser-Agentヘッダーを指定したことに気付いたかもしれません。curlこれは、Reddis がそれについて非常にうるさいようで、指定されていない場合、ほとんどの場合、HTTP 429 "Too many requests" を返すためです。それらは応答でヘッダーを返さないRetry-Afterため、別の要求を行う前にどれだけ待つ必要があるかわかりません.
  2. Spring Cloud Netflix と Netflix Feign はオープン ソースであるため、ある程度の (多くの) 忍耐力とデバッグ スキルが非常に役立ちます。

「話は安い。コードを見せて」(Torvalds, Linus (2000-08-25)) .

優れたSpring Initializrサイトを使用して Gradle アプリを生成しました。ファイルの一部を次に示しbuild.gradleます。

dependencies {
    compile('org.springframework.cloud:spring-cloud-starter-feign')
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Camden.SR3"
    }
}

クライアントを装う:

@FeignClient(name = "reddit")
public interface RedditClient {
    @RequestMapping(method = GET, value = "/r/java/top.json?count=1",
            headers = {USER_AGENT + "=Mozilla/5.0", ACCEPT + "=" + APPLICATION_JSON_VALUE})
    public String posts();
}

起動アプリケーション:

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

    @RestController
    static class DemoController {
        @Autowired
        private RedditClient redditClient;

        @GetMapping("/posts")
        public String posts() {
            return redditClient.posts();
        }
    }
}

ブートストラップ.yml :

reddit:
  ribbon:
    listOfServers: www.reddit.com:443
    ConnectTimeout: 20000
    ReadTimeout: 20000
    IsSecure: true
hystrix.command.default.execution:
  timeout.enabled: true
  isolation.thread.timeoutInMilliseconds: 50000

統合テスト:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void testGetPosts() {
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("/posts", String.class);

        HttpStatus statusCode = responseEntity.getStatusCode();
        assertThat(String.format("Actual status code: %d, reason: %s.",
                statusCode.value(), statusCode.getReasonPhrase()),
                statusCode.is2xxSuccessful(), equalTo(true));
    }
}
于 2016-12-13T03:44:07.540 に答える
1

依存関係:

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

         <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-parent</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

アプリ:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.test.cloud.bookservice.models.Book;

@SpringBootApplication
@RestController
@RequestMapping("/books")
@EnableFeignClients
public class BookServiceApplication {

    Logger logger = LogManager.getLogger(BookServiceApplication.class);

    @Autowired
    private StoreClient storeClient;


    public static void main(String[] args) {
        SpringApplication.run(BookServiceApplication.class, args);
    }


    @GetMapping("/book")
    public Book findBook() {
            return this.restTemplate.getForObject("http://stores/book", Book.class);
    }

    @FeignClient(name = "StoreClient", url = "127.0.0.1:8089")
    interface StoreClient {
        @RequestMapping(method = RequestMethod.GET, value = "/stores/book", consumes = "application/json")
        Book getBook();
    }

}
于 2019-07-05T13:25:27.337 に答える
0

誰かが私たちがどのようにそれを行ったのかを知ることに興味を持っていたので、彼らの利益のために回答を投稿しました.

親モジュール

package com.hitech.module.base;

@EnableFeignClients
public abstract class BaseApplication extends SpringBootServletInitializer {
...
..
}

build.gradle:

buildscript {
    ext {
        springBootVersion = '1.3.5.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE")
    }
}
...
...

dependencies {
    compile('io.springfox:springfox-swagger-ui:2.5.0')
    compile('io.springfox:springfox-swagger2:2.5.0')
    compile('org.springframework.cloud:spring-cloud-starter-feign')

子モジュール

package com.hitech.module.app;

import com.hitech.module.base.BaseApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication(exclude = {MongoDataAutoConfiguration.class, MongoAutoConfiguration.class},
        scanBasePackages = {"com.hitech.module.base", "com.hitech.module.app", })
@EnableFeignClients("com.hitech.module.app.clients")
public class MyServiceApplication extends BaseApplication {

    private static final Logger LOG = LoggerFactory.getLogger(MyServiceApplication.class);

    public static void main(String[] args) {

        String s1 = "google";

        LOG.info ("=== Started Orchestration Service ===");
        SpringApplication.run(MyServiceApplication.class, args);


    }
}

ブートストラップ.yml

feign:
  hystrix:
    enabled: false
datasource:
  audit:
    mongodb:
      host: localhost
      port: 27019
      database: audit
于 2017-05-11T21:37:42.120 に答える