跳至主要內容

FastDFS组件

杨轩-国实信息大约 2 分钟常用组件接口文档

git地址:

http://10.16.202.103:8089/component/component-ser/fastdfs-client-java-ss

修改自官方源码1.3.0版本:

https://github.com/happyfish100/fastdfs-client-java

要解决的问题

在DMZ访问金宏网的FastDFS时,网闸代理的是TrackerServer的22122端口,但是实际存储时使用的是StorageServer的23000端口。StorageServer的ip和port是由TrackerServer查询返回的,这个过程中FastDFS会返回没有代理过的ip和port,导致文件无法正常上传。

流程如下图所示。

所以要做的就是DMZ内,不通过TrackServer获取StorageServer的地址,从本地配置文件读取它的ip和port。

使用

添加依赖:

<dependency>
    <groupId>com.gosci.tech</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.30-SNAPSHOT</version>
</dependency>

配置文件修改:

原先的fastdfs-client.properties的内容不需要修改,只需要添加一行配置(ip地址和TrackerServer相同,StorageServer的默认端口是23000):

fastdfs.storage_servers = 192.168.98.103:23000

在有这一行配置时,会直接使用这个地址连接StorageServer。没有这行配置时,仍然走之前的通过TrackerServer进行发现。

改造原理

ClientGlobal类中,读取配置文件:

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());

    // 在这添加读取fastdfs.storage_servers配置
    storage_server_conf=props.getProperty(PROP_KEY_STORAGE_SERVERS);
    initStorageServer(storage_server_conf);

    //...
}

创建静态StorageServer对象:

  private static void initStorageServer(String storage_server_conf){
    if (StrUtil.isBlank(storage_server_conf)){
      return;
    }

    String[] split = storage_server_conf.split(":");
    if (split.length!=2){
      return;
    }

    int port = Integer.parseInt(split[1]);
    try {
      storageServer= new StorageServer(split[0], port, 0);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

实际使用StorageServer在类StorageClient类1616行的函数中:

    protected boolean newWritableStorageConnection(String group_name) throws IOException, MyException {
        if (this.storageServer != null) {
            return false;
        } else {
            TrackerClient tracker = new TrackerClient();
            //获取静态StorageServer对象
            StorageServer storageServer1 = ClientGlobal.storageServer;
            if (storageServer1!=null){
                //不为null则使用
                this.storageServer=storageServer1;
            }else {
                //为null则从tracker进行获取,走原先的逻辑
                this.storageServer = tracker.getStoreStorage(this.trackerServer, group_name);
            }

            if (this.storageServer == null) {
                throw new MyException("getStoreStorage fail, errno code: " + tracker.getErrorCode());
            }
            return true;
        }
    }