最近遇到视频上传很慢的情况,20M大约需要花费一分钟才能上传玩,但是通过

ftp nfs smb_ftp nfs smb

ftp测试,发现时长4s左右,阿里云2M的带宽,以下的测试都是以阿里云2M的带宽做的一个测试的结果。

1.不带缓冲区

2M带宽下,20M的视频,上传时长大约为60s,多次测试,取平均值

/**
     * 上传文件(可供Action/Controller层使用)
     * 
     * @param hostname
     *            FTP服务器地址
     * @param port
     *            FTP服务器端口号
     * @param username
     *            FTP登录帐号
     * @param password
     *            FTP登录密码
     * @param pathname
     *            FTP服务器保存目录
     * @param fileName
     *            上传到FTP服务器后的文件名称
     * @param inputStream
     *            输入文件流
     * @return
     */
    public static boolean uploadFile(String hostname, int port, String username, String password, String pathname,
            String fileName, InputStream inputStream) {
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");
        try {
            // 连接FTP服务器
            ftpClient.connect(hostname, port);
            // 登录FTP服务器
            ftpClient.login(username, password);
            // 是否成功登录FTP服务器
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                return flag;
            }
            //指定上传文件的类型  二进制文件
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //检查上传路径是否存在 如果不存在返回false
            boolean pathFlagExist = createDir(ftpClient, pathname);
            if(!pathFlagExist){
                return false;
            }
            //这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上或者其他服务器上面,由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决。
            ftpClient.enterLocalPassiveMode();
            //设置上传目录  
            ftpClient.changeWorkingDirectory(pathname);
       
            ftpClient.storeFile(fileName, inputStream);
            inputStream.close();
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            logger.info("上传失败"+e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.info("上传文件-->关闭连接失败"+e);
                }
            }
        }
        return flag;
    }

2.增加缓存代码

2M带宽下,20M的视频,上传时长大约为11s,多次测试,取平均值

/**
     * 上传文件(可供Action/Controller层使用)
     * 
     * @param hostname
     *            FTP服务器地址
     * @param port
     *            FTP服务器端口号
     * @param username
     *            FTP登录帐号
     * @param password
     *            FTP登录密码
     * @param pathname
     *            FTP服务器保存目录
     * @param fileName
     *            上传到FTP服务器后的文件名称
     * @param inputStream
     *            输入文件流
     * @return
     */
    public static boolean uploadFile(String hostname, int port, String username, String password, String pathname,
            String fileName, InputStream inputStream) {
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");
        try {
            // 连接FTP服务器
            ftpClient.connect(hostname, port);
            // 登录FTP服务器
            ftpClient.login(username, password);
            // 是否成功登录FTP服务器
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                return flag;
            }
            //指定上传文件的类型  二进制文件
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //检查上传路径是否存在 如果不存在返回false
            boolean pathFlagExist = createDir(ftpClient, pathname);
            if(!pathFlagExist){
                return false;
            }
            //这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上或者其他服务器上面,由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决。
            ftpClient.enterLocalPassiveMode();
            //设置上传目录  
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.setBufferSize(1024*1024);
            BufferedInputStream input = new BufferedInputStream(inputStream);
            ftpClient.storeFile(fileName, input);
            inputStream.close();
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            logger.info("上传失败"+e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.info("上传文件-->关闭连接失败"+e);
                }
            }
        }
        return flag;
    }

实际上就是增加两句话

添加缓冲区的方式,根据上传文件的大 小,设置缓冲区大小,上传的过程中,缓冲区写满后才会进行磁盘的读写操作

ftpClient.setBufferSize(1024*1024);
BufferedInputStream input = new BufferedInputStream(inputStream);

3.结论

  通过设置缓冲区,性能大小差不多提升了快6倍,如果有好的优化方法,可以在下方留言