10-OpenFeign-实现异步调用

通常我们在使用openfeign发起服务调用时,需要同步等待调用结束。某些场景下,我们需要实现异步调用。

1、使用java8 的 CompletableFuture 异步工具

    @Resource
    OauthFeign oauthFeign;


    @GetMapping("/get")
    public Object get() {

        CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
                    return oauthFeign.openFeignApi();
                });
        return completableFuture;
    }
 
  

RequestContextHolder中是将请求信息放入ThreadLocal中的,只能取到同一个线程的数据。

2、使用RequestContextHolder 获取主线程中的header信息

RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

在异步线程内部设置 RequestContextHolder.setRequestAttributes(attributes);

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> {
 //openfeign的调用
 return feign.remoteCall();
},executor);

CompletableFuture future2 = CompletableFuture.supplyAsync(() -> {
 //openfeign的调用
 return feign.remoteCall();
},executor);

CompletableFuture.allOf(future1,future2).join();

.....
//获取主线程的请求信息
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

CompletableFuture future1 = CompletableFuture.supplyAsync(() -> {
   //将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败
   RequestContextHolder.setRequestAttributes(attributes);
    
 //openfeign的调用
 return feign.remoteCall();
},executor);


CompletableFuture future2 = CompletableFuture.supplyAsync(() -> {
   //将主线程的请求信息设置到异步线程中,否则会丢失请求上下文,导致调用失败
 RequestContextHolder.setRequestAttributes(attributes);
 
    //openfeign的调用
 return feign.remoteCall();
},executor);

CompletableFuture.allOf(future1,future2).join();

.....

 

3、全局设置(未验证)

1. 定义一个Feign RequestInterceptor拦截器:
java
public class RequestContextInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            RequestContextHolder.setRequestAttributes(requestAttributes, true);
        }
    }
} 



2. 在FeignClient上添加配置,使用该拦截器:
java
@FeignClient(name="hello", configuration = HelloConfiguration.class)
public interface HelloClient {
    // ...
}

public class HelloConfiguration { 
    @Bean
    public RequestInterceptor requestContextInterceptor() {
        return new RequestContextInterceptor();
    }
}

你可能感兴趣的:(openfeign,异步调用)