(转) 淘淘商城系列——使用FastDFS-Client客户端进行上传图片的测试

http://blog.csdn.net/yerenyuan_pku/article/details/72804018

不久之前,我们实现了商品的类目选择这个功能,但这只是万里长征的第一步,我们还有很多事情需要做,例如怎样实现图片上传这个功能。本文就来教大家如何实现图片上传。

图片上传分析

我们知道,对于传统项目来说,所有的模块都在一个项目中开发,包括所有静态资源文件比如图片等,都存储在这一个tomcat服务器上,如下图所示。 

如果访问量小的话,这样做问题倒不大,但是对于互联网项目来说,用户访问量很大,这样一个tomcat服务器是远远不能满足业务需求的。这就需要部署tomcat集群,有集群就需要用到负载均衡,我们一般都会使用nginx来作为负载均衡服务器,如下图所示。 

但是这种tomcat集群的缺点也很明显,假如我们把一张a.jpg的图片上传到了tomcat1的images目录下了,由于Nginx负责均衡处理请求,当用户去请求访问这张图片的时候,假设第一次,Nginx把请求交给tomcat1去处理,它到自己的images目录下去找这张图片,发现是可以找到的,于是我们便能看到这张图片,当我们第二次通过Nginx去请求访问该图片时,Nginx把请求交给tomcat2去处理了,这时tomcat2去它自己的images目录下去查找这张图片,发现并没有这张图片,因此页面上便看不到图片。作为用户来讲,一次访问能看到,再刷新就看不到,再刷新能看到,用户会很不理解,直观的感觉便是我们的系统太烂了。 
针对上面提到的问题,我们对集群做下改善,我们专门搞一个图片服务器,所有的tomcat都将用户上传的图片上传到图片服务器上,tomcat本身并不保存图片。我们采用http的方式来访问图片,这样我们就需要使用http服务器,能作为http服务器的有很多种选择。

  1. tomcat可以作为http服务器,但是由于tomcat服务器的强项并不在于处理静态资源( 它的强项是处理servlet和jsp等动态页面)因此我们不选择tomcat。
  2. 使用Apache作为http服务器,Apache是由C语言编写的一款服务器(注意,这里指的并不是Apache组织,而仅仅是一个服务器),这款服务器在以前用的人是很多的,不过现在用的人少了。
  3. 使用nginx,nginx因为其独特的优势,作为http服务器是目前最火的。我们就使用nginx来统一管理这些图片,这样用户要访问图片的时候,nginx直接把图片服务器上的图片给返回就可以了,从而解决了tomcat集群资源无法共享的问题。

但是这里需要考虑一个问题,那就是作为服务器,容量肯定是有限的,当这个服务器容量满了,怎么办呢?还有就是图片服务器挂了,怎么办呢?这些都是必须要解决的问题,为了解决这两个问题,我们使用FastDFS集群来解决。FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。它的优势是可以水平扩容,FastDFS存储资源的设备是按组来区分的,当存储空间不足时,便可以通过水平增加分组并相应添加设备来达到扩容的目的,而且是没有上限的。它还有个优势是高可用,也就是说FastDFS集群能够做到当提供服务的nginx发生故障时,自动切换到另一台nginx设备上,保障服务的稳定。 

图片服务器的安装

在此提醒大家搭建FastDFS集群是非常非常麻烦的,至少我现在就不会,所以,作为练习,我们只需搭建单机版FastDFS即可。一个最简单的FastDFS架构如下: 

这个架构就是我给大家提供的一个图片服务器的架构,当然了,这个最简单的架构在真正的生产环境中是远远不够的。由于图片服务器的安装过程非常复杂,就不需要大家掌握了,所以我会给大家提供一个安装好的图片服务器。大家可参考我的这篇文章淘淘商城系列——VMware添加已配置好的虚拟机进行学习。

使用FastDFS-Client客户端上传图片

下面我便用FastDFS-Client来进行上传和下载图片的测试,不过在这之前我们需要先做两件事。 
第一件事:由于中央仓库并没有fastdfs-client的包,因此需要我们自己整。这里我提供了一个有关fastdfs-client的maven工程,如下图所示。 

我们所要做的就是将fastdfs-client这个maven工程导入到Eclipse中,如下图所示,导入完成之后定要将这个maven工程打包到本地maven仓库中。 

至此,是不是万事大吉了呢?很显然并不是,我们直接通过表现层上传图片到图片服务器,大可不必再经过Service层,所以taotao-manager-web工程需要依赖fastdfs-client工程,因此需要在taotao-manager-web工程的pom.xml文件中添加对fastdfs-client的依赖,如下所示。

<dependency>
    <groupId>fastdfs_client</groupId>
    <artifactId>fastdfs_client</artifactId>
    <version>1.25</version>
</dependency>
  • 1

第二件事:在taotao-manager-web工程的src/main/resources目录下新建一个resource文件夹并在它下面创建fast_dfs.conf文件,fast_dfs.conf文件中输入tracker所在的设备的IP及端口,由于我的tracker是在ip为192.168.25.133的虚拟机上,因此我这里写的是”tracker_server=192.168.156.13:22122”,如下图所示。 

下面我们新建一个测试类来进行图片上传的测试,我们在src/test/java目录下新建一个com.taotao.fdfs包,并在该包下新建一个测试类TestFastDfs.java,如下图所示。 

为方便复制,现把测试类代码粘贴如下:

public class TestFastDfs {

    @Test
    public void testUpload() throws Exception {
        // 1.先创建一个配置文件——fast_dfs.conf,配置文件的内容就是指定TrackerServer的地址

        // 2.使用全局方法加载配置文件
        ClientGlobal.init("F:/Java/my-taotao/taotao-manager-web/src/main/resources/resource/fast_dfs.conf");
        // 3.创建一个TrackerClient对象
        TrackerClient trackerClient = new TrackerClient();
        // 4.通过TrackerClient对象获得TrackerServer对象
        TrackerServer trackerServer = trackerClient.getConnection();
        // 5.创建StorageServer的引用,null就可以了
        StorageServer storageServer = null;
        // 6.创建一个StorageClient对象,其需要两个参数,一个是TrackerServer,一个是StorageServer
        StorageClient storageClient = new StorageClient(trackerServer, storageServer);
        // 7.使用StorageClient对象上传文件(图片)
        // 参数1:文件名,参数名:扩展名,不能包含".",参数3:文件的元数据,保存文件的原始名、大小、尺寸等,如果没有可为null
        String[] strings = storageClient.upload_file("F:/fastdfs_test/meinv.jpg", "jpg", null);
        for (String string : strings) {
            System.out.println(string);
        }
    }

}

上面的代码有两点需要注意:

  1. taotao-manager-web工程还未添加对junit的依赖,因此需要在pom.xml文件中添加对junit的依赖,如下所示,这里之所以不用写版本是因为在taotao-parent工程中已经统一定义好版本了。

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
  2. 我们在复制粘贴win10系统的本地文件绝对路径(例如F:\fastdfs_test\meinv.jpg)时,Eclipse是识别不了的,运行会报如下错误。解决方法是手动输入,而且要注意把包括双引号在内的这个路径串删除("E:/images/2.jpg"),然后手动输入一遍。 

注意上面两点之后,我们再执行这个测试方法便可成功,如下图所示。回显信息的第一行是该图片被保存到哪个组了,由于我们现在只是用的单机FastDFS服务器,因此现在都是group1。第二行是存放的具体位置。 

既然图片上传上去了,现在我们试着用http的方式来访问下该图片,我们需要把group1和M00/00/00/wKgZhVksG-6AOre0AAFkkATUCZ8885.jpg拼接到一块来访问,这样我们便可以查看到我们刚才上传的照片了,如下图所示。 

经过上面的操作,说明我们搭建的图片服务器没问题。但有个问题是,图片上传的操作步骤繁琐,因此我们迫切需要对其进行封装,现在我把封装好的工具类——FastDFSClient.java的内容粘贴如下。

public class FastDFSClient {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;

    public FastDFSClient(String conf) throws Exception {
        if (conf.contains("classpath:")) {
            conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
        }
        ClientGlobal.init(conf);
        trackerClient = new TrackerClient();
        trackerServer = trackerClient.getConnection();
        storageServer = null;
        storageClient = new StorageClient1(trackerServer, storageServer);
    }

    /**
     * 上传文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileName 文件全路径
     * @param extName 文件扩展名,不包含(.)
     * @param metas 文件扩展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
        String result = storageClient.upload_file1(fileName, extName, metas);
        return result;
    }

    public String uploadFile(String fileName) throws Exception {
        return uploadFile(fileName, null, null);
    }

    public String uploadFile(String fileName, String extName) throws Exception {
        return uploadFile(fileName, extName, null);
    }

    /**
     * 上传文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileContent 文件的内容,字节数组
     * @param extName 文件扩展名
     * @param metas 文件扩展信息
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {

        String result = storageClient.upload_file1(fileContent, extName, metas);
        return result;
    }

    public String uploadFile(byte[] fileContent) throws Exception {
        return uploadFile(fileContent, null, null);
    }

    public String uploadFile(byte[] fileContent, String extName) throws Exception {
        return uploadFile(fileContent, extName, null);
    }
}

该工具类构造方法中的

conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());

这句话的意思是,如果用户传入的文件路径是相对路径(相对路径以src/main/resources目录为根目录),比如用户传入的文件路径是”classpath:applications.properties”,那么需要转为绝对路径,因此需要把”classpath:”给替换掉,改为F:/Java/my-taotao/taotao-manager-web/src/main/resources。而且封装类中使用的Storage客户端是StorageClient1而不是StorageClient。这个客户端的好处是能够帮我们自动把文件所在的组以及存放位置拼接到一块。 
我们在taotao-manager-web工程下新建一个com.taotao.utils工具包,然后把我们的封装类FastDFSClient.java放到下面。我们来测测这个工具类是否好使,我们再在TestFastDfs单元测试类中新建一个测试方法testFastDfsClient,如下图所示。 

testFastDfsClient单元测试方法代码如下:

@Test
public void testFastDfsClient() throws Exception {
    FastDFSClient fastDFSClient = new FastDFSClient("F:/Java/my-taotao/taotao-manager-web/src/main/resources/resource/fast_dfs.conf");
    String string = fastDFSClient.uploadFile("F:/fastdfs_test/a.jpg");
    // 注意,你再上传一遍,刚才你上传的那个图片就已经丢了,它已经存在服务器上了,你再也访问不到了
    System.out.println(string);
}

我们运行testFastDfsClient方法,返回的结果如下图所示。 

我们来访问这个图片,如下图所示。 

时间: 2024-10-07 10:03:28

(转) 淘淘商城系列——使用FastDFS-Client客户端进行上传图片的测试的相关文章

(转)淘淘商城系列——商品搜索功能测试

http://blog.csdn.net/yerenyuan_pku/article/details/72941506 到这里,我相信大家也是不容易,我自己也算是很不容易写到这里,希望自己能一直写下去.之前我们就差不多把商品搜索功能实现了,本文我们来一起测试下该搜索功能. 首先我们要保证zookeeper.redis.image.solr服务都开启.接着我们把taotao-common工程重新打包到本地maven仓库,由于taotao-search-interface工程新添加了一个接口,所以我

(转) 淘淘商城系列——Redis的安装

http://blog.csdn.net/yerenyuan_pku/article/details/72849612 通过上文的学习,我相信大家已经将首页的轮播图展示出来了,接下来我们将进入一个新的领域的学习,希望大家能振作精神,保持乐观向上的心态.本文我会教大家如何在Linux系统上安装Redis. 一般来说,如果我们是做一个互联网项目,通常都要在工程中添加缓存,之所以这样做,是因为在互联网项目中查询功能是非常频繁的,如果每次查询都调用数据库的话,会给数据库造成很大的压力,因此需要在用户和数

(转)淘淘商城系列——实现图片上传功能

http://blog.csdn.net/yerenyuan_pku/article/details/72808000 上文我们使用FastDFS-Client进行了简单的文件上传操作测试,淘淘商城项目中添加商品时上传图片的功能还没实现,如下图所示.本文将花大量笔墨来教大家如何实现图片上传这个功能. 我们来看下item-add.jsp页面,可以看到上传图片触发的方法是通过叫做picFileUpload的class来处理的,在<a>标签的下方是一个隐藏域,是用来接收图片上传到图片服务器的回显地址

淘淘商城系列——使用maven构建工程

开发工具和环境 这里,我统一规范一下淘淘商城的开发工具和环境,如下: Eclipse 4.5.2(Mars2),其自带maven插件,需要手工安装svn插件,但我提供的这个eclipse,svn插件已经搭好了 Maven-3.3.9(开发工具自带) Tomcat-7.0.75(Maven Tomcat Plugin) JDK 1.7 MySQL 5.7.17 Nginx 1.8.0 Redis 3.0.0 Win10 操作系统 SVN(版本管理工具) 工程搭建 使用maven的好处 项目构建.M

淘淘商城_0100_前言

好记性不如烂笔头,寄点东西吧!大神请略过此系列文章,,, 淘淘商城是传智播客发布的视频教程,里头涉及的技术点挺多的,之前看过一部分,感觉不错,但是过段时间又忘了, 智商一直是我的硬伤,还是寄点东西吧! 为了完整性,把一些文档也贴出来吧!虽然用处不大.. 1   课程计划 一共14天课程 1.第一天:电商行业的背景.淘淘商城的介绍.搭建项目工程.Svn的使用. 2.第二天:框架的整合.后台管理商品列表的实现.分页插件. 3.第三天:后台管理.商品添加.商品类目的选择.图片上传.富文本编辑器的使用.

淘淘商城01——工程介绍及搭建

一.淘淘商城介绍 淘淘网上商城是一个综合性的B2C(商家到用户)平台,类似京东商城.天猫商城.会员可以在商城浏览商品.下订单,以及参加各种活动. 管理员.运营可以在平台后台管理系统中管理商品.订单等. 客服可以在后台管理系统中处理用户的询问以及投诉. 1.1 系统功能图 1.2  系统功能介绍 后台管理系统:管理商品.订单.类目.商品规格属性.用户管理以及内容发布等功能. 前台系统:用户可以在前台系统中进行注册.登录.浏览商品.首页.下单等操作. 会员系统:用户可以在该系统中查询已下的订单.收藏

01淘淘商城项目:项目Maven工程搭建

最近在学习淘淘商城项目的搭建,使用maven做管理 后台管理系统工程搭建: 使用maven的好处: 1.依赖管理.jar包.工程之间依赖 2.项目构建:实现项目的一步构建 3.工程聚合.继承.依赖 maven工程分为三种类型: pom工程:用在父级工程,聚合工程中 war包工程:主要用作网站 jar包工程:就是当作jar使用的,可以用来打包 先给出总的项目结构,然后再解释是如何实现这些结构的 解释如下: 1.taotao-parent taotao-parent公司级别的maven工程.主要功能

淘宝商城model部分

淘宝商城 model /** * 功能:这是一个数据库连接,一个model类 */ package com.xf.model; import java.sql.*; public class ConnDB { private Connection ct=null; public Connection getConn() { try { Class.forName("com.mysql.jdbc.Driver"); ct=DriverManager.getConnection("

淘宝商城servlet部分

package com.xf.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.*; import com.xf.model.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; imp