`
247687009
  • 浏览: 173982 次
  • 性别: 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常用于大型网站或企业内部的文件管理系统,配合Nginx实现高并发的文件访问。由于其轻量级的特性,FastDFS在资源消耗和性能方面都有优秀表现,因此在业界得到了广泛的应用。在进行安装和配置时...

    jdk8的rpm包与FastDFS.zip

    总结一下,本篇文章主要介绍了如何在Linux环境中使用JDK 8的RPM包安装Java开发环境,并利用FastDFS搭建图片服务器。通过这两个关键组件的结合,你可以构建一个高效、稳定的图片存储和访问系统。记住,每个步骤都需要...

    fastdfs压测文档1

    例如,系统负载的三个值(9.59, 4.75, 1.92)分别代表过去1分钟、5分钟、15分钟的平均负载。 【测试结果分析】 - 测试服务器: - 逐步增加并发数进行上传测试,发现250个并发时程序开始报错,因此,最大上传并发...

    FastDFS 使用经验分享

    ### FastDFS 使用经验分享 #### 经验一:FastDFS文件下载恢复原始文件名 **应用背景** 在使用FastDFS存储文件时,当文件被上传至服务器后,Storage服务端会返回一个文件索引(FID)。这个FID通常不是原始文件名,...

    fastdfs 安装及使用

    1. **引入依赖**:在Java项目中,需要添加FastDFS的Java客户端库依赖。 2. **配置连接参数**:配置FastDFS Tracker服务器的地址、端口等信息。 3. **编写代码**:使用FastDFS Java API进行文件上传、下载、删除等...

    FastDFSClient C#源码

    在C#环境下,FastDFSClient库提供了与FastDFS服务器交互的接口,使得开发者可以方便地在.NET环境中使用FastDFS服务。 FastDFSClient C#源码是FastDFS在.NET平台上的客户端实现,它是基于C#语言编写的,可以在Visual...

    JDK8tar包与FastDFS.zip

    3. **默认方法**:在接口中添加了默认方法,这使得接口可以拥有实现代码,同时避免破坏现有实现接口的类。 4. **Stream API**:提供了一种新的序列处理方式,可以对集合进行高效的操作,如过滤、映射和聚合等。 5....

    linux下搭建FastDFS+Nginx服务器

    FastDFS是一个轻量级的分布式文件系统,它为互联网应用提供了高可用、高并发的文件存储解决方案。它的主要特点是将文件存储和元数据分离,通过Tracker服务器管理文件的存储路径和文件组信息,而Storage服务器则负责...

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

    总之,FastDFS的安装和使用涉及多个步骤,包括安装依赖库、配置文件、启动服务,以及进行基本的功能测试。确保每个步骤正确执行,才能构建起一个稳定可靠的分布式文件系统。在实际应用中,还要考虑高可用性、负载...

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

    5. **文件ID生成**:FastDFS使用自定义的文件ID,由组名、文件名和文件扩展名三部分组成,方便存储和检索。 6. **源代码**:FastDFS的源代码可以帮助开发者深入理解其内部机制,包括文件操作、元数据管理、故障恢复...

    fastDFS使用指导_余庆1

    此外,FastDFS还提供了如my_fdfs_client_java这样的示例代码,以及对应的client库源码,方便开发者理解和使用。 总的来说,FastDFS是一个轻量级的分布式文件系统,适合于高并发的文件上传和下载场景,尤其适合电商...

    FastDFS使用和优化.docx

    FastDFS 使用和优化 FastDFS 是一个开源的分布式文件系统,旨在解决大规模文件存储和高性能文件访问问题。以下是 FastDFS 的相关知识点。 一、FastDFS 简介 FastDFS 的整体架构主要包括三个角色:Tracker、...

    fastDFS1.25jar包

    描述中提到的"在maven配置环境变量的情况下可以解决新手遇到fastDFS.jar1.25版本找不到的问题",意味着在使用Maven构建项目时,可能会遇到找不到FastDFS特定版本1.25的jar包的问题。Maven是一个项目管理和综合工具,...

    Fastdfs单节点安装包集合资源(Fastdfs+libfastcommon+fastdfs-nginx-module+nginx)

    Fastdfs由三部分组成:Fastdfs服务器、libfastcommon库和Fastdfs-nginx-module模块。 1. **Fastdfs服务器**: - **架构**:Fastdfs采用主从结构,分为Tracker Server和Storage Server。Tracker Server负责调度,...

    fastDFS+Nginx_fastdfs_fastdfs、nginx_fastdfs/nginx_

    FastDFS是一个开源的轻量级分布式文件系统,专门针对互联网应用设计,可以有效解决大数据量、高并发访问的问题。而Nginx作为一款高性能的HTTP和反向代理服务器,常被用作负载均衡器,与FastDFS结合,可以实现高效...

    fastdfs安装包(fastdfs-6.06,fastdfs-nginx-module-1.22,nginx-1.16.1)

    在本教程中,我们将详细探讨如何利用FastDFS-6.06、fastdfs-nginx-module-1.22和nginx-1.16.1这三个组件来搭建一套完整的FastDFS系统。 首先,我们来看FastDFS-6.06。这是FastDFS的主要部分,负责文件的存储和管理...

    fastdfs安装包以及步骤.zip

    1. 安装基础环境:确保服务器已安装GCC编译器、curl库、libevent库、pcre库等FastDFS依赖的软件包。 2. 获取源码:从官方网站或其他可信渠道下载FastDFS的最新源代码包。 三、FastDFS安装步骤 1. 解压源码包:将...

    fastdfs-java源码

    Java客户端库则扮演了与FastDFS服务端通信的关键角色,实现了文件操作的API。 二、FastDFS Java源码结构 1. `com.fastdfs.client`包:这是FastDFS Java客户端的主要代码,包括连接管理、请求发送、响应处理等功能...

    fastdfs+libfastcommon.zip

    1. 工具函数:包括字符串操作、内存管理、时间日期处理、网络通信等,这些函数在FastDFS的各个模块中被广泛使用,提高了代码的复用性和效率。 2. 线程池:libfastcommon中的线程池组件,可以有效地管理和调度线程,...

Global site tag (gtag.js) - Google Analytics