Feign使用笔记和问题解决

15 篇文章 1 订阅

Feign让客户端调用变得非常简单

使用

添加maven依赖
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>
增加注解@EnableFeignClients

注意 @EnableFeignClients注解的clients和basePackages同时配置的话只有clients生效
这个看一下FeignClientsRegistrar.registerFeignClients源码就可以很好理解了

@EnableFeignClients(clients = {com.**.IUserFeign.class})
客户端@FeignClient
  1. 参数value, 如果调用微服务环境中的应用,value等于服务的名字,也可以是一个完整的http接口请求前缀
  2. 参数path, 其实默认为/,可以不用配置,如果请求方法有公共前缀或者服务有站点路径可以配置在这里。
@FeignClient(value = "sso", path="/")
public interface IUserFeign{
   @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public User getUserById(@PathVariable String id)
}
配置一个FeignConfiguration

RequestMappingHandlerMapping的部分源码如下,可以看出只要有Controller注解或者有RequestMapping注解就会进行请求注册,我们调用外部接口的时候是不需要将@FeignClient接口类中@RequestMapping注解的方法注册到mvc中,所以需要修改注册规则

    protected boolean isHandler(Class<?> beanType) {
        return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) || AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class);
    }
import feign.Feign;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Configuration
@ConditionalOnClass({Feign.class})
public class FeignConfiguration {
    @Bean
    public WebMvcRegistrations feignWebRegistrations() {
        return new WebMvcRegistrations() {
            @Override
            public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
                return new FeignRequestMappingHandlerMapping();
            }
        };
    }
    private static class FeignRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
        @Override
        protected boolean isHandler(Class<?> beanType) {
            return super.isHandler(beanType) &&
                    !AnnotatedElementUtils.hasAnnotation(beanType, FeignClient.class);
        }
    }
}

Feign默认是会重试的, new Retryer.Default()源码可以看出最多重试5次
有一个业务是失败一次就直接提示用户稍后再试,增加下面注解来禁止重试

    @Bean
    Retryer feignRetryer() {
        return new Retryer() {
            @Override
            public void continueOrPropagate(RetryableException e) {
                throw e;
            }

            @Override
            public Retryer clone() {
                return this;
            }
        };
    }
超时时间设置

默认1秒就超时,也太短了

feign:
  client:
    config:
      default:
        connect-timeout: 10000
        read-timeout: 120000
  hystrix:
    enabled: true
  compression:
    request:
      enabled: true
      mime-types: text/xml,application/xml,application/json
      min-request-size: 2048
      max-request-size: 2097152000

要点和问题

1.Error creating bean with name ‘mvcResourceUrlProvider’: Requested bean is currently in creation: Is there an unresolvable circular reference?

出现错误现象如下, 有些原因不明,如果有大神看到请帮忙解释一下:

  1. dev,test,uat,本地电脑打的jar包都能正常运行,线上发布打的jar包就是会报上面的错误,后面发现线上打的jar包还有20%的概率也能正常运行(求解释
  2. 正常运行的jar包和运行异常的jar包我用beyond compare都比较过,内容完全一样
  3. 正常的jar包每次启动都运行正常,启动报错的jar包每次都会报错,启动报错的包拷贝到本地指定dev,test,uat环节启动都会报错,(有一段时间发布我们线上发布都是从uat拷贝jar包)
  4. 有很多微服务中都在拦截器中有使用feign接口,但是只有一个服务线上打包才报错(求解释)
    参考大神的一篇文章 springcloud 拦截器注入Feign接口导致循环依赖问题解决

直接列出结论:
如果在拦截器中有地方用到了feign接口就会出现循环依赖的错误,这个时候在feign注入的地方加上@Lazy注解问题就能解决

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {

    @Lazy
    @Override
    private IUserFeign userFeign;
    
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new HandlerInterceptorAdapter() {

			@Override
			public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
					throws Exception {
					
			}
		}).addPathPatterns("/**");

}
2.Hystrix circuit short-circuited and is OPEN

服务提供方会报错,服务提供方参照下面的文章增加配置
Hystrix circuit short-circuited and is OPEN 异常
hystrix.command.default.circuitBreaker.requestVolumeThreshold=1000
hystrix.threadpool.default.coreSize=100
#断路器超时设置和请求的超时
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=300000
ribbon.ConnectTimeout=300000
ribbon.ReadTimeout=300000
#设置回退的最大线程数
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=50

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
RabbitMQ和Feign异步的使用场景包括限流削峰、异步解耦和数据收集。在限流削峰场景中,可以使用RabbitMQ和Feign来控制请求的并发量,避免系统过载。\[1\]在异步解耦方面,使用Feign进行微服务间的调用时,可以通过异步方式发送请求,提高系统的响应速度和吞吐量。\[1\]同时,使用异步消息队列(如RabbitMQ)可以实现解耦,将请求发送到消息队列中,然后由消费者异步处理,提高系统的可伸缩性和可靠性。\[2\]在数据收集方面,可以使用RabbitMQ和Feign来收集和处理大量的数据,通过异步方式将数据发送到消息队列中,然后由消费者进行处理和存储,提高数据处理的效率和可靠性。\[1\]\[3\] #### 引用[.reference_title] - *1* [分布式消息中间件RabbitMQ学习笔记(一)——使用场景(限流削峰、异步解耦、数据收集)](https://blog.csdn.net/weixin_51542566/article/details/127471912)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [服务异步通讯——RabbitMQ](https://blog.csdn.net/m0_56188609/article/details/127576258)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值