2016-07-21 6 views
2

Невозможно заставить Файон Клиента работать. Сначала попытался с POST. Неисправность запущена в ошибки, связанные с типом кодирования/декодера. Затем нашел пример на github, чтобы в конце концов называть простой GET API и решил сделать снимок. По-прежнему не удаетсяНевозможно заставить Файон Клиента работать на базовый пример

В Github и в Интернете я вижу несколько версий Feign Client Spring-Cloud, OpenFeign, Netflix.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 [main] [0; 39m [36mo.s.boot.SpringApplication [0; 39m [2m: [0 ; 39m Ошибка при запуске приложения

org.springframework.beans.factory.BeanCreationException: Ошибка создании компонента с именем 'testWLCController': Инъекции autowired зависимостей не удалось; вложенное исключение: org.springframework.beans.factory.BeanCreationException: не удалось поле autowire: private com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; вложенное исключение: org.springframework.beans.factory.BeanCreationException: Ошибка создание bean-компонента с именем 'com.aa..controllers.GetFeignClient': FactoryBean исключил создание объекта; вложенное исключение составляет java.lang.NullPointerException на org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​(AutowiredAnnotationBeanPostProcessor.java:334) ~ [пружинных-бобов-4.2.6.RELEASE.jar: 4.2.6. RELEASE] на org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean (AbstractAutowireCapableBeanFactory.java:1214) ~ [весна-бобы-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org.springframework .beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:543) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapable BeanFactory.java:482) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject (AbstractBeanFactory.java:306) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:230) ~ [spring-beans- 4.2.6.RELEASE.jar: 4.2.6.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (AbstractBeanFactory.java:302) ~ [spring-beans-4.2.6.RELEASE.jar : 4.2.6.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:197) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons (DefaultListableBeanFactory.java:772) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.РЕЛИЗ] на org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization (AbstractApplicationContext.java:839) ~ [весенне-контекстно-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org.springframework.context .support.AbstractApplicationContext.refresh (AbstractApplicationContext.java:538) ~ [spring-context-4.2.6.RELEASE.jar: 4.2.6.RELEASE] в org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh (EmbeddedWebApplicationContext.java:118) ~ [spring-boot-1.3.5.RELEASE.jar: 1.3.5.RELEASE] в org.springframework.boot.SpringApplication.refresh (SpringApplication.java:766) [spring-boot -1.3.5.RELEASE.jar: 1.3.5.RELEASE] на org.springframework.boot.SpringApplication.createAndR efreshContext (SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar: 1.3.5.RELEASE] в org.springframework.boot.SpringApplication.run (SpringApplication.java:307) [spring- boot-1.3.5.RELEASE.jar: 1.3.5.RELEASE] в org.springframework.boot.SpringApplication.run (SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar: 1.3. 5.RELEASE] на org.springframework.boot.SpringApplication.run (SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar: 1.3.5.RELEASE] на com.paa.ServiceApplication. main (ServiceApplication.java:44) [bin /: na] Вызвано: org.springframework.beans.factory.BeanCreationException: Не удалось создать поле autowire: private com.paa.controllers.GetFeignClient com.paa.controllers.TestWLCController.gfClient; вложенное исключение: org.springframework.beans.factory.BeanCreationException: Ошибка создание bean-компонента с именем 'com.paa.controllers.GetFeignClient': FactoryBean исключил создание объекта; вложенное исключение java.lang.NullPointerException в org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:573) ~ [Весна-Beans-4.2.6.RELEASE.jar: 4.2. 6.RELEASE] на org.springframework.beans.factory.nnation.InjectionMetadata.inject (InjectionMetadata.java:88) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] на org .springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​(AutowiredAnnotationBeanPostProcessor.java:331) ~ [spring-beans-4.2.6.RELEASE.jar: 4.2.6.RELEASE] ... 17 com.n кадров опущено

ответ

1

Я не уверен, что вы в конце концов поняли это сами, но ради других, которые могли бы наткнуться на эту нить, ниже - рабочий пример того, что вы пытались сделать. Сначала я укажу несколько вещей, которые неправильны или, по крайней мере, не желательны в вашем коде, а затем покажите мой код, который работает.

  1. Вы должны стараться не использовать атрибут url. Вместо этого настройте список серверов, используя <feign client name>.ribbon.listOfServers в bootstrap.yml (или bootstrap.properties). Это позволяет балансировать нагрузку на стороне клиента, поскольку listOfServers может быть разделен запятыми.
  2. Используя ленту для соединений HTTPS, вам нужно указать две вещи, которые вам не нужны для HTTP-соединений. Порт, который является частью listOfServers и <feign client name>.ribbon.IsSecure: true. Без порта соединение выполняется с портом 80 и без IsSecure, используется HTTP.
  3. Тестирование с использованием curl, я обнаружил, что Reddit принимает очень долгое время ответа.См. Это SO post для получения подробной информации о том, как разбить общее время, затрачиваемое циклом запроса-ответа.

    $ 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 «Слишком много запросов». Они не возвращают заголовок Retry-After в ответе, поэтому не сообщается, сколько времени вам нужно ждать, прежде чем делать другой запрос.
  2. Spring Cloud Netflix, а также Netflix Feign - это с открытым исходным кодом, поэтому некоторые (много) терпения и навыки отладки очень полезны.

«Обсуждение дешево. Покажите мне код». (Торвальдс, Линус (2000-08-25)).

Я создал приложение Gradle, используя отличный сайт Spring Initializr. Вот фрагмент файла 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" 
    } 
} 

Feign клиент:

@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(); 
     } 
    } 
} 

bootstrap.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)); 
    } 
} 
+0

Я был в состоянии успешно использовать симулировать хотя мы действительно не использовать 'ленточку'. Мы использовали в качестве клиента для отдыха, так как он намного чище. Другой урок, который мы узнали, заключался в том, что для Feign для обработки заголовков и перехватов ответов необходимо реализовать Decoders for Feign, а также настроить Feign Config. Я отправлю код, как только получаю некоторое время. – Rockoder

+0

@Rockoder Нет необходимости отправлять код, что вы сказали, является частью документации, ничего необычного. –

+0

Точка, которую я попытался уточнить, мы использовали Фейнг без ленты.Поэтому лента не обязательно использовать Feign ==== симулировать: Hystrix: включено: ложные DataSource: аудит: MongoDB: хозяин: локальный порт: 27019 база данных: аудит === – Rockoder

0

Кто был заинтересован, чтобы узнать, как мы делали это так разместить ответ на их пользу.

Родитель Модуль

package com.cisco.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); 


    } 
} 

bootstrap.yml

feign: 
    hystrix: 
    enabled: false 
datasource: 
    audit: 
    mongodb: 
     host: localhost 
     port: 27019 
     database: audit