概述
spring cloud集成seata报错Read timed out问题解决
- 问题
- 解决
问题
最近做项目,需要集成seata实现分布式事务。遇到一个很麻烦的问题,异常能回滚,但是总是测试正常调用时会出现 “ReadTimeOut” 调用超时的异常。异常信息如下:
feign.RetryableException: Read timed out executing POST http://test/test?status=false
at feign.FeignException.errorExecuting(FeignException.java:213)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:115)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:80)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy169.test(Unknown Source)
at com.personal.record.handler.UserHandler.insertUser(UserHandler.java:30)
at com.personal.record.handler.UserHandler$$FastClassBySpringCGLIB$$5e19999f.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
...
解决
在网上看了很多方法,试了都不行,于是决定Debug,从源码分析试一试。
通过报错一路追溯,发现是ribben调用时超时报错。
因为之前也配置了ribben的ReadTimedOut参数,但是始终不生效,于是找到ribben的ReadTimedOut注入的位置。
public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector) {
super(lb, clientConfig);
this.setRetryHandler(RetryHandler.DEFAULT);
this.clientConfig = clientConfig;
this.ribbon = RibbonProperties.from(clientConfig);
RibbonProperties ribbon = this.ribbon;
this.connectTimeout = ribbon.getConnectTimeout();
this.readTimeout = ribbon.getReadTimeout();
this.serverIntrospector = serverIntrospector;
}
public Integer getReadTimeout() {
return (Integer)this.get(CommonClientConfigKey.ReadTimeout);
}
public <T> T get(IClientConfigKey<T> key) {
return this.config.get(key);
}
@Override
public <T> T get(IClientConfigKey<T> key) {
Object obj = getProperty(key.key());
if (obj == null) {
return null;
}
Class<T> type = key.type();
if (type.isInstance(obj)) {
return type.cast(obj);
} else {
if (obj instanceof String) {
String stringValue = (String) obj;
if (Integer.class.equals(type)) {
return (T) Integer.valueOf(stringValue);
} else if (Boolean.class.equals(type)) {
return (T) Boolean.valueOf(stringValue);
} else if (Float.class.equals(type)) {
return (T) Float.valueOf(stringValue);
} else if (Long.class.equals(type)) {
return (T) Long.valueOf(stringValue);
} else if (Double.class.equals(type)) {
return (T) Double.valueOf(stringValue);
} else if (TimeUnit.class.equals(type)) {
return (T) TimeUnit.valueOf(stringValue);
}
throw new IllegalArgumentException("Unable to convert string value to desired type " + type);
}
throw new IllegalArgumentException("Unable to convert value to desired type " + type);
}
}
protected Object getProperty(String key) {
if (enableDynamicProperties) {
String dynamicValue = null;
DynamicStringProperty dynamicProperty = dynamicProperties.get(key);
if (dynamicProperty != null) {
dynamicValue = dynamicProperty.get();
}
if (dynamicValue == null) {
dynamicValue = DynamicProperty.getInstance(getConfigKey(key)).getString();
if (dynamicValue == null) {
dynamicValue = DynamicProperty.getInstance(getDefaultPropName(key)).getString();
}
}
if (dynamicValue != null) {
return dynamicValue;
}
}
return properties.get(key);
}
String getDefaultPropName(String propName) {
return getNameSpace() + "." + propName;
}
@Override
public String getNameSpace() {
return propertyNameSpace;
}
public static final String DEFAULT_PROPERTY_NAME_SPACE = "ribbon";
private String propertyNameSpace = DEFAULT_PROPERTY_NAME_SPACE;
通过Debug及源码分析,程序注入的一直是默认值:1000,配置未注入。而注入ribben的ReadTimedOut的方式是读取 “ribben.ReadTimedOut”配置。在之前的配置中,此项配置一直放在yml文件中:
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
之后将此项配置放入properties配置文件中
ribbon.ReadTimeout = 10000
ribbon.ConnectTimeout = 10000
重启项目再次调用,发现配置正常注入,不再报超时错误。
最后
以上就是舒服老鼠为你收集整理的spring cloud集成seata报错Read timed out问题解决问题解决的全部内容,希望文章能够帮你解决spring cloud集成seata报错Read timed out问题解决问题解决所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复