架构设计大数据分布式

taotao-图片服务器

2018-07-27  本文已影响37人  小小蒜头

1. 图片服务器分析

1.1 传统方式

适用于并发量小、用户少

1.2 互联网项目

用服务器做集群,添加一个Tomcat,部署另外一份相同代码(先不管负载均衡问题),当上传图片时,只会有一个Tomcat接收,恰巧Tomcat1接收了(a.jpg),现在访问图片地址,如果是Tomcat2访问,Tomcat2的images下没有a.jpg。

适用于并发量高、用户多

解决方案,新建一个图片服务器,不管是哪个服务器接收图片,都把图片上传到图片服务器。图片服务器上需要安装一个http服务器,可以使用tomcat、apache、nginx。

图片是静态资源,选择用Nginx,性能好。Nginx(介绍)是一个使用c语言开发的高性能的http服务器及反向代理服务器。
Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发,官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。

解决方案

2. 图片服务器的搭建

搭建图片服务器使用FastDFS。FastDFS是一款C语言开发的分布式文件系统,很容易搭建一套高性能的文件服务集群来提供文件上传、下载等服务。FastDFS环境搭建文件上传和下载

3. 图片服务器的分析

官方提供一个jar包
使用方法:
1、把FastDFS提供的jar包添加到工程中
2、初始化全局配置。加载一个配置文件。
3、创建一个TrackerClient对象。
4、创建一个TrackerServer对象。
5、声明一个StorageServer对象,null。
6、获得StorageClient对象。
7、直接调用StorageClient对象方法上传文件即可。

需求:上传图片

3.1 功能分析

功能分析1 功能分析2

3.2 请求的参数

请求的参数

3.3 请求的URL

/pic/upload ------ 参考文档

3.4 需要的jar包

<!--图片服务器-->
<dependency>
      <groupId>cn.bestwu</groupId>
      <artifactId>fastdfs-client-java</artifactId>
      <version>1.27</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

3.5 在springmvc.xml中配置多媒体解析器

<!--配置多媒体解析器-->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>

3.6 响应的内容

返回格式(JSON)

//成功时
{
"error" : 0,
"url" : "http://www.example.com/path/to/file.ext"
}
//失败时
{
"error" : 1,
"message" : "错误信息"
}

需要创建一个pojo描述返回值。
pojo中有三个属性:error、url、message,可以放到taotao-common工程中

package com.taotao.common.pojo;

/**
 * Created by yvettee on 18-8-17.
 */
public class PictureResult {

    private int error;
    private String url;
    private String message;

    public int getError() {
        return error;
    }

    public void setError(int error) {
        this.error = error;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

3.8 service层

接收图片数据,把图片上传到图片服务器,返回PictureResult 。需要使用FastDFSClient工具类。
参数:MultiPartFile pictureFile
返回值:PictureResult

要用到图片服务器工具类FastDFSClient

package com.taotao.utils;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

/**
 * Created by yvettee on 18-8-17.
 */
/*
* 图片服务器工具类
* */
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);
    }
}

配置文件client.conf

tracker_server=192.168.0.118:22122

PictureServiceImpl

package com.taotao.service.impl;

import com.taotao.common.pojo.PictureResult;
import com.taotao.service.PictureService;
import com.taotao.utils.FastDFSClient;
import org.springframework.web.multipart.MultipartFile;

/**
 * 图片上传
 * Created by yvettee on 18-8-17.
 */
@Service
public class PictureServiceImpl implements PictureService {

    @Override
    public PictureResult uploadPic(MultipartFile picFile) {
        PictureResult result = new PictureResult();
        //判断图片是否为空
        if (picFile.isEmpty()) {
            result.setError(1);
            result.setMessage("图片为空");
            return result;
        }

        //上传图片到服务器
        try {
            //取出图片的扩展名,不要.
            String originalFileName = picFile.getOriginalFilename();
            String extName = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);

            FastDFSClient client = new FastDFSClient("classpath:properties/client.conf");
            String url = client.uploadFile(picFile.getBytes(), extName);

            //再把URL相应给客户端
            result.setError(0);
            result.setUrl(url);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(1);
            result.setMessage("图片上传失败");
        }


        return result;
    }
}

3.9 Controller

接收上传的图片信息,调用Service把图片上传到图片服务器。返回json数据。需要使用@ResponseBody

PictureController

package com.taotao.controller;

import com.taotao.common.pojo.PictureResult;
import com.taotao.service.PictureService;
import com.taotao.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

/**
 * 图片上传Controller
 * Created by yvettee on 18-8-17.
 */
@Controller
public class PictureController {
    @Autowired
    private PictureService pictureService;

    @RequestMapping("/pic/upload")
    @ResponseBody
    public String uploadFile(MultipartFile uploadFile) {
        PictureResult result = pictureService.uploadPic(uploadFile);

        //需要把Java对象手工转换成JSON
        String str = JsonUtils.objectToJson(result);

        return str;
    }
}

上篇:taotao-添加商品-类目选择
下篇:taotao-商品添加的实现
源代码:https://github.com/yvettee36/taotao

上一篇下一篇

猜你喜欢

热点阅读