解决 Seata 与 Sleuth 引起的冲突

解决 Seata 与 Sleuth 引起的冲突
版本:
Spring Cloud : Hoxton.SR4
Spring Boot: 2.2.5.RELEASE
Spring Cloud Alibaba:2.2.1.RELEASE
Seata:1.1.0
spring-cloud-starter-sleuth:2.2.3.RELEASE

1.Seata 引入 Sleuth 后报错

整合了 Alibaba 的 nacos、sentinel、seata,分布式事务运行正常,整合 sleuth 之后就报错了:

com.netflix.client.ClientException: Load balancer does not have available server for client:

2.加配置

百度问题,无意中看到这个配置,也不是解决这个问题的,只是觉得问题出在 Feign 上,就加上试试。

feign:
  hystrix:
    enabled: true

加了配置后报错

The bean 'feignHystrixBuilder', 
defined in class path resource 
[org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.class], 
could not be registered. A bean with that name has already been defined in class path resource 
[com/alibaba/cloud/seata/feign/SeataFeignClientAutoConfiguration.class] and overriding is disabled.

3.看源码

TraceFeignClientAutoConfiguration:

    // 类上的注解
    @ConditionalOnProperty(
    value = {"spring.sleuth.feign.enabled"},
    matchIfMissing = true
)


    @Bean
    @Scope("prototype")
    @ConditionalOnClass(
        name = {"com.netflix.hystrix.HystrixCommand", "feign.hystrix.HystrixFeign"}
    )
    @ConditionalOnProperty(
        name = {"feign.hystrix.enabled"},
        havingValue = "true"
    )
    Builder feignHystrixBuilder(BeanFactory beanFactory) {
        return SleuthHystrixFeignBuilder.builder(beanFactory);
    }

SeataFeignClientAutoConfiguration:

    @Bean
    @Scope("prototype")
    @ConditionalOnClass(
        name = {"com.netflix.hystrix.HystrixCommand"}
    )
    @ConditionalOnProperty(
        name = {"feign.hystrix.enabled"},
        havingValue = "true"
    )
    Builder feignHystrixBuilder(BeanFactory beanFactory) {
        return SeataHystrixFeignBuilder.builder(beanFactory);
    }

这两个类中都有创建 Bean:feignHystrixBuilder
只能留一个

4.加配置

spring:
  sleuth:
    feign:
      enabled: false

报错:

Field accountService in com.orderplus.demo.provider.service.impl.OrderServiceImpl required a single bean, but 2 were found:
	- feignHystrixBuilder: defined by method 'feignHystrixBuilder' in class path resource [com/alibaba/cloud/seata/feign/SeataFeignClientAutoConfiguration.class]
	- feignSentinelBuilder: defined by method 'feignSentinelBuilder' in class path resource [com/alibaba/cloud/seata/feign/SeataFeignClientAutoConfiguration.class]

5.改配置

注释掉

#feign:
#  hystrix:
#    enabled: true

6.重启

分布式事务正常,Sleuth 不正常了

以上步骤可以忽略

7.配置 Seata 拦截

新建 SetSeataInterceptor 类,拦截 xid

import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

@Component
@ConditionalOnClass({RequestInterceptor.class, GlobalTransactional.class})
public class SetSeataInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        String currentXid = RootContext.getXID();
        if (StringUtils.isNotEmpty(currentXid)) {
            requestTemplate.header(RootContext.KEY_XID, currentXid);
        }
    }
}

8.启动类排除 SeataFeignClientAutoConfiguration.class

@SpringBootApplication(exclude = {SeataFeignClientAutoConfiguration.class})

9.其他配置

这个是默认为 true,可以不配置

spring:
  sleuth:
    feign:
      enabled: true

10.重启

问题终于解决了

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值