分布式系统图片上传方案
Posted yangweiyong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式系统图片上传方案相关的知识,希望对你有一定的参考价值。
思路分析
直接将图片上传到一个指定的目录,访问、下载图片都访问这个目录。
由于项目最终是要部署到Linux环境,所以直接将图片上传到Linux服务器。
问题:那如何将图片上传到Linux呢?
答:使用vsftpd组件,实现文件传输。
vsftpd简介
问题1:vsftpd是什么?
答:ftp(File Transfer Protocol)文件传输协议。(实现不同操作系统之间文件的传输)
vsftpd是一个基于ftp协议的文件传输服务器软件。
问题2:vsftpd作用是什么?
答:传输文件。(跨平台、跨操作系统)
问题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 |
第五步:修改selinux(Linux安全内核系统)
(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做服务器,来加载图片。
问题1:Tengine是什么?
答:Tengine是web服务器。
问题2:web服务器常用种类?
答:apache、IIS、nginx
问题3:web服务器和web应用服务器的区别?
答:web应用服务器,是用来处理动态请求,常见的以tomcat、jetty等servlet容器为代表。可以用来部署应用。
web服务器,只能处理静态资源请求。
如果要处理动态请求,需要通过其动态代理功能实现。
问题3:为什么不用Tomcat呢?
答:(1)Tomcat是servlet容器,处理静态资源的速度远低于Tengine。
(2)Tomcat的并发连接数,远远低于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这个路径是要省掉的。
以上是关于分布式系统图片上传方案的主要内容,如果未能解决你的问题,请参考以下文章