FastDfs问题处理

通过上一篇文章,我们了解了fastdfs 的安装,文章的最后遗留了 fastdfs 可能遇到的问题,接下来会详细探讨下这些问题,并给出相应的解决方案

先了解下 fastdfs 的上传过程
在这里插入图片描述
java集成fastdfs-client上传文件到服务器

client 上传过程中,先获取到可用的storage 的ip和端口,这里获取到的ip和端口是fastdfs 服务器上 storage 配置文件中设置的ip 地址和端口
在这里插入图片描述
其中 tracker_server 的ip设置 如果是内网 那么client获取到的storage ip 为内网
如果设置的是外网那么获取到的storage ip 为外网

1、fastdfs 部署与外网服务器,其配置使用的是外网,非内网Client 可以上传了 但会出现同组内 Storage 文件 不同步

由上可知 当 其配置使用的是外网 那么不管 client 部署在内网 还是外网 都是可以上传文件了,这样线下的测试环境也是可以上传文件了

但是当我们 查看Storage和Tracker是否在通信 时

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

会发现
在这里插入图片描述
同组间storage 的文件同步出现了问题
last_synced_timestamp = 2019-07-17 16:32:31 (never synced)

这是因为 同组间的storage 在文件同步时 会获取内网ip对应的storage,但是这里设置的是外网ip地址,所以同步时会 报错 (报错信息这边没有贴出来) 大概意思 就是 :
获取不到 ip(内网):端口 对应的storage

然而我们想要的是 设置的是外网,同步时获取的也是外网,这个目前还不知道有没有相关的配置项可以设置,那么如果想改的话就只能改源码了,可行性不大(不建议),所以我们会想着将设置的ip 设为内网,这样的话就能够获取到 可用的 storage 了,那么同组间的同步就没有问题了

如果fastdfs 部署与外网服务器,其配置使用的是内网,那么 非内网Client 无法上传

由上,当配置的ip 为内网时 文件同步问题解决了,
这时 client 在上传文件时:

  1. 同局域网内 client 上传,没有任何问题
  2. 非局域网,如(线下测试环境),获取到的storage 为 内网地址是无法上传的

下面提供一种解决方案
client 上传时 将获取到的内网 storage ip 替换成相应的外网ip
解决步骤
1 在配置文件中加入

fastdfs.inner_out_net=内网ip:外网ip,内网ip:外网ip
这里是storage 的地址,多个storage 用逗号隔开
格式   内网:外网,内网:外网


2 修改 fastdfs-client-java jar 中的 ClientGlobal

package org.csource.fastdfs;

import org.csource.common.IniFileReader;
import org.csource.common.MyException;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.*;

/**
 * Global variables
 *
 * @author Happy Fish / YuQing
 * @version Version 1.11
 */
public class ClientGlobal {

  public static final String CONF_KEY_CONNECT_TIMEOUT = "connect_timeout";
  public static final String CONF_KEY_NETWORK_TIMEOUT = "network_timeout";
  public static final String CONF_KEY_CHARSET = "charset";
  public static final String CONF_KEY_HTTP_ANTI_STEAL_TOKEN = "http.anti_steal_token";
  public static final String CONF_KEY_HTTP_SECRET_KEY = "http.secret_key";
  public static final String CONF_KEY_HTTP_TRACKER_HTTP_PORT = "http.tracker_http_port";
  public static final String CONF_KEY_TRACKER_SERVER = "tracker_server";

  public static final String PROP_KEY_CONNECT_TIMEOUT_IN_SECONDS = "fastdfs.connect_timeout_in_seconds";
  public static final String PROP_KEY_NETWORK_TIMEOUT_IN_SECONDS = "fastdfs.network_timeout_in_seconds";
  public static final String PROP_KEY_CHARSET = "fastdfs.charset";
  public static final String PROP_KEY_HTTP_ANTI_STEAL_TOKEN = "fastdfs.http_anti_steal_token";
  public static final String PROP_KEY_HTTP_SECRET_KEY = "fastdfs.http_secret_key";
  public static final String PROP_KEY_HTTP_TRACKER_HTTP_PORT = "fastdfs.http_tracker_http_port";
  public static final String PROP_KEY_TRACKER_SERVERS = "fastdfs.tracker_servers";

  public static final String PROP_KEY_INNER_OUT_NET = "fastdfs.inner_out_net";

  public static final int DEFAULT_CONNECT_TIMEOUT = 5; //second
  public static final int DEFAULT_NETWORK_TIMEOUT = 30; //second
  public static final String DEFAULT_CHARSET = "UTF-8";
  public static final boolean DEFAULT_HTTP_ANTI_STEAL_TOKEN = false;
  public static final String DEFAULT_HTTP_SECRET_KEY = "FastDFS1234567890";
  public static final int DEFAULT_HTTP_TRACKER_HTTP_PORT = 80;

  public static int g_connect_timeout = DEFAULT_CONNECT_TIMEOUT * 1000; //millisecond
  public static int g_network_timeout = DEFAULT_NETWORK_TIMEOUT * 1000; //millisecond
  public static String g_charset = DEFAULT_CHARSET;
  public static boolean g_anti_steal_token = DEFAULT_HTTP_ANTI_STEAL_TOKEN; //if anti-steal token
  public static String g_secret_key = DEFAULT_HTTP_SECRET_KEY; //generage token secret key
  public static int g_tracker_http_port = DEFAULT_HTTP_TRACKER_HTTP_PORT;

  public static TrackerGroup g_tracker_group;

  public static Map<String,String> InnerOutNet;

  private ClientGlobal() {
  }

  /**
   * load global variables
   *
   * @param conf_filename config filename
   */
  public static void init(String conf_filename) throws IOException, MyException {
    IniFileReader iniReader;
    String[] szTrackerServers;
    String[] parts;

    iniReader = new IniFileReader(conf_filename);

    g_connect_timeout = iniReader.getIntValue("connect_timeout", DEFAULT_CONNECT_TIMEOUT);
    if (g_connect_timeout < 0) {
      g_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
    }
    g_connect_timeout *= 1000; //millisecond

    g_network_timeout = iniReader.getIntValue("network_timeout", DEFAULT_NETWORK_TIMEOUT);
    if (g_network_timeout < 0) {
      g_network_timeout = DEFAULT_NETWORK_TIMEOUT;
    }
    g_network_timeout *= 1000; //millisecond

    g_charset = iniReader.getStrValue("charset");
    if (g_charset == null || g_charset.length() == 0) {
      g_charset = "ISO8859-1";
    }

    szTrackerServers = iniReader.getValues("tracker_server");
    if (szTrackerServers == null) {
      throw new MyException("item \"tracker_server\" in " + conf_filename + " not found");
    }

    InetSocketAddress[] tracker_servers = new InetSocketAddress[szTrackerServers.length];
    for (int i = 0; i < szTrackerServers.length; i++) {
      parts = szTrackerServers[i].split("\\:", 2);
      if (parts.length != 2) {
        throw new MyException("the value of item \"tracker_server\" is invalid, the correct format is host:port");
      }

      tracker_servers[i] = new InetSocketAddress(parts[0].trim(), Integer.parseInt(parts[1].trim()));
    }
    g_tracker_group = new TrackerGroup(tracker_servers);

    g_tracker_http_port = iniReader.getIntValue("http.tracker_http_port", 80);
    g_anti_steal_token = iniReader.getBoolValue("http.anti_steal_token", false);
    if (g_anti_steal_token) {
      g_secret_key = iniReader.getStrValue("http.secret_key");
    }

    String[] storyInnerOutNet = iniReader.getValues("fastdfs.inner_out_net");
    if(storyInnerOutNet!=null){
      if(InnerOutNet==null){
        InnerOutNet = new HashMap<String,String>();
      }
      for (int i = 0; i < storyInnerOutNet.length; i++) {
        String innerOutNet = storyInnerOutNet[i];
        String key = innerOutNet.split(":")[0];
        String value = innerOutNet.split(":")[1];
        InnerOutNet.put(key,value);
      }
    }
  }

  public static String getChangeInnerToOutNet(String innerNet){
    if(InnerOutNet!=null){
      if(InnerOutNet.containsKey(innerNet)){
        return InnerOutNet.get(innerNet);
      }
    }
    return innerNet;
  }

  /**
   * load from properties file
   *
   * @param propsFilePath properties file path, eg:
   *                      "fastdfs-client.properties"
   *                      "config/fastdfs-client.properties"
   *                      "/opt/fastdfs-client.properties"
   *                      "C:\\Users\\James\\config\\fastdfs-client.properties"
   *                      properties文件至少包含一个配置项 fastdfs.tracker_servers 例如:
   *                      fastdfs.tracker_servers = 10.0.11.245:22122,10.0.11.246:22122
   *                      server的IP和端口用冒号':'分隔
   *                      server之间用逗号','分隔
   */
  public static void initByProperties(String propsFilePath) throws IOException, MyException {
    Properties props = new Properties();
    InputStream in = IniFileReader.loadFromOsFileSystemOrClasspathAsStream(propsFilePath);
    if (in != null) {
      props.load(in);
    }
    initByProperties(props);
  }

  public static void initByProperties(Properties props) throws IOException, MyException {
    String trackerServersConf = props.getProperty(PROP_KEY_TRACKER_SERVERS);
    if (trackerServersConf == null || trackerServersConf.trim().length() == 0) {
      throw new MyException(String.format("configure item %s is required", PROP_KEY_TRACKER_SERVERS));
    }
    initByTrackers(trackerServersConf.trim());

    String connectTimeoutInSecondsConf = props.getProperty(PROP_KEY_CONNECT_TIMEOUT_IN_SECONDS);
    String networkTimeoutInSecondsConf = props.getProperty(PROP_KEY_NETWORK_TIMEOUT_IN_SECONDS);
    String charsetConf = props.getProperty(PROP_KEY_CHARSET);
    String httpAntiStealTokenConf = props.getProperty(PROP_KEY_HTTP_ANTI_STEAL_TOKEN);
    String httpSecretKeyConf = props.getProperty(PROP_KEY_HTTP_SECRET_KEY);
    String httpTrackerHttpPortConf = props.getProperty(PROP_KEY_HTTP_TRACKER_HTTP_PORT);

    String innerOutNet = props.getProperty(PROP_KEY_INNER_OUT_NET);
    if (connectTimeoutInSecondsConf != null && connectTimeoutInSecondsConf.trim().length() != 0) {
      g_connect_timeout = Integer.parseInt(connectTimeoutInSecondsConf.trim()) * 1000;
    }
    if (networkTimeoutInSecondsConf != null && networkTimeoutInSecondsConf.trim().length() != 0) {
      g_network_timeout = Integer.parseInt(networkTimeoutInSecondsConf.trim()) * 1000;
    }
    if (charsetConf != null && charsetConf.trim().length() != 0) {
      g_charset = charsetConf.trim();
    }
    if (httpAntiStealTokenConf != null && httpAntiStealTokenConf.trim().length() != 0) {
      g_anti_steal_token = Boolean.parseBoolean(httpAntiStealTokenConf);
    }
    if (httpSecretKeyConf != null && httpSecretKeyConf.trim().length() != 0) {
      g_secret_key = httpSecretKeyConf.trim();
    }
    if (httpTrackerHttpPortConf != null && httpTrackerHttpPortConf.trim().length() != 0) {
      g_tracker_http_port = Integer.parseInt(httpTrackerHttpPortConf);
    }
    initStoryInnerOutNet(innerOutNet.trim());
  }

  public static void initStoryInnerOutNet(String innerOutNetString){
    if(innerOutNetString!=null&&!"".equals(innerOutNetString)){
      String[] storyInnerOutNet = innerOutNetString.split(",");
      if(storyInnerOutNet!=null){
        if(InnerOutNet==null){
          InnerOutNet = new HashMap<String,String>();
        }
        for (int i = 0; i < storyInnerOutNet.length; i++) {
          String innerOutNet = storyInnerOutNet[i];
          String key = innerOutNet.split(":")[0];
          String value = innerOutNet.split(":")[1];
          InnerOutNet.put(key,value);
        }
      }
    }
  }

  /**
   * load from properties file
   *
   * @param trackerServers 例如:"10.0.11.245:22122,10.0.11.246:22122"
   *                       server的IP和端口用冒号':'分隔
   *                       server之间用逗号','分隔
   */
  public static void initByTrackers(String trackerServers) throws IOException, MyException {
    List<InetSocketAddress> list = new ArrayList();
    String spr1 = ",";
    String spr2 = ":";
    String[] arr1 = trackerServers.trim().split(spr1);
    for (String addrStr : arr1) {
      String[] arr2 = addrStr.trim().split(spr2);
      String host = arr2[0].trim();
      int port = Integer.parseInt(arr2[1].trim());
      list.add(new InetSocketAddress(host, port));
    }
    InetSocketAddress[] trackerAddresses = list.toArray(new InetSocketAddress[list.size()]);
    initByTrackers(trackerAddresses);
  }

  public static void initByTrackers(InetSocketAddress[] trackerAddresses) throws IOException, MyException {
    g_tracker_group = new TrackerGroup(trackerAddresses);
  }

  /**
   * construct Socket object
   *
   * @param ip_addr ip address or hostname
   * @param port    port number
   * @return connected Socket object
   */
  public static Socket getSocket(String ip_addr, int port) throws IOException {
    Socket sock = new Socket();
    sock.setSoTimeout(ClientGlobal.g_network_timeout);
    sock.connect(new InetSocketAddress(ip_addr, port), ClientGlobal.g_connect_timeout);
    return sock;
  }

  /**
   * construct Socket object
   *
   * @param addr InetSocketAddress object, including ip address and port
   * @return connected Socket object
   */
  public static Socket getSocket(InetSocketAddress addr) throws IOException {
    Socket sock = new Socket();
    sock.setSoTimeout(ClientGlobal.g_network_timeout);
    sock.connect(addr, ClientGlobal.g_connect_timeout);
    return sock;
  }

  public static int getG_connect_timeout() {
    return g_connect_timeout;
  }

  public static void setG_connect_timeout(int connect_timeout) {
    ClientGlobal.g_connect_timeout = connect_timeout;
  }

  public static int getG_network_timeout() {
    return g_network_timeout;
  }

  public static void setG_network_timeout(int network_timeout) {
    ClientGlobal.g_network_timeout = network_timeout;
  }

  public static String getG_charset() {
    return g_charset;
  }

  public static void setG_charset(String charset) {
    ClientGlobal.g_charset = charset;
  }

  public static int getG_tracker_http_port() {
    return g_tracker_http_port;
  }

  public static void setG_tracker_http_port(int tracker_http_port) {
    ClientGlobal.g_tracker_http_port = tracker_http_port;
  }

  public static boolean getG_anti_steal_token() {
    return g_anti_steal_token;
  }

  public static boolean isG_anti_steal_token() {
    return g_anti_steal_token;
  }

  public static void setG_anti_steal_token(boolean anti_steal_token) {
    ClientGlobal.g_anti_steal_token = anti_steal_token;
  }

  public static String getG_secret_key() {
    return g_secret_key;
  }

  public static void setG_secret_key(String secret_key) {
    ClientGlobal.g_secret_key = secret_key;
  }

  public static TrackerGroup getG_tracker_group() {
    return g_tracker_group;
  }

  public static void setG_tracker_group(TrackerGroup tracker_group) {
    ClientGlobal.g_tracker_group = tracker_group;
  }

  public static String configInfo() {
    String trackerServers = "";
    if (g_tracker_group != null) {
      InetSocketAddress[] trackerAddresses = g_tracker_group.tracker_servers;
      for (InetSocketAddress inetSocketAddress : trackerAddresses) {
        if(trackerServers.length() > 0) trackerServers += ",";
        trackerServers += inetSocketAddress.toString().substring(1);
      }
    }
    return "{"
      + "\n  g_connect_timeout(ms) = " + g_connect_timeout
      + "\n  g_network_timeout(ms) = " + g_network_timeout
      + "\n  g_charset = " + g_charset
      + "\n  g_anti_steal_token = " + g_anti_steal_token
      + "\n  g_secret_key = " + g_secret_key
      + "\n  g_tracker_http_port = " + g_tracker_http_port
      + "\n  trackerServers = " + trackerServers
      + "\n}";
  }

}


在这里插入图片描述
添加了内外网的相互转化

/**
 * Copyright (C) 2008 Happy Fish / YuQing
 * <p>
 * FastDFS Java Client may be copied only under the terms of the GNU Lesser
 * General Public License (LGPL).
 * Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
 */

package org.csource.fastdfs;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;

/**
 * Tracker client
 *
 * @author Happy Fish / YuQing
 * @version Version 1.19
 */
public class TrackerClient {
  protected TrackerGroup tracker_group;
  protected byte errno;

  /**
   * constructor with global tracker group
   */
  public TrackerClient() {
    this.tracker_group = ClientGlobal.g_tracker_group;
  }

  /**
   * constructor with specified tracker group
   *
   * @param tracker_group the tracker group object
   */
  public TrackerClient(TrackerGroup tracker_group) {
    this.tracker_group = tracker_group;
  }

  /**
   * get the error code of last call
   *
   * @return the error code of last call
   */
  public byte getErrorCode() {
    return this.errno;
  }

  /**
   * get a connection to tracker server
   *
   * @return tracker server Socket object, return null if fail
   */
  public TrackerServer getConnection() throws IOException {
    return this.tracker_group.getConnection();
  }

  /**
   * query storage server to upload file
   *
   * @param trackerServer the tracker server
   * @return storage server Socket object, return null if fail
   */
  public StorageServer getStoreStorage(TrackerServer trackerServer) throws IOException {
    final String groupName = null;
    return this.getStoreStorage(trackerServer, groupName);
  }

  /**
   * query storage server to upload file
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name to upload file to, can be empty
   * @return storage server object, return null if fail
   */
  public StorageServer getStoreStorage(TrackerServer trackerServer, String groupName) throws IOException {
    byte[] header;
    String ip_addr;
    int port;
    byte cmd;
    int out_len;
    boolean bNewConnection;
    byte store_path;
    Socket trackerSocket;

    if (trackerServer == null) {
      trackerServer = getConnection();
      if (trackerServer == null) {
        return null;
      }
      bNewConnection = true;
    } else {
      bNewConnection = false;
    }

    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    try {
      if (groupName == null || groupName.length() == 0) {
        cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE;
        out_len = 0;
      } else {
        cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE;
        out_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
      }
      header = ProtoCommon.packHeader(cmd, out_len, (byte) 0);
      out.write(header);

      if (groupName != null && groupName.length() > 0) {
        byte[] bGroupName;
        byte[] bs;
        int group_len;

        bs = groupName.getBytes(ClientGlobal.g_charset);
        bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];

        if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
          group_len = bs.length;
        } else {
          group_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
        }
        Arrays.fill(bGroupName, (byte) 0);
        System.arraycopy(bs, 0, bGroupName, 0, group_len);
        out.write(bGroupName);
      }

      ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
        ProtoCommon.TRACKER_PROTO_CMD_RESP,
        ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN);
      this.errno = pkgInfo.errno;
      if (pkgInfo.errno != 0) {
        return null;
      }

      ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim();

      port = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN
        + ProtoCommon.FDFS_IPADDR_SIZE - 1);
      store_path = pkgInfo.body[ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1];

      ip_addr = ClientGlobal.getChangeInnerToOutNet(ip_addr);
      return new StorageServer(ip_addr, port, store_path);
    } catch (IOException ex) {
      if (!bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }

      throw ex;
    } finally {
      if (bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }
  }

  /**
   * query storage servers to upload file
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name to upload file to, can be empty
   * @return storage servers, return null if fail
   */
  public StorageServer[] getStoreStorages(TrackerServer trackerServer, String groupName) throws IOException {
    byte[] header;
    String ip_addr;
    int port;
    byte cmd;
    int out_len;
    boolean bNewConnection;
    Socket trackerSocket;

    if (trackerServer == null) {
      trackerServer = getConnection();
      if (trackerServer == null) {
        return null;
      }
      bNewConnection = true;
    } else {
      bNewConnection = false;
    }

    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    try {
      if (groupName == null || groupName.length() == 0) {
        cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ALL;
        out_len = 0;
      } else {
        cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ALL;
        out_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
      }
      header = ProtoCommon.packHeader(cmd, out_len, (byte) 0);
      out.write(header);

      if (groupName != null && groupName.length() > 0) {
        byte[] bGroupName;
        byte[] bs;
        int group_len;

        bs = groupName.getBytes(ClientGlobal.g_charset);
        bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];

        if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
          group_len = bs.length;
        } else {
          group_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
        }
        Arrays.fill(bGroupName, (byte) 0);
        System.arraycopy(bs, 0, bGroupName, 0, group_len);
        out.write(bGroupName);
      }

      ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
        ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
      this.errno = pkgInfo.errno;
      if (pkgInfo.errno != 0) {
        return null;
      }

      if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN) {
        this.errno = ProtoCommon.ERR_NO_EINVAL;
        return null;
      }

      int ipPortLen = pkgInfo.body.length - (ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + 1);
      final int recordLength = ProtoCommon.FDFS_IPADDR_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE;

      if (ipPortLen % recordLength != 0) {
        this.errno = ProtoCommon.ERR_NO_EINVAL;
        return null;
      }

      int serverCount = ipPortLen / recordLength;
      if (serverCount > 16) {
        this.errno = ProtoCommon.ERR_NO_ENOSPC;
        return null;
      }

      StorageServer[] results = new StorageServer[serverCount];
      byte store_path = pkgInfo.body[pkgInfo.body.length - 1];
      int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;

      for (int i = 0; i < serverCount; i++) {
        ip_addr = new String(pkgInfo.body, offset, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim();
        offset += ProtoCommon.FDFS_IPADDR_SIZE - 1;

        port = (int) ProtoCommon.buff2long(pkgInfo.body, offset);
        offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE;

        ip_addr = ClientGlobal.getChangeInnerToOutNet(ip_addr);
        results[i] = new StorageServer(ip_addr, port, store_path);
      }

      return results;
    } catch (IOException ex) {
      if (!bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }

      throw ex;
    } finally {
      if (bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }
  }

  /**
   * query storage server to download file
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name of storage server
   * @param filename      filename on storage server
   * @return storage server Socket object, return null if fail
   */
  public StorageServer getFetchStorage(TrackerServer trackerServer,
                                       String groupName, String filename) throws IOException {
    ServerInfo[] servers = this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE,
      groupName, filename);
    if (servers == null) {
      return null;
    } else {
      return new StorageServer(servers[0].getIpAddr(), servers[0].getPort(), 0);
    }
  }

  /**
   * query storage server to update file (delete file or set meta data)
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name of storage server
   * @param filename      filename on storage server
   * @return storage server Socket object, return null if fail
   */
  public StorageServer getUpdateStorage(TrackerServer trackerServer,
                                        String groupName, String filename) throws IOException {
    ServerInfo[] servers = this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE,
      groupName, filename);
    if (servers == null) {
      return null;
    } else {
      return new StorageServer(servers[0].getIpAddr(), servers[0].getPort(), 0);
    }
  }

  /**
   * get storage servers to download file
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name of storage server
   * @param filename      filename on storage server
   * @return storage servers, return null if fail
   */
  public ServerInfo[] getFetchStorages(TrackerServer trackerServer,
                                       String groupName, String filename) throws IOException {
    return this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL,
      groupName, filename);
  }

  /**
   * query storage server to download file
   *
   * @param trackerServer the tracker server
   * @param cmd           command code, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE or
   *                      ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE
   * @param groupName     the group name of storage server
   * @param filename      filename on storage server
   * @return storage server Socket object, return null if fail
   */
  protected ServerInfo[] getStorages(TrackerServer trackerServer,
                                     byte cmd, String groupName, String filename) throws IOException {
    byte[] header;
    byte[] bFileName;
    byte[] bGroupName;
    byte[] bs;
    int len;
    String ip_addr;
    int port;
    boolean bNewConnection;
    Socket trackerSocket;

    if (trackerServer == null) {
      trackerServer = getConnection();
      if (trackerServer == null) {
        return null;
      }
      bNewConnection = true;
    } else {
      bNewConnection = false;
    }
    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    try {
      bs = groupName.getBytes(ClientGlobal.g_charset);
      bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];
      bFileName = filename.getBytes(ClientGlobal.g_charset);

      if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
        len = bs.length;
      } else {
        len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
      }
      Arrays.fill(bGroupName, (byte) 0);
      System.arraycopy(bs, 0, bGroupName, 0, len);

      header = ProtoCommon.packHeader(cmd, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + bFileName.length, (byte) 0);
      byte[] wholePkg = new byte[header.length + bGroupName.length + bFileName.length];
      System.arraycopy(header, 0, wholePkg, 0, header.length);
      System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
      System.arraycopy(bFileName, 0, wholePkg, header.length + bGroupName.length, bFileName.length);
      out.write(wholePkg);

      ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
        ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
      this.errno = pkgInfo.errno;
      if (pkgInfo.errno != 0) {
        return null;
      }

      if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) {
        throw new IOException("Invalid body length: " + pkgInfo.body.length);
      }

      if ((pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) % (ProtoCommon.FDFS_IPADDR_SIZE - 1) != 0) {
        throw new IOException("Invalid body length: " + pkgInfo.body.length);
      }

      int server_count = 1 + (pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) / (ProtoCommon.FDFS_IPADDR_SIZE - 1);

      ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim();
      int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ProtoCommon.FDFS_IPADDR_SIZE - 1;

      port = (int) ProtoCommon.buff2long(pkgInfo.body, offset);
      offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE;

      ServerInfo[] servers = new ServerInfo[server_count];
      ip_addr = ClientGlobal.getChangeInnerToOutNet(ip_addr);
      servers[0] = new ServerInfo(ip_addr, port);
      for (int i = 1; i < server_count; i++) {
        servers[i] = new ServerInfo(new String(pkgInfo.body, offset, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim(), port);
        offset += ProtoCommon.FDFS_IPADDR_SIZE - 1;
      }

      return servers;
    } catch (IOException ex) {
      if (!bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }

      throw ex;
    } finally {
      if (bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }
  }

  /**
   * query storage server to download file
   *
   * @param trackerServer the tracker server
   * @param file_id       the file id(including group name and filename)
   * @return storage server Socket object, return null if fail
   */
  public StorageServer getFetchStorage1(TrackerServer trackerServer, String file_id) throws IOException {
    String[] parts = new String[2];
    this.errno = StorageClient1.split_file_id(file_id, parts);
    if (this.errno != 0) {
      return null;
    }

    return this.getFetchStorage(trackerServer, parts[0], parts[1]);
  }

  /**
   * get storage servers to download file
   *
   * @param trackerServer the tracker server
   * @param file_id       the file id(including group name and filename)
   * @return storage servers, return null if fail
   */
  public ServerInfo[] getFetchStorages1(TrackerServer trackerServer, String file_id) throws IOException {
    String[] parts = new String[2];
    this.errno = StorageClient1.split_file_id(file_id, parts);
    if (this.errno != 0) {
      return null;
    }

    return this.getFetchStorages(trackerServer, parts[0], parts[1]);
  }

  /**
   * list groups
   *
   * @param trackerServer the tracker server
   * @return group stat array, return null if fail
   */
  public StructGroupStat[] listGroups(TrackerServer trackerServer) throws IOException {
    byte[] header;
    String ip_addr;
    int port;
    byte cmd;
    int out_len;
    boolean bNewConnection;
    byte store_path;
    Socket trackerSocket;

    if (trackerServer == null) {
      trackerServer = getConnection();
      if (trackerServer == null) {
        return null;
      }
      bNewConnection = true;
    } else {
      bNewConnection = false;
    }

    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    try {
      header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_LIST_GROUP, 0, (byte) 0);
      out.write(header);

      ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
        ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
      this.errno = pkgInfo.errno;
      if (pkgInfo.errno != 0) {
        return null;
      }

      ProtoStructDecoder<StructGroupStat> decoder = new ProtoStructDecoder<StructGroupStat>();
      return decoder.decode(pkgInfo.body, StructGroupStat.class, StructGroupStat.getFieldsTotalSize());
    } catch (IOException ex) {
      if (!bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }

      throw ex;
    } catch (Exception ex) {
      ex.printStackTrace();
      this.errno = ProtoCommon.ERR_NO_EINVAL;
      return null;
    } finally {
      if (bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }
  }

  /**
   * query storage server stat info of the group
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name of storage server
   * @return storage server stat array, return null if fail
   */
  public StructStorageStat[] listStorages(TrackerServer trackerServer, String groupName) throws IOException {
    final String storageIpAddr = null;
    return this.listStorages(trackerServer, groupName, storageIpAddr);
  }

  /**
   * query storage server stat info of the group
   *
   * @param trackerServer the tracker server
   * @param groupName     the group name of storage server
   * @param storageIpAddr the storage server ip address, can be null or empty
   * @return storage server stat array, return null if fail
   */
  public StructStorageStat[] listStorages(TrackerServer trackerServer,
                                          String groupName, String storageIpAddr) throws IOException {
    byte[] header;
    byte[] bGroupName;
    byte[] bs;
    int len;
    boolean bNewConnection;
    Socket trackerSocket;

    if (trackerServer == null) {
      trackerServer = getConnection();
      if (trackerServer == null) {
        return null;
      }
      bNewConnection = true;
    } else {
      bNewConnection = false;
    }
    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    try {
      bs = groupName.getBytes(ClientGlobal.g_charset);
      bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];

      if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
        len = bs.length;
      } else {
        len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
      }
      Arrays.fill(bGroupName, (byte) 0);
      System.arraycopy(bs, 0, bGroupName, 0, len);

      int ipAddrLen;
      byte[] bIpAddr;
      if (storageIpAddr != null && storageIpAddr.length() > 0) {
        bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset);
        if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE) {
          ipAddrLen = bIpAddr.length;
        } else {
          ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1;
        }
      } else {
        bIpAddr = null;
        ipAddrLen = 0;
      }

      header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_LIST_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte) 0);
      byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen];
      System.arraycopy(header, 0, wholePkg, 0, header.length);
      System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
      if (ipAddrLen > 0) {
        System.arraycopy(bIpAddr, 0, wholePkg, header.length + bGroupName.length, ipAddrLen);
      }
      out.write(wholePkg);

      ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
        ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
      this.errno = pkgInfo.errno;
      if (pkgInfo.errno != 0) {
        return null;
      }

      ProtoStructDecoder<StructStorageStat> decoder = new ProtoStructDecoder<StructStorageStat>();
      return decoder.decode(pkgInfo.body, StructStorageStat.class, StructStorageStat.getFieldsTotalSize());
    } catch (IOException ex) {
      if (!bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }

      throw ex;
    } catch (Exception ex) {
      ex.printStackTrace();
      this.errno = ProtoCommon.ERR_NO_EINVAL;
      return null;
    } finally {
      if (bNewConnection) {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }
  }

  /**
   * delete a storage server from the tracker server
   *
   * @param trackerServer the connected tracker server
   * @param groupName     the group name of storage server
   * @param storageIpAddr the storage server ip address
   * @return true for success, false for fail
   */
  private boolean deleteStorage(TrackerServer trackerServer,
                                String groupName, String storageIpAddr) throws IOException {
    byte[] header;
    byte[] bGroupName;
    byte[] bs;
    int len;
    Socket trackerSocket;

    trackerSocket = trackerServer.getSocket();
    OutputStream out = trackerSocket.getOutputStream();

    bs = groupName.getBytes(ClientGlobal.g_charset);
    bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN];

    if (bs.length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) {
      len = bs.length;
    } else {
      len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
    }
    Arrays.fill(bGroupName, (byte) 0);
    System.arraycopy(bs, 0, bGroupName, 0, len);

    int ipAddrLen;
    byte[] bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset);
    if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE) {
      ipAddrLen = bIpAddr.length;
    } else {
      ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1;
    }

    header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_DELETE_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte) 0);
    byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen];
    System.arraycopy(header, 0, wholePkg, 0, header.length);
    System.arraycopy(bGroupName, 0, wholePkg, header.length, bGroupName.length);
    System.arraycopy(bIpAddr, 0, wholePkg, header.length + bGroupName.length, ipAddrLen);
    out.write(wholePkg);

    ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.getInputStream(),
      ProtoCommon.TRACKER_PROTO_CMD_RESP, 0);
    this.errno = pkgInfo.errno;
    return pkgInfo.errno == 0;
  }

  /**
   * delete a storage server from the global FastDFS cluster
   *
   * @param groupName     the group name of storage server
   * @param storageIpAddr the storage server ip address
   * @return true for success, false for fail
   */
  public boolean deleteStorage(String groupName, String storageIpAddr) throws IOException {
    return this.deleteStorage(ClientGlobal.g_tracker_group, groupName, storageIpAddr);
  }

  /**
   * delete a storage server from the FastDFS cluster
   *
   * @param trackerGroup  the tracker server group
   * @param groupName     the group name of storage server
   * @param storageIpAddr the storage server ip address
   * @return true for success, false for fail
   */
  public boolean deleteStorage(TrackerGroup trackerGroup,
                               String groupName, String storageIpAddr) throws IOException {
    int serverIndex;
    int notFoundCount;
    TrackerServer trackerServer;

    notFoundCount = 0;
    for (serverIndex = 0; serverIndex < trackerGroup.tracker_servers.length; serverIndex++) {
      try {
        trackerServer = trackerGroup.getConnection(serverIndex);
      } catch (IOException ex) {
        ex.printStackTrace(System.err);
        this.errno = ProtoCommon.ECONNREFUSED;
        return false;
      }

      try {
        StructStorageStat[] storageStats = listStorages(trackerServer, groupName, storageIpAddr);
        if (storageStats == null) {
          if (this.errno == ProtoCommon.ERR_NO_ENOENT) {
            notFoundCount++;
          } else {
            return false;
          }
        } else if (storageStats.length == 0) {
          notFoundCount++;
        } else if (storageStats[0].getStatus() == ProtoCommon.FDFS_STORAGE_STATUS_ONLINE ||
          storageStats[0].getStatus() == ProtoCommon.FDFS_STORAGE_STATUS_ACTIVE) {
          this.errno = ProtoCommon.ERR_NO_EBUSY;
          return false;
        }
      } finally {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }

    if (notFoundCount == trackerGroup.tracker_servers.length) {
      this.errno = ProtoCommon.ERR_NO_ENOENT;
      return false;
    }

    notFoundCount = 0;
    for (serverIndex = 0; serverIndex < trackerGroup.tracker_servers.length; serverIndex++) {
      try {
        trackerServer = trackerGroup.getConnection(serverIndex);
      } catch (IOException ex) {
        System.err.println("connect to server " + trackerGroup.tracker_servers[serverIndex].getAddress().getHostAddress() + ":" + trackerGroup.tracker_servers[serverIndex].getPort() + " fail");
        ex.printStackTrace(System.err);
        this.errno = ProtoCommon.ECONNREFUSED;
        return false;
      }

      try {
        if (!this.deleteStorage(trackerServer, groupName, storageIpAddr)) {
          if (this.errno != 0) {
            if (this.errno == ProtoCommon.ERR_NO_ENOENT) {
              notFoundCount++;
            } else if (this.errno != ProtoCommon.ERR_NO_EALREADY) {
              return false;
            }
          }
        }
      } finally {
        try {
          trackerServer.close();
        } catch (IOException ex1) {
          ex1.printStackTrace();
        }
      }
    }

    if (notFoundCount == trackerGroup.tracker_servers.length) {
      this.errno = ProtoCommon.ERR_NO_ENOENT;
      return false;
    }

    if (this.errno == ProtoCommon.ERR_NO_ENOENT) {
      this.errno = 0;
    }

    return this.errno == 0;
  }
}

在这里插入图片描述
此处在获取storage 时 内网转化成外网

到此fastdfs的 问题解决,若还有别的问题,请联系!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值