`
247687009
  • 浏览: 171232 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

FastDFS(三)使用jdk5新增的并发库中的LinkedBlockingQueue实现fifo池

阅读更多

最近做的电商项目中,使用了fastDFS文件系统来作为图片和文件的存储,然后官方提供的API中并没有提供连接池的实现,必然导致每次建立连接的开销较大,为了节约系统资源和提高效率,便自己动手写一个。原理是数据库连接池类似。如有不足,和问题往指出,我加以修改

首先来看连接池的接口,我这里做的很简单
/**
 * 
* @ClassName: ITrackerServerPool
* @Description: TODO(连接池的基本接口)
* @author LiuYi
* @date 2014年5月19日 下午2:07:05
*
 */
public interface ITrackerServerPool {
        
                public TrackerServer geTrackerServer() throws Exception;
                public TrackerServer geTrackerServer(long timeout) throws Exception;
                public boolean close(TrackerServer server) throws Exception;
                public void reset() throws Exception;
                
                
}

连接池的实现
/**
 * 
* @ClassName: LinkedQueueTrackerPool
* @Description: TODO(使用jdk1.5新增的并发库LinkedBlockingQueue实现连接池)
* @author LiuYi
*
 */
public class LinkedQueueTrackerPool implements
 ITrackerServerPool{
        private LinkedBlockingQueue<TrackerServer> tspool = null; 
        private int poolSize;
        public LinkedQueueTrackerPool(String clientConfigPath, int poolSize) 
                        throws FileNotFoundException, IOException, MyException, InterruptedException {
                super();
                this.poolSize = poolSize;
                ClientGlobal.init(clientConfigPath);
                init();
        }
             /**
             * @Description: TODO(使用远DFSAPI来保持长连接,轮询,开销小于创建一个新连接)
             * @author LiuYi
              */
        private void keepingPool() {
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                                        for(TrackerServer ts : tspool){
                                                try {
                                                        ProtoCommon.activeTest(ts.getSocket());
                                                } catch (IOException e) {
                                                        e.printStackTrace();
                                                }
                                        }
                        }
                }, 30*1000, 30*1000);
                
                
        }
        /**
         * 
        * @Description: TODO(初始化方法)
        * @author LiuYi
        *  @throws IOException
        *  @throws InterruptedException  void
         */
        private void init() throws IOException, InterruptedException{
                this.tspool = new LinkedBlockingQueue<>(this.poolSize);
                for(int i=0;i<this.poolSize;i++){
                        TrackerClient tc = new TrackerClient();
                        TrackerServer ts = tc.getConnection();
                        ProtoCommon.activeTest(ts.getSocket());
                        this.tspool.put(ts);
                }
                keepingPool();
        }

        @Override
        public TrackerServer geTrackerServer() throws Exception {
                return this.tspool.poll();
        }

        @Override
        public TrackerServer geTrackerServer(long timeout) throws Exception {
                TrackerServer ts = this.geTrackerServer();
                if(ts == null){
                        return this.tspool.poll(timeout, TimeUnit.SECONDS);
                }
                return ts;
        }

        @Override
        public boolean close(TrackerServer server) throws Exception {
                        if(server != null){
                                this.tspool.put(server);
                                return true;
                        }
                return false;
        }

        @Override
        public void reset() throws Exception {
                this.init();
        }

}

下面是对客户端操作的一个封装

客户端操作的接口,很简单
public interface IDFSClient {
                public String upload(File file) throws Exception;
                public String upload(File file,NameValuePair... metaList) throws Exception;
                public File download(String fileName,String localPath) throws Exception;
                public boolean remove(String fileName) throws Exception;
                public NameValuePair[] getFileMate(String fileName) throws Exception;
                
}

接下来是一个抽象的实现
/**
 * 
* @ClassName: AbstractClientImpl
* @Description: TODO(Client的抽象实现,主要是保存一些公用方法)
* @author LiuYi
*
 */
public abstract class AbstractClientImpl implements IDFSClient {

        protected String getFileTypeName(String fileName) {
                if (fileName != null && fileName.contains(".")) {
                        fileName = fileName.substring(fileName.lastIndexOf(".") + 1);
                }
                return fileName;
        }
        /**
         * 
        * @Description: TODO(文件转换为字节数组)
        * @author LiuYi
        *  @param file
        *  @return  byte[]
         */
        protected byte[] file2Byte(File file) {
                FileInputStream fis = null;
                ByteArrayOutputStream ops = null;
                BufferedInputStream bis = null;
                try {
                        byte[] temp = new byte[2048];
                        fis = new FileInputStream(file);
                        bis = new BufferedInputStream(fis);
                        ops = new ByteArrayOutputStream(2048);
                        int n;
                        while ((n = bis.read(temp)) != -1) {
                                ops.write(temp, 0, n);
                        }
                        return ops.toByteArray();
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        try {
                                if (ops != null) {
                                        ops.close();
                                }
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                        try {
                                if (bis != null) {
                                        bis.close();
                                }
                        } catch (IOException e1) {
                                e1.printStackTrace();
                        }
                        try {
                                if (fis != null) {
                                        fis.close();
                                }
                        } catch (IOException e1) {
                                e1.printStackTrace();
                        }
                }
                return null;
        }

       /**
        * 
       * @Description: TODO(这里用一句话描述这个方法的作用)
       * @author LiuYi
       *  @param buf
       *  @param filePath
       *  @param fileName  void
        */
        public  File byte2File(byte[] buf, String filePath, String fileName) {
                BufferedOutputStream bos = null;
                FileOutputStream fos = null;
                File file = null;
                try {
                        File dir = new File(filePath);
                        if (!dir.exists() && dir.isDirectory()) {
                                dir.mkdirs();
                        }
                        file = new File(filePath + File.separator + fileName);
                        fos = new FileOutputStream(file);
                        bos = new BufferedOutputStream(fos);
                        bos.write(buf);
                        return file;
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        if (bos != null) {
                                try {
                                        bos.close();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                }
                        }
                        if (fos != null) {
                                try {
                                        fos.close();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                }
                        }
                }
                return file;
        }
}

具体的实现
/**
 * 
* @ClassName: SimpleClientImpl
* @Description: TODO(对DFSjavaAPI的一个封装,加入连接池技术,提高效率)
* @author LiuYi
*
 */
public class SimpleClientImpl extends AbstractClientImpl {
        private ITrackerServerPool pool = null;
        private int waitTime = 3;
        
        public SimpleClientImpl(String clientConfigPath,int poolSize) throws FileNotFoundException, IOException, MyException, InterruptedException{
                this.pool = new LinkedQueueTrackerPool(clientConfigPath, poolSize);
        }
        public SimpleClientImpl(String clientConfigPath,int poolSize,int waitTime) throws FileNotFoundException, IOException, MyException, InterruptedException{
                this.pool = new LinkedQueueTrackerPool(clientConfigPath, poolSize);
                this.waitTime=waitTime;
        }
        public SimpleClientImpl(ITrackerServerPool pool){
                this.pool = pool;
        }
        
        @Override
        public String upload(File file) throws Exception {
                TrackerServer ts = null;
                try {
                        ts = pool.geTrackerServer(waitTime);
                        System.out.println(ts);
                        StorageClient1 client1 = new StorageClient1(ts, null);
                        return client1.upload_file1(file2Byte(file), getFileTypeName(file.getName()), null);
                } catch (Exception e) {
                        e.printStackTrace();
                }finally{
                        this.pool.close(ts);
                }
                return null;
        }

        @Override
        public String upload(File file, NameValuePair... metaList) throws Exception {
                TrackerServer ts = null;
                try {
                        ts = pool.geTrackerServer(waitTime);
                        StorageClient1 client1 = new StorageClient1(ts, null);
                        System.out.println(ts);
                        return client1.upload_file1(file2Byte(file), getFileTypeName(file.getName()), metaList);
                } catch (Exception e) {
                        e.printStackTrace();
                }finally{
                        this.pool.close(ts);
                }
                return null;
        }
        /**
         * 文件名为默认的
         */
        @Override
        public File download(String fileName,String localPath) throws Exception {
                TrackerServer ts = null;
                try {
                        ts = pool.geTrackerServer(waitTime);
                        StorageClient1 client1 = new StorageClient1(ts, null);
                      return  this.byte2File( client1.download_file1(fileName),localPath,UUID.randomUUID().toString()+"."+getFileTypeName(fileName));
                } catch (Exception e) {
                        e.printStackTrace();
                        throw e;
                }finally{
                        this.pool.close(ts);
                }
        }

        @Override
        public boolean remove(String fileName) throws Exception {
                boolean result = false;
                TrackerServer ts = null;
                try {
                        ts = this.pool.geTrackerServer(waitTime);
                        StorageClient1 client1 = new StorageClient1(ts, null);
                        result = client1.delete_file1(fileName) == 0 ? true : false;
                } catch (Exception e) {
                        e.printStackTrace();
                        throw e;
                }finally{
                        this.pool.close(ts);
                }
                return result;
        }
        @Override
        public NameValuePair[] getFileMate(String fileName) throws Exception {
                TrackerServer ts = null;
                try {
                        ts = pool.geTrackerServer(waitTime);
                        StorageClient1 client1 = new StorageClient1(ts, null);
                      return client1.get_metadata1(fileName);
                } catch (Exception e) {
                        e.printStackTrace();
                        throw e;
                }finally{
                        this.pool.close(ts);
                }
        }

}

测试代码
public class Test {
        public String local_filename = "D:\\seafood_project\\fast_DFS\\src\\client.conf";
        public static String conf_filename = "D:\\seafood_project\\fast_DFS\\src\\client.conf";
        public static String jpg = "D:/seafood_project/seafood-front/src/main/webapp/common/productImg/11.png";
        @org.junit.Test
        public void test() throws FileNotFoundException, IOException, MyException, InterruptedException{
              
        }
                
                public static void main(String[] args) throws FileNotFoundException, IOException, MyException, InterruptedException {
                        final IDFSClient client = new SimpleClientImpl(conf_filename, 2);
                        //使用定时任务模拟并发 
                        for(int i=0;i<10;i++){
                                new Timer()
                                .schedule(new TimerTask() {
                                        @Override
                                        public void run() {
                                                try {
                                                                //测试上传
//                                                        System.out.println(client.upload(new File(jpg)));
                                                                //测试下载
//                                                        System.out.println(client.download("g1/M00/00/07/wKjriVN6C9iAPX3HAACsXXNt0Y8813.png","D:\\image"));
                                                                
                                                } catch (Exception e) {
                                                        e.printStackTrace();
                                                }
                                                
                                        }
                                }, 1, 1000);
                        }
                }

}

在simplClient中添加一句System.out.println(ts);把TraeckServer打印出来,运行测试上传,控制台输出

org.csource.fastdfs.TrackerServer@933bcb
org.csource.fastdfs.TrackerServer@3ac93e
org.csource.fastdfs.TrackerServer@15718f2

g1/M00/00/08/wKjriVN6HFOAN7-VAACsXXNt0Y8407.png
org.csource.fastdfs.TrackerServer@933bcb
g1/M00/00/08/wKjriVN6HFOAYseLAACsXXNt0Y8802.png
org.csource.fastdfs.TrackerServer@3ac93e
g1/M00/00/08/wKjriVN6HFOAIj-dAACsXXNt0Y8445.png
org.csource.fastdfs.TrackerServer@15718f2
g1/M00/00/08/wKjriVN6HFOAf7l2AACsXXNt0Y8484.png
org.csource.fastdfs.TrackerServer@3ac93e
g1/M00/00/08/wKjriVN6HFOAN2ToAACsXXNt0Y8894.png
org.csource.fastdfs.TrackerServer@15718f2
g1/M00/00/08/wKjriVN6HFOAAvNuAACsXXNt0Y8064.png
org.csource.fastdfs.TrackerServer@933bcb
g1/M00/00/08/wKjriVN6HFOAMs7BAACsXXNt0Y8246.png
org.csource.fastdfs.TrackerServer@3ac93e
g1/M00/00/08/wKjriVN6HFOAJmNSAACsXXNt0Y8331.png
g1/M00/00/08/wKjriVN6HFOAH0VDAACsXXNt0Y8359.png
g1/M00/00/08/wKjriVN6HFOAEG62AACsXXNt0Y8530.png

附上jar
分享到:
评论

相关推荐

    fastdfs三个依赖包

    fastdfs三个依赖包(fastdfs-master.zip、fastdfs-nginx-module_v1.16.tar.gz、libfastcommon-master.zip)

    FastDFS 使用经验分享

    经验一:FastDFS文件下载恢复原始文件名 经验二:从文件的使用技巧

    jdk8的rpm包与FastDFS.zip

    提供jdk8的rpm包和FastDFS相关工具,帮助你搭建自己的图片服务器

    fastdfs 安装及使用

    fastdfs 安装及使用,里面包含了fastdfs安装需要的软件,以及java-api工程,和使用实例

    JDK8tar包与FastDFS.zip

    提供JDK8的tar包和FastDFS,亲测有用,CentOS6.8下搭建文件服务器

    FastDFS安装使用 我就是这么做的

    1.修改FastDFS/conf/tracker.conf文件,修改如下(以下修改都是在192.168.4.168服务器的修改) ①修改base_path,该目录必须存在,用于存储日志及storage server等信息 base_path=/home/yuqing/fastdfs -&gt; base_path...

    使用docker安装fastdfs

    使用docker安装fastdfs

    FastDFS与 spring 整合,使用 Nginx 来显示图片

    FastDFS 分布式文件系统的安装与使用(单节点) 1.服务器安装配置 fastdfs 2.通过 spring 整合 fastdfs 3.整合 fastdfs的Nginx模块可以通过 Nginx 来显示图片

    FastDFS和Linux下安装使用FastDFS

    FastDFS和Linux下安装使用FastDFS 安装Nginx 分布式文件系统

    FastDFS分布式文件系统

    •FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡 •FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储 •支持存储服务器在线扩容 •支持相同内容的文件只保存一份,...

    FastDFS图片服务器详细介绍文档

    FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储。支持存储服务器在线扩容。支持相同内容的文件只保存一份,节约...

    FastDFSClient C#源码

    vs2017 FastDFSClient C# 源码,经过测试可以正常使用

    fastdfs使用说明,包括各接口函数的说明

    fastdfs使用说明,包括各接口函数的说明。如: 基本概念 1、读取配置文件 2、获取tracker连接 3、获取tracker可用的storage 4、连接到获取的storage服务器 5、上传文件三种方式:字节数组、文件流、本地文件 6、续传...

    fastDFS 介绍文档,源代码,使用样例,JAR包

    分布式fastDFS 介绍文档,源代码,使用样例,JAR包

    【FastDFS专题】fastdfs使用实战(Java实例篇)

    NULL 博文链接:https://josh-persistence.iteye.com/blog/2067574

    FastDFS分布式文件系统.docx

    5.能够完成FastDFS环境搭建(使用docker镜像即可) 6.能够理解FastDFS&nginx访问流程 7.能够掌握FastDFS错误日志查看方法 8.能够理解FastDFS文件同步原理 9.能够掌握FastDFS文件合并存储机制 10.能够掌握FastDFS图片...

    FastDFS监控系统(fastdfs-zyc-fastdfs_client1.24)

    针对FastDFS文件系统的监控软件,软件基于B/S,实现对FastDFS整体服务状况与各类节点的监控,实时掌握FastDFS的服务状况。同时,通过对FastDFS并发情况与存储情况的监控,为FastDFS的部署实施提供参考。

    FastDFS客户端 FastDFS java客户端

    FastDFS服务器是一个轻量级的文件存储服务,结合Nginx使用,实现集群高可用,但是他的java客户端不是特别好找。本java客户端依赖包,能够完美整合实现FastDFS服务器的连接,上传、下载和删除。 内部附有简单API使用...

    FastDFS使用文档

    FastDFS使用文档FastDFS使用文档FastDFS使用文档FastDFS使用文档FastDFS使用文档

    linux下搭建FastDFS+Nginx服务器

    linux下搭建FastDFS+Nginx服务器需要的安装包和搭建教程

Global site tag (gtag.js) - Google Analytics