fastDFS服务挂掉重启后客户端无法连接异常
程序员文章站
2022-04-15 17:51:07
客户端版本 com.github.tobato fastdfs-client 1.27.2 异常信息ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet]...
客户端版本
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
异常信息
ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Unable to borrow buffer from pool] with root cause
com.github.tobato.fastdfs.exception.FdfsUnavailableException: 无法获取服务端连接资源:找不到可用的tracker /192.168.0.127:22122,
这个异常会在tricker挂掉之后出现,但是重启后依然会报这个异常,并且持续10分钟。
具体原因是:
TrackerConnectionManager中的executeFdfsTrackerCmd()方法中的address = trackerLocator.getTrackerAddress();出现异常。
public <T> T executeFdfsTrackerCmd(FdfsCommand<T> command) {
Connection conn = null;
InetSocketAddress address = null;
// 获取连接
try {
address = trackerLocator.getTrackerAddress();
LOGGER.debug("获取到Tracker连接地址{}", address);
conn = getConnection(address);
trackerLocator.setActive(address);
} catch (FdfsConnectException e) {
trackerLocator.setInActive(address);
throw e;
} catch (Exception e) {
LOGGER.error("Unable to borrow buffer from pool", e);
throw new RuntimeException("Unable to borrow buffer from pool", e);
}
// 执行交易
return execute(address, conn, command);
}
继续向下追踪发现是holder的canTryToConnect()方法问题
public InetSocketAddress getTrackerAddress() {
TrackerAddressHolder holder;
// 遍历连接地址,抓取当前有效的地址
for (int i = 0; i < trackerAddressCircular.size(); i++) {
holder = trackerAddressCircular.next();
if (holder.canTryToConnect(retryAfterSecond)) {
return holder.getAddress();
}
}
throw new FdfsUnavailableException("找不到可用的tracker " + getTrackerAddressConfigString());
}
进入canTryToConnect()方法,结果很明了了,如果上次失败了,就一直得等到超过重试时间才会继续尝试。
public boolean canTryToConnect(int retryAfterSecend) {
// 如果是有效连接
if (this.available) {
return true;
// 如果连接无效,并且达到重试时间
} else if ((System.currentTimeMillis() - lastUnavailableTime) > retryAfterSecend * 1000) {
return true;
}
return false;
}
查询重试时间配置发现这个值无法配置。主要配置代码如下(来自多个类)。
/**
* 10分钟以后重试连接
*/
private static final int DEFAULT_RETRY_AFTER_SECOND = 10 * 60;
/**
* 连接中断以后经过N秒重试
*/
private int retryAfterSecond = DEFAULT_RETRY_AFTER_SECOND;
/**
* 初始化方法
*/
@PostConstruct
public void initTracker() {
LOGGER.debug("init trackerLocator {}", trackerList);
trackerLocator = new TrackerLocator(trackerList);
}
/**
* 初始化Tracker服务器地址
* 配置方式为 ip:port 如 192.168.1.2:21000
*
* @param trackerList
*/
public TrackerLocator(List<String> trackerList) {
super();
this.trackerList = trackerList;
buildTrackerAddresses();
}
解决方法:
1. 改源码。
2. 获取相关对象修改值
3. 接受10分钟不能用。
我使用第二种
import com.github.tobato.fastdfs.domain.conn.TrackerConnectionManager;
import com.github.tobato.fastdfs.domain.fdfs.TrackerLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Field;
/**
* 项目启动监听器
*/
@Component
public class ApplicationStartedEventListener implements ApplicationListener<ApplicationReadyEvent> {
private Logger logger = LoggerFactory.getLogger(ApplicationStartedEventListener.class);
@Resource
private TrackerConnectionManager trackerConnectionManager;
@Value("${fdfs.retry-after-second}")
private Integer retryAfterSecond;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
logger.info("spring启动成功!");
try {
logger.info("修改fastDFS重连时间为" + retryAfterSecond + "秒");
Field field = trackerConnectionManager.getClass().getDeclaredField("trackerLocator");
field.setAccessible(true);
TrackerLocator trackerLocator = (TrackerLocator) field.get(trackerConnectionManager);
trackerLocator.setRetryAfterSecond(retryAfterSecond);
field.set(trackerConnectionManager, trackerLocator);
logger.info("修改fastDFS重连时间成功");
} catch (Exception e) {
logger.error("修改fastDFS重连时间异常:", e);
}
}
}
本文地址:https://blog.csdn.net/sly1311220942/article/details/109847771