分布式系统图片上传方案

Posted yangweiyong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式系统图片上传方案相关的知识,希望对你有一定的参考价值。

 思路分析

直接将图片上传到一个指定的目录,访问、下载图片都访问这个目录。

由于项目最终是要部署到Linux环境,所以直接将图片上传到Linux服务器。

技术图片

 

问题:那如何将图片上传到Linux呢?

答:使用vsftpd组件,实现文件传输。

 

 vsftpd简介

 

问题1vsftpd是什么?

 

答:ftpFile Transfer Protocol)文件传输协议。(实现不同操作系统之间文件的传输)

 

vsftpd是一个基于ftp协议的文件传输服务器软件。

 

 

 

问题2vsftpd作用是什么?

 

答:传输文件。(跨平台、跨操作系统)

 

 

 

问题3:如何使用?

 

答:服务端:在linux安装vsftpd软件,开启服务。

 

       客户端:通过FtpClient客户端建立和服务器的连接,向服务器发送请求。

 

实现步骤

 

第一部分:在Linux上部署vsftpd服务

 

思路 :(1)安装软件

 

    (2)测试服务是否可用

 

 

 

第一步:安装vsftpd软件

 

[[email protected] ~]# yum -y install vsftpd

第二步:关闭匿名访问

修改vsftpd配置文件   vim /etc/vsftpd/vsftpd.conf

技术图片

 

第三步:添加一个FTP用户

创建一个用户,专门用来访问vsftpd服务。

[[email protected] ~]# useradd ftpuser

[[email protected] ~]# passwd ftpuser

 

第四步:设置防火墙

vsftpd服务默认端口号为21,修改防火墙,开放此端口,重启防火墙。

[[email protected] ~]# vim /etc/sysconfig/iptables

[[email protected] ~]# service iptables restart

 

第五步:修改selinuxLinux安全内核系统)

1)先查看selinux,默认是禁用了ftp访问的。

[[email protected] ~]# getsebool -a | grep ftp  

allow_ftpd_anon_write --> off

allow_ftpd_full_access --> off

allow_ftpd_use_cifs --> off

allow_ftpd_use_nfs --> off

ftp_home_dir --> off

ftpd_connect_db --> off

ftpd_use_passive_mode --> off

httpd_enable_ftp_server --> off

tftp_anon_write --> off

 

2)修改selinux,开放ftp访问权限

[[email protected] ~]# setsebool -P allow_ftpd_full_access on

[[email protected] ~]# setsebool -P ftp_home_dir on

 

第六步:启动vsftpd服务

[[email protected] vsftpd]# service vsftpd start

vsftpd 启动 vsftpd:                                    [确定]

 

通过浏览器访问测试

访问地址:ftp://192.168.23.12:21发现无法访问

 

原因:被动模式下,数据传输服务被防火墙拦截了。

 

1)被动模式

第二次请求过程中,客户端跟服务端建立数据通道;

服务端被动将数据响应给客户端。

第二次请求数据传输,会随机生成一个服务端口。被防火墙禁用。

 

技术图片

 

2)主动模式

服务端主动向客户端发送数据,会被客户端的防火墙禁掉。

多数客户端不支持主动模式,不安全。

技术图片

第八步:配置被动模式

1)编辑/etc/vsftpd/vsftpd.conf文件

[[email protected] ~]# vim /etc/vsftpd/vsftpd.conf

 

2)添加防火墙范围设置(在文件尾部添加即可):

pasv_min_port=30000

pasv_max_port=30999

 

3)修改防火墙,开启30000:30999之间所有的端口。

4)重启防火墙。

5)重启vsftpd服务

技术图片

再次访问浏览器,发现可以正常连接了。

技术图片

java代码测试上传功能

Java代码中,是通过FtpClient客户端建立和服务端的连接的。在ego-base工程中测试。

1)在ego-base中添加ftp服务的依赖。

<dependency>

<groupId>commons-net</groupId>

<artifactId>commons-net</artifactId>

</dependency>

 

2)创建测试类

说明:使用ftpuser用户上传。指定上从目录/home/ftpuser/ego/images

注意:为了保证ftpuser有这个目录下的写权限,我们要用ftpuser用户创建这个目录。

su命令:切换用户

[[email protected] ~]#su ftpuser

[[email protected] ~]#mkdir -p /home/ftpuser/ego/images

 

测试类TestFtp

package cn.gzsxt.manager.test;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.SocketException;

 

import org.apache.commons.net.ftp.FTP;

import org.apache.commons.net.ftp.FTPClient;

 

public class TestFtp {

 

static String baseUrl = "/home/ftpuser/ego/images";

public static void main(String[] args) {

//1、建立和服务端的连接

FTPClient client = new FTPClient();

try {

client.connect("192.168.23.12", 21);

//2、身份认证

client.login("ftpuser", "ftpuser");

//3、指定源文件

File file = new File("F:\\\\图片\\\\5b7a8115N89613314.jpg");

InputStream local = new FileInputStream(file);

//4、指定文件上传的方式   二进制字节码

client.setFileType(FTP.BINARY_FILE_TYPE);

//5、指定上传目录  默认是/home/ftpuser,即ftpuser用户的家目录

// 切换到ftpuser用户来创建目录。     /home/ftpuser/ego/images/

client.changeWorkingDirectory("/home/ftpuser/ego/images");

//6、设置文件上传的模式,指定为被动模式

client.enterLocalPassiveMode();

 

boolean flag = client.storeFile("test.jpg", local);

if(flag){

System.out.println("上传成功");

}else{

System.out.println("上传失败");

}

} catch (SocketException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

封装FTPUtils工具类

package cn.gzsxt.base.utils;

 

import java.io.IOException;

import java.io.InputStream;

 

import org.apache.commons.net.ftp.FTP;

import org.apache.commons.net.ftp.FTPClient;

 

public class FtpUtils {

 

FTPClient client = null;

 

/**

 * 文件上传

 * @param hostName   ftp主机名

 * @param port       ftp主机端口

 * @param username   上传用户名

 * @param password   上传用户密码

 * @param basePath   上传基础路径

 * @param filePath   文件存放路径

 * @param remoteFileName  上传后文件名称

 * @param in         文件输入流

 * @return

 */

public static boolean upload(String hostName,int port,String username,String password,String basePath,

String filePath,String remoteFileName,InputStream in){

 

//1、创建客户端

FTPClient client = new FTPClient();

 

try {

 

//2、建立和服务端的链接

client.connect(hostName, port);

 

//3、登陆服务端

client.login(username, password);

 

//4、指定图片上传的方式为二进制,即字节流

client.setFileType(FTP.BINARY_FILE_TYPE);

 

//5、指定上传的访问模式为被动模式    说明:大部分的操作系统,默认的都是被动模式,并且禁用了主动了模式

client.enterLocalPassiveMode();

 

//6、指定上传的目录     默认目录 是当前ftpuser用户的家目录   

boolean flag = client.changeWorkingDirectory(basePath+filePath);

 

//如果切换目录失败,则创建指定的目录

if(!flag){

 

//创建目录失败,则可能是存在没有创建的父目录

if(!client.makeDirectory(basePath+filePath)){

String tempPath = basePath;

 

String[] split = filePath.split("/");

for (String string : split) {

if(null!=string && !"".equals(string)){

tempPath = tempPath+"/"+string;

 

//先判断第一层路径是否存在,如果不存在,则创建

if(!client.changeWorkingDirectory(tempPath)){

//如果创建第一层路径成功,则判断是否能切换到这一层路径

if(client.makeDirectory(tempPath)){

//切换失败,则返回false

if(!client.changeWorkingDirectory(tempPath)){

return false;

}

//如果创建第一层路径失败,则直接返回false

}else{

 

return false;

}

}

 

//如果有空路径,则直接跳过

}else{

continue;

}

}

}else{

//创建成功,则直接切换到指定的目录

if(!client.changeWorkingDirectory(basePath+filePath)){

return false;

}

}

 

}

 

//8、上传

boolean result = client.storeFile(remoteFileName, in);

 

return result;

 

 

} catch (Exception e) {

 

e.printStackTrace();

 

return false;

}finally {

//9,退出登录,并关闭连接

try {

if(client.logout()){

client.disconnect();

 

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

}

}

 

第二部分:搭建图片服务器访问图片

我们知道,图片等静态资源需要服务器加载,才能被访问到。

这里我们选择Tengine做服务器,来加载图片。

 

问题1Tengine是什么?

答:Tengineweb服务器。

 

问题2web服务器常用种类?

答:apacheIISnginx

 

问题3web服务器和web应用服务器的区别?

答:web应用服务器,是用来处理动态请求,常见的以tomcatjettyservlet容器为代表。可以用来部署应用。

web服务器,只能处理静态资源请求。

如果要处理动态请求,需要通过其动态代理功能实现。

 

问题3:为什么不用Tomcat呢?

答:(1Tomcatservlet容器,处理静态资源的速度远低于Tengine

2Tomcat的并发连接数,远远低于Tengine

 

所以,这里我们选择Tengine做图片服务器。

 

搭建步骤说明:

1)安装Tengine。(源码安装)

2)配置图片服务。

第一步:上传、解压

[[email protected] ~]# tar -zxvf tengine-2.1.0.tar.gz

 

第二步:预编译

预编译作用:检查编译过程中所需要的依赖、环境。

依次安装预编译过程中,所需要的环境。(根据个人虚拟机安装所缺环境)

[[email protected] ~]# cd tengine-2.1.0

[[email protected] tengine-2.1.0]# ./configure

第三步:编译

[[email protected] tengine-2.1.0]# make

 

第四步:安装

默认安装路径/usr/local/nginx/

[[email protected] tengine-2.1.0]# make install

 

第五步:启动Tengine服务器

[[email protected] tengine-2.1.0]# cd /usr/local/nginx/sbin/

[[email protected] sbin]# ./nginx

 

第六步访问测试

1)查看配置文件。默认服务端口是80

[[email protected] sbin]# cd ../conf

[[email protected] conf]# vim nginx.conf

 

2)修改防火墙,开发80端口。重启防火墙

[[email protected] conf]# vim /etc/sysconfig/iptables

[[email protected] conf]# service iptables restart

 

3)浏览器访问地址 http://192.168.23.12:80

第七步:配置图片服务

1)修改/conf/nginx.conf文件。指定图片根路径和服务端口

 

2)重启tengine服务器

 

[[email protected] sbin]# ./nginx -s reload

 

 

 

3)浏览器访问图片

 

注意:服务器加载的根路径是/home/ftpuser/ego

 

所以浏览器中访问图片的目录为/images/+图片名称.jpg

 

4)解决访问图片的权限问题

 

在第六步中,我们访问的页面是/html/index.html

 

所以:我们只需要将图片的权限修改为index.html一致即可。

 

 

 

查看/html/index.html的权限

 

技术图片

技术图片

 

 

 

修改ftpuser目录的权限为可读、可执行

 

[[email protected] nginx]# chmod 705 /home/ftpuser

 

5)重新访问图片,成功!!!

 

图片访问路径说明:

 

图片真实目录时  /home/ftpuser/ego/images

 

Tengine中,设置得图片资源的根目录为  /home/ftpuser/ego

 

 

 

意味着,我们每次请求图片的时候,是直接到/home/ftpuser/ego这个目录下,找图片的。因此图片的访问路径中,/home/ftpuser/ego这个路径是要省掉的。

 

 

 

 

以上是关于分布式系统图片上传方案的主要内容,如果未能解决你的问题,请参考以下文章

上传图片至fastdfs分布式文件系统并回显

FastDFS分布式文件系统(主要用作图片上传)

分布式部署网站---文件系统的存储--ftp上传图片到指定文件服务器

分布式文件系统之FastDFS

分布式系统的那些事儿 - 系统与系统之间的调用

视频分布式上传方案详解