Home » ops » FastDFS的坑以及补救方案
FastDFS的坑以及补救方案

终于把FastDFS搭起来并在线上环境中稳定下来了,这其中发现了很多问题,除了完全没文档这个大坑之外,还有一些不小的坑。

  1. 如果需要自定义FastDFS的安装路径,需要手动修改源码中make.sh里面TARGET_PREFIX和TARGET_CONF_PATH这2个字段,而不是通过 configure 指定 --prefix 的方式。

    并且需要注意的是,目前稳定的版本是5.0.3,其他的版本都会有一些bug.

  2. 编译FastDFS完成之后,需要 cp /path/to/fdfs/lib/* /usr/local/lib/, 然后 ln -s libfastcommon.so /usr/local/lib/libfastcommon.so.1 && ln -s libfastclient.so /usr/local/lib/libfastclient.so.1.

  3. 客户端安装php-client的时候,源码包种的 php-client/configure 文件中需要修改第3415行,改成 ROOT=/path/to/your/fdfs.

  4. 线上运行一段时间后,系统就不能传图了,报的错误是connection reset by beer.

    这个问题实际上是TCP连接没有被释放掉,通过命令 netstat -antp | grep fdfs | wc -l 可以看到 上传图片完成后tcp连接数是一直增加的,直到超过FastDFS能处理的最大值.

    要解决这个问题,首先要确保客户端,也就是安装了php模块的app服务器中 /path/to/your/fdfs/conf/client.conf 文件中 use_connection_pool 字段 只能false,作者在php客户端使用连接池连接FastDFS的代码中有bug,所以客户端不能开启连接池。

    然后,在封装保存接口的时候,最好使用类的方法,并且要手动关掉tracker的连接,如下:

    public static function save($filename) {
        $fdfs = new FastDFS();
        $file_info = $fdfs->storage_upload_by_filename1($filename);
        $fdfs->tracker_close_all_connections();
        $fdfs->close();
        return $file_info;
    }
    

    并且如果修改之后要手动重启php-fpm: service php-fpm restart . 最好在部署FastDFS的机器上也补上一个脚本加入到crontab中,判断连接数过大则重启app服务器的php-fpm:

    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash
    
    conn_count=`netstat -antp | grep fdfs | wc -l`
    
    if [ $conn_count -gt 500 ]; then
        ssh root@your_app_server_ip "service php-fpm restart"
    fi
    
  5. 会有内存溢出的可能

    如果调用 vmstat 命令发现cache字段过大,并且 free 发现内存使用过大,那么有可能是FastDFS导致的内存泄露问题。

    这个问题应该属于FastDFS的bug,现在只能写一个补救脚本加入到crontab中:

    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash
    
    mem=`free -m | awk 'NR==2{print $4}'`
    
    if [ $mem -lt 1024 ]; then
        echo "1" > /proc/sys/vm/drop_caches
    fi
    

最后,将FastDFS部署到线上作为一个稳定的服务是不明智的行为,拿它做简单的内部日志存储还行,但是作为一个线上服务,现阶段它还明显不适合。