分布式系统图片上传方案

思路分析

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

由于项目最终是要部署到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这个路径是要省掉的。

原文地址:https://www.cnblogs.com/yangweiyong/p/10777096.html

时间: 2024-08-30 07:04:09

分布式系统图片上传方案的相关文章

JS图片上传预览插件制作(兼容到IE6)

其实,图片预览功能非常地常见.很意外,之前遇到上传图片的时候都不需要预览,也一直没有去实现过.现在手上的项目又需要有图片预览功能,所以就动手做了一个小插件.在此分享一下思路. 一.实现图片预览的一些方法. 了解了一下,其实方法都是大同小异的.大概有以下几种方式: ①订阅input[type=file]元素的onchange事件. 一旦选择的路径被改变就把图片上传至服务器,然后就返回图片在服务器端的地址,并且赋值到img元素上. 缺点:工作量大,有些上传并不是用户最终需要上传的图片,但是这种方式会

图片上传那些事

简述: 一个项目上,之前已经做好了用flash上传图片的功能,但是现在因为客户端的限制,要求不用flash,可以使用html5,于是改造开始了. 先给出之前flash的界面: 需求:  上面的图片里面可以看出三个需求: 1. 文件选择按钮外观需要美化 2. 可以预览图片 3. 上传图片(上传后的图片存在形式需要与之前flash上传的一样,也就是说需要byte[]的形式) 用户上传图片之后,需要把新的图片显示到其他位置,所以还有一个需求: 4. 上传成功后调用回调函数 思考: 1. 文件选择按钮外

kindeditor扩展粘贴图片功能&amp;修改图片上传路径并通过webapi上传图片到图片服务器

前言 kindeditor是一个非常好用的富文本编辑器,它的简单使用我就不再介绍了. 而kindeditor却对图片的处理不够理想. 本篇博文需要解决的问题有两个: kindeditor扩展粘贴图片功能 kindeditor修改图片上传路径并通过webapi上传图片到图片服务器(支持分布式图片) 结果演示 1.扩展粘贴图片功能演示 2.修改图片上传路径演示: 我们的网站演示地址是:http://localhost:9393/ 我们的图片服务器地址是:http://localhost:9394/

图片上传安全性问题,根据ContentType (MIME) 判断其实不准确、不安全

图片上传常用的类型判断方法有这么几种---截取扩展名.获取文件ContentType (MIME) .读取byte来判断(这个什么叫法来着?).前两种都有安全问题.容易被上传不安全的文件,如木马什么的.第1种截取文件扩展名来判断的方法很明显不安 全,第2种ContentType MIME可以伪造,所以用ContentType来判断其实也不安全.建议采用第3种. C#演示: 1.截取扩展名来做判断,不可取. if (Request.Files.Count > 0) { //这里只测试上传第一张图片

js实现图片上传预览原理

现在网上有很多成熟的图片上传的插件,由于之前对于图片上传未接触过,不了解其实现原理.网上查阅了相关资料,了解到其是基于FileReader Api. 众所周知,大家平时做兼容性都是为了兼容低版本浏览器,图片上传则恰恰相反.基于浏览器的安全策略,file标签在现代浏览器中已经获取不到真实路径.恰恰相反,低版本ie却能获取到真实物理路径.所以此功能是基于现代浏览器的解决方案. FileReader就是html5为我们提供的读取文件的api.它的作用就是把文本流按指定格式读取到缓存,以供js调用. F

JQuery插件:图片上传本地预览插件,改进案例一则。

/* *名称:图片上传本地预览插件 v1.1 *作者:周祥 *时间:2013年11月26日 *介绍:基于JQUERY扩展,图片上传预览插件 目前兼容浏览器(IE 谷歌 火狐) 不支持safari *插件网站:http://keleyi.com/keleyi/phtml/image/16.htm *参数说明: Img:图片ID;Width:预览宽度;Height:预览高度;ImgType:支持文件类型;Callback:选择文件显示图片后回调方法; *使用方法: <div> <img id

base64图片上传

图片上传 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet

多实例集群部署下的图片上传

场景 存在多个无状态的Web应用服务,支持多实例集群化部署(使用nginx作为反向代理) 在Web应用中存在图片文件上传功能 不能将图片文件直接保存到数据库中,数据库中只保存文件访问链接 问题 因为Web应用服务是多实例集群化部署的,因此上传图片之后不能简单保存到本地,否则其他实例将无法访问上传之后的图片. 图片上传之后不要通过Web应用来访问(像Tomcat这样的Servlet容器不擅长处理静态文件) 解决方案 图片如何存储 针对第一个问题,图片通过Web应用上传之后不能保存在本地,应该使用专

.Net Core 图片上传FormData和Base64

缓冲和流式传输是上传文件的两种常用方案,这里主要演示流式传输. 1.Net Core MVC Form提交方式: 前端页面 form表单提交: 1 <form id="uploadForm"> 2 图片上传: <input type="file" name="file" multiple value="选择" onchange="doUpload()" id="ajaxfile&