搭建分布式文件上传系统总结(linux(ubuntu)搭建FastDFS、java后端实现文件上传、搭建过程中遇到的各种问题总结)
背景
搭建分布式文件上传系统。本身所用到的知识并不是很难,但是搭建过程比较复杂,需要修改的配置很多,所以很容易出错,尤其是对没有linux的来说,更是南上加南。我是重装2次虚拟机,搭建3次FastDFS才成功,所以总结下来
一、所用技术
- ubuntu的linux虚拟机
- linux搭建nginx
- linux搭建FastDFS
- Java搭建文件上传后端微服务
- 前台实现文件上传(vue-cli)
二、具体搭建过程
linux搭建FastDFS
(1)先安装libevent
步骤下载地址:http://libevent.org/
解压后进入目录(进入目录命令:cd 目录地址)
执行编译 make
执行安装 make install
验证 ls -al /usr/lib |grep libevent
如果make命令不能执行,按照提示要求,安装make插件就好
apt-get install ubuntu-make
yum install -y libevent
(2)安装 libfastcommon
步骤下载地址:https://github.com/happyfish100/libfastcommon.git
解压后进入目录
执行编译 make
执行安装 make install
注意上述安装完之后,安装完的路径在/usr/lib64,但是fastDFS访问的lib路径在 /usr/local/lib 中 所以此时需要建立软连接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
可能出现的问题如果报错缺少gcc编译器环境,那么使用yum -y install gcc-c++ 安装gcc
(3)安装FastDFS
下载地址: https://sourceforge.net/projects/fastdfs/files/FastDFS%20Server%20Source%20Code/FastDFS%20Server%20with%20PHP%20Extension%20Source%20Code%20V5.08/
解压后进入目录
执行编译 make
执行安装 make install
- 创建tracker的数据文件/日志目录(我存放在了/opt/fastdfs_tracker)
mkdir -p /opt/fastdfs_tracker
2. 进入 /etc/fdfs/ 执行
cd /etc/fdfs
cp tracker.conf.sample tracker.conf
3. 编辑 tracker.conf
disabled=false #启用配置文件 port=22122 #设置tracker的端口号 base_path=/opt/fastdfs_tracker#设置tracker的数据文件和日志目录(需预先创建) http.server_port=4418 #设置http端口号(根据需求设置),默认为8080
为启动脚本创建软引用,因为fdfs_trackerd等命令在/usr/local/bin中并没有,而是在/usr/bin路径下:
ln -s /usr/bin/fdfs_trackerd /usr/local/bin ln -s /usr/bin/stop.sh /usr/local/bin ln -s /usr/bin/restart.sh /usr/local/bin
4. 启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
- 设置开机启动
echo ‘/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart’ >> /etc/rc.d/rc.local
- 通过如下命令查看trackerd服务是否启动:
netstat -tupln | grep trackerd
7. 查看一下端口监听情况
netstat -unltp|grep fdfs
8. 如果有错可以在 /opt/fastdfs_tracker/logs 中查看
可能出现的问题
如果重启后发现未能自动启动则通过命令检查一下rc.local是否具备可执行权限
ll /etc/rc.d/rc.local
若是无可执行权限则进行授权
chmod +x /etc/rc.d/rc.local
配置Storage服务- 创建存放storage 数据/日志文件目录
mkdir -p /opt/fastdfs_storage
mkdir /opt/fastdfs_storage_data
2. 进入/etc/fdfs
cd /etc/fdfs/
cp storage.conf.sample storage.conf
3. 编辑 storage.conf
disabled=false #启用配置文件 group_name=group1 #组名,根据实际情况修改 port=23000 #设置storage的端口号 base_path=/opt/fastdfs_storage #设置storage的日志目录(需预先创建) store_path_count=1 #存储路径个数,需要和store_path个数匹配 store_path0=/opt/fastdfs_storage_data #实际文件存储路径 tracker_server=192.168.25.130:22122 #tracker服务器的IP地址和端口号 (如果是虚拟机,用虚拟机的地址) http.server_port=4419 #设置http端口号
配置完成后同样要为Storage服务器的启动脚本设置软引用:
ln -s /usr/bin/fdfs_storaged /usr/local/bin
4. 启动
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
- service fdfs_storaged start开机启动
echo ‘/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart’ >> /etc/rc.d/rc.local - 是否启动
netstat -tupln | grep storaged
7. 查看一下端口监听情况
netstat -unltp|grep fdfs
8. 如果有错可以在 /opt/fastdfs_storage/logs 中查看
可能出现的问题
storage的23000端口不能正常被监听到,导致失败
查看
tracker_server=192.168.25.130:22122的地址是否配置正确 配置client
cd /etc/fdfs/
cp client.conf.sample client.conf
vi client.conf
base_path=/opt/fastdfs_storage # 日志路径 tracker_server=172.16.1.40:22122 # 可以配置自己虚拟机的地址 http.tracker_server_port=4418 # tracker服务器的http端口号,必须和tracker的设置对应起来文件上传测试
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /opt/1.jpg
如果有类似的信息group1/M00/00/00/wKhXgl2ExjWACzHWAASe8_3bspM447.png证明上传成功
- 启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart - 查看进程
netstat -tupln | grep 进程名称 - 查看端口监听情况
netstat -unltp|grep 端口名称
(4)安装fastdfs-nginx-module
下载地址:https://sourceforge.net/projects/fastdfs/files/FastDFS%20Nginx%20Module%20Source%20Code/
解压进入目录
修改fastdfs-nginx-module-1.20/src/config文件(解决make时报错问题——fatal error: fdfs_define.h: 没有那个文件或目录
#include “fdfs_define.h”)
配置mod_fastdfs.conf
connect_timeout=10 # 客户端访问文件连接超时时长(单位:秒) tracker_server=192.168.56.101:22122 # tracker服务IP和端口(自己设置) url_have_group_name=true # 访问链接前缀加上组名 store_path0=/opt/fastdfs_storage # 文件存储路径
复制FastDFS/conf/的部分配置文件到/etc/fdfs目录
cp http.conf mime.types /etc/fdfs/
(5)安装Nginx
注:如果之前安装过nginx在之后的fastdfs-nginx-module编译肯能会报错,博主就是遇到这样的问题,然后重新写在nginx然后重装
附:彻底卸载nginx
rm -rf /etc/nginx
rm -rf /usr/sbin/nginx
apt-get remove nginx* (apt-get remove --purge nginx)
sudo apt-get remove nginx #Removes all but config files
sudo apt-get purge nginx #Removes everything
有提示没有可卸载的,不用理会
安装一、基于APT源安装sudo apt-get install nginx
/usr/sbin/nginx:主程序
/etc/nginx:存放配置文件
/usr/share/nginx:存放静态文件
/var/log/nginx:存放日志
其实从上面的根目录文件夹可以知道,Linux系统的配置文件一般放在/etc,日志一般放在/var/log,运行的程序一般放在/usr/sbin或者/usr/bin。
当然,如果要更清楚Nginx的配置项放在什么地方,可以打开/etc/nginx/nginx.conf
我猜测,Nginx如果指定默认加载/etc/nginx/nginx.conf的配置文件。如果要查看加载的是哪个配置文件,可以用这个命令sudo nginx -t或者ps -ef | grep nginx
然后通过这种方式安装的,会自动创建服务,会自动在/etc/init.d/nginx新建服务脚本,然后就可以使用sudo service nginx {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}的命令启动
安装二、通过源码包编译安装下载地址:http://nginx.org/en/download.html
关闭防火墙
ufw enable
ufw disable
安装依赖:
安装gcc g++的依赖库
sudo apt-get install build-essential
sudo apt-get install libtool
安装pcre依赖库(http://www.pcre.org/)
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev
安装zlib依赖库(http://www.zlib.net)
sudo apt-get install zlib1g-dev
安装SSL依赖库(16.04默认已经安装了)
sudo apt-get install openssl
之后正式开始安装:
进入解压目录
配置
sudo ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/home/leyou/fdfs/fastdfs-nginx-module/src
#编译:
make
#安装:
sudo make install
配置nginx整合fastdfs-module模块,修改nginx配置文件,在/opt/nginx/config/nginx.conf文件中:
sudo vim /opt/nginx/conf/nginx.conf
server { listen 80; server_name image.taotao.com; # 监听域名中带有group的,交给FastDFS模块处理 location ~/group([0-9])/ { ngx_fastdfs_module; } location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
nginx # 启动
nginx -s stop # 停止
nginx -s reload # 重新加载配置
#查看进程:
ps -ef | grep nginx
配置开机启动服务
在/etc/init.d/下创建nginx文件,sudo vim /etc/init.d/nginx,内容如下:
#!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: NGINX is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/bin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` if [ -n "$user" ]; then if [ -z "`grep $user /etc/passwd`" ]; then useradd -M -s /bin/nologin $user fi options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done fi } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
#设置服务脚本有执行权限
sudo chmod +x /etc/init.d/nginx #注册服务
cd /etc/init.d/
sudo update-rc.d nginx defaults
此时在虚拟机所有的配置已经完成
三、java后端搭建图片上传服务
这里只展示上传文件的类
@Service public class UploadService { private static final Logger logger = LoggerFactory.getLogger(UploadController.class); // 支持的文件类型 private static final List<String> suffixes = Arrays.asList("image/png", "image/jpeg"); @Autowired FastFileStorageClient storageClient; public String upload(MultipartFile file) { try { // 1、图片信息校验 // 1)校验文件类型 String type = file.getContentType(); if (!suffixes.contains(type)) { logger.info("上传失败,文件类型不匹配:{}", type); return null; } // 2)校验图片内容 BufferedImage image = ImageIO.read(file.getInputStream()); if (image == null) { logger.info("上传失败,文件内容不符合要求"); return null; } // 2、将图片上传到FastDFS // 2.1、获取文件后缀名 String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), "."); // 2.2、上传 StorePath storePath = this.storageClient.uploadFile( file.getInputStream(), file.getSize(), extension, null); // 2.3、返回完整路径 return "http://image.xxx.com/" + storePath.getFullPath(); } catch (Exception e) { return null; } } }
如果想要更加方便去返回,如果使用了springboot的话,可以在配置文件中配置suffixes的文件支持类型和return的域名前缀
这个操作省略
(6)测试
在浏览器中输入http://image.xxx.com/group1/M00/00/00/wKhXgl2ExjWACzHWAASe8_3bspM447.png
去访问图片
nginx、FastDFS都没有问题可以访问成功
可能遇到的问题
- win10访问linux的nginx,浏览器报502 Bad Gateway 的错误
在nginx的配置文件中将localhost改为虚拟机的地址
前台实现向后台请求,然后上传图片相对简单,暂时省略
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- Ubuntu(乌班图)系统下搭建Gerrit服务器及使用过程中会遇到的一些问题
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- Linux环境之下搭建Fastdfs文件上传服务系统
- 嵌入式开发(一)虚拟机上的ubuntu系统上搭建nfs过程及遇到问题
- ubifs文件系统的制作过程&&遇到的问题及解决方案总结---之一“uboot中添加对UBIFS文件系统的支持”
- ubuntu搭建java开发环境遇到的问题总结
- u盘启动盘 联想服务器TS250 Win Server 2016 下 安装Linux(ubuntu-18.04.1-desktop-amd64)双系统 各种问题总结(2018-11-13)
- ubifs文件系统的制作过程&&遇到的问题及解决方案总结---之三“UBIFS镜像的制作&&烧写”
- ubifs文件系统的制作过程&&遇到的问题及解决方案总结---之二“Linux内核中添加对UBIFS文件系统的支持”
- java上传下载文件部署到linux系统下的一些问题
- linux-ubuntu下用ftp遇到的各种问题总结和解决
- Linux系统下Java应用程序打包成.jar文件遇到问题与解决问题
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- linux环境搭建ftp服务以及遇到的问题总结:上传不成功,ftp:connection refused等等
- gitlab使用过程中遇到大文件上传或下载失败的问题,总结一下
- MyEclipse6.5整合flex实现与java简单通信过程中遇到的问题和注意事项
- 求救: 关于java与linux系统文件权限问题
- Hadoop HDFS文件系统通过java FileSystem 实现上传下载等