FeignClient 调用

1.简介

微服务架构服务实例众多,服务与服务之间如何调用,Spring Cloud提供了解决方案:伪装者 Feign。

Feign 是 Spring Cloud 的一个组件,也是一个WebService客户端,用于服务之间的调动。

2. 如何使用

第一步:服务之间调用

本例需要创建三个工程:

eureka-server 注册中心服务(项目创建参照第三节网关)

product-service 产品服务(最基础的客户端服务,提供一个rest接口即可。前面第三节已创建,可参考,不需要做任何修改)

order-service-feignclient 订单服务(测试服务调用)

order-service-feignclient 工程目录如下图:
这里写图片描述

(1)pom.xml增加依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

(2)增加接口和 @FeignClient 注解

package com.hole.feign;

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

/**
 * Created by helei on 2017/7/16.
 */
@FeignClient(value = "product-service",fallback = ProductServiceFeignDaoHystrix.class)
public interface ProductServiceFeignDao {

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    String hello();
}
@FeignClient(value = "product-service"

value设置要调用服务的服务名。Feign会根据服务名去注册中心查找服务url
(3)启动类增加 @EnableFeignClient开启Feign功能,新增Rest接口用于调用产品服务。

package com.hole;

import com.hole.feign.ProductServiceFeignDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@EnableDiscoveryClient
@SpringBootApplication
@RestController
@EnableFeignClients
public class OrderServiceFeignclientApplication {
    @Autowired
    private ProductServiceFeignDao productServiceFeignDao;

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

    @RequestMapping(value = "/product/hello",method = RequestMethod.GET)
    public String getHelloFromProductService(){
        return productServiceFeignDao.hello();
    }
}

(4)启动服务验证

启动成功后请求 /product/hello,结果成功调用产品服务并返回结果。

这里写图片描述

第二步:增加 Hystrix 断路熔断机制

(1)增加 Feign接口实现类,实现方法作为断路器的回调方法。

package com.hole.feign;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * Created by helei on 2017/7/16.
 */
@Component
public class ProductServiceFeignDaoHystrix implements ProductServiceFeignDao {

    @Override
    public String hello() {
        return "服务不见鸟,稍后再试!";
    }
}

(2)Feign接口的 @FeignClient注解增加 fallback参数,指向接口的实现类。

package com.hole.feign;

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

/**
 * Created by helei on 2017/7/16.
 */
@FeignClient(value = "product-service",fallback = ProductServiceFeignDaoHystrix.class)
public interface ProductServiceFeignDao {

    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    String hello();
}

(3)启动服务验证。

启动成功后将 product-sevice 服务关闭,再次请求 /product/hello,结果发现报异常。

这里写图片描述

发现断路器并没有起作用,而是直接抛异常。

带着疑惑查了下官方API,官方文档中大致意思是feign默认是启用hystrix的,然而测试的结果是并没有。但发现了一段配置

feign.hystrix.enabled=false

这个配置意思很明确了吧,将false改为true,试试又不犯法,结果。。。

对,就是你认为的那样,成功了!

这里写图片描述

还有一个地方要补充下:

FigenClient已经包含了Hystrix,所有启动类不需要再开启 @EnableCircuitBreaker

本文为借鉴于 https://blog.youkuaiyun.com/u013084910/article/details/76539201

### FeignClient 调用失败的原因及解决方案 Feign 是一种声明式的 Web Service 客户端,它使得编写 HTTP API 的客户端变得更加容易。然而,在实际开发过程中,可能会遇到 `FeignClient` 调用失败的情况。以下是可能的原因及其对应的解决方案。 #### 1. **超时设置不足** 如果服务提供方响应时间较长或者网络延迟较高,而 `FeignClient` 的默认超时时间较短,则可能导致调用失败。可以通过配置自定义的连接和读取超时来解决问题[^1]。 ```java @Configuration public class FeignConfig { @Bean public OkHttpClient client() { return new OkHttpClient.Builder() .connectTimeout(60, TimeUnit.SECONDS) // 设置连接超时时间为60秒 .readTimeout(60, TimeUnit.SECONDS) // 设置读取超时时间为60秒 .build(); } } ``` 通过上述方式可以有效避免由于超时引起的调用失败问题。 #### 2. **负载均衡器或服务发现机制异常** 当使用 Spring Cloud Netflix Eureka 或其他服务注册与发现工具时,若目标服务未正常注册到服务中心,或者负载均衡器出现问题,也可能导致调用失败。此时应检查以下几点: - 确认目标服务已成功注册至服务中心。 - 验证 Ribbon 或者其他负载均衡组件是否工作正常。 #### 3. **请求参数错误** 发送给远程接口的数据结构不符合预期格式,例如字段缺失、数据类型不匹配等问题都会引发调用失败。因此需要仔细核对接口文档以及传递的实际参数是否一致。 对于复杂对象作为入参的情况下,建议采用如下形式进行调试: ```java @PostMapping("/createBatch") public RestResult createBatch(@RequestBody BatchCreateReqDTO batchCreateReqDTO){ log.info("Request Body: {}", batchCreateReqDTO); return restTemplate.postForObject(url, batchCreateReqDTO, RestResult.class); } ``` 记录日志可以帮助定位具体哪个部分存在问题。 #### 4. **Hystrix 断路器触发** 假如启用了 Hystrix 并设置了熔断策略,那么一旦达到设定阈值之后就会进入快速失败模式从而阻止后续请求继续尝试访问降级的服务实例。这种情况下应该调整熔断规则或者是优化下游依赖性能以减少失败率。 --- ### 总结 针对以上提到的各种可能性逐一排查即可找到根本原因并采取相应措施加以修复。合理地配置 Feign 客户端的各项属性能够极大地提升其稳定性与可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值