重启后客户端无法连接异常"/>
fastDFS服务挂掉重启后客户端无法连接异常
客户端版本
<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;/*** 初始化方法*/@PostConstructpublic 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);@Resourceprivate TrackerConnectionManager trackerConnectionManager;@Value("${fdfs.retry-after-second}")private Integer retryAfterSecond;@Overridepublic 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);}}
}
更多推荐
fastDFS服务挂掉重启后客户端无法连接异常
发布评论