部署SpringBoot项目(jar+nginx+fastdfs)
1、依赖/使用的程序软件
mysql
:数据存储服务器nginx
:反向代理,用于访问图片fastDFS
:分布式上传下载图片docker
:提供容器服务
2、操作
(1)MySQL
- 使用
docker
安装MySQL
,服务器无需安装MySQL
-
搜索
mysql
容器docker search mysql
-
拉取
mysql
docker pull mysql
-
查看
mysql
镜像docker images
mysql
镜像已经下载好
- 启动
mysql
服务
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=xxxx -d mysql:latest
--name
:指定一个容器的名字,后续可以用这个名字进行一些操作-p
:将容器的3306端口映射到docker
宿主机的3306端口-e
:设置参数的值,这里MYSQL_ROOT_PASSWORD
是设置MySQL
的root
用户的密码-d
:指定启动哪个镜像
# 查看mysql是否启动成功
docker ps
已经启动成功
-
连接
mysql
docker exec -it mysql bash
使用上述命令进入容器中,连接mysql
mysql -u root -p xxx
mysql连接成功,说明mysql已经配置好了。想要操作mysql就需要进入到docker
已经开启的mysql
容器中进行操作
- 关闭/重启
mysql
docker stop mysql # 关闭mysql
docker start mysql # 开启mysql
docker restart mysql # 重启mysql
docker ps # 查看正在运行的容器
docker ps -a # 包括未运行的容器
(2)fastDFS和nginx
nginx和fastDFS需要一起使用
-
所有安装包
-
libfastcommonV1.0.7.tar.gz:fastDFS依赖程序
-
FastDFS_v5.05.tar.gz:fastDFS安装包
-
fastdfs-nginx-module_v1.16.tar.gz:nginx和fastdfs的桥梁插件模块
-
nginx-1.8.1.tar.gz:nginx安装包
-
-
安装过程
-
安装编译环境
apt install gcc g++
-
安装
libfastcommon
cd /usr/local/package # /usr/local/package存放安装包 tar -xzf libfastcommonV1.0.7.tar.gz cd libfastcommon-1.0.7 ./make.sh ./make.sh install cp /usr/lib64/libfastcommon.so /usr/lib
-
创建
fastDFS
数据存储的目录mkdir -p /usr/local/apps/fastDFS/tracker # fastDFS跟踪器数据目录 mkdir -p /usr/local/apps/fastDFS/storage # fastDFS存储节点数据目录 mkdir -p /usr/local/apps/fastDFS/client
-
安装
fastDFS
cd /usr/local/package tar -zxf FastDFS_v5.05.tar.gz cd FastDFS ./make.sh ./make.sh install cd conf cp * /etc/fdfs
-
配置
fastDFS
的tracker
节点vim /etc/fdfs/tracker.conf base_path=/usr/local/apps/fastDFS/tracker/ # 设置此变量,就是刚才创建的目录
-
启动
tracker
节点/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
此时可以看到
tracker
跟踪器节点已经启动: -
配置
storage
节点vim /etc/fdfs/storage.conf base_path=/usr/local/apps/fastDFS/storage/ store_path0=/usr/local/apps/fastDFS/storage/ tracker_server=172.16.49.5:22122 # 服务器需要改为公网ip
-
启动
storage
节点/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
此时可以看到
storage
存储节点已经启动
-
测试
fastDFS
-
从编译完的
FastDFS
目录(/usr/local/package/FastDFS/
)复制libfastclient.so
到/usr/lib
目录cd /usr/local/package/FastDFS cp libfastclient.so /usr/lib
-
修改测试的配置文件
vim /etc/fdfs/client.conf base_path=/usr/local/apps/fastDFS/client tracker_server=172.16.49.5:22122 # 和上诉设置得一样
-
开始测试上传
echo hello > test.txt # 新建一个测试文件 /usr/bin/fdfs_test /etc/fdfs/client.conf upload test.txt #上传文件
可以看到文件已经上传成功了:
进入到M00/00/00/rBAxBV-hInOARQxgAAAABncc3SA130_big.txt
目录中去看一下文件是否存在,数据目录就是前面设置的/usr/local/apps/fastDFS/storage
文件存在。
-
-
安装
nginx
需要的依赖包sudo apt-get install openssl libssl-dev # openssl sudo apt-get install libpcre3 libpcre3-dev # pcre sudo apt-get install zlib1g-dev # zlib
-
解压
fastdfs-nginx-module_v1.16.tar.gz
cd /usr/local/package tar -zxf fastdfs-nginx-module_v1.16.tar.gz
-
修改
fastdfs-nginx-module
的配置文件cd fastdfs-nginx-module/src/ vim config
修改图中的两个变量。
-
复制
fastdfs-nginx-module/src/mod_fastdfs.conf
到/etc/fdfs
目录下,并编辑vim /etc/fdfs/mod_fastdfs.conf tracker_server=172.16.49.5:22122 # 和上述ip一样 url_have_group_name=true storage_server_port=23000 group_name=group1 store_path0=/usr/local/apps/fastDFS/storage
-
安装
nginx
cd /usr/local/package tar -xvf nginx-1.8.1.tar.gz cd nginx-1.8.1 ./configure --add-module=/usr/local/package/fastdfs-nginx-module/src/ make make install
在make的时候可能出现的问题
-
把警告当错误处理
src/core/ngx_murmurhash.c: In function ‘ngx_murmur_hash2’: src/core/ngx_murmurhash.c:37:11: error: this statement may fall through [-Werror=implicit-fallthrough=] h ^= data[2] << 16; ~~^~~~~~~~~~~~~~~~ src/core/ngx_murmurhash.c:38:5: note: here case 2: ^~~~ src/core/ngx_murmurhash.c:39:11: error: this statement may fall through [-Werror=implicit-fallthrough=] h ^= data[1] << 8; ~~^~~~~~~~~~~~~~~ src/core/ngx_murmurhash.c:40:5: note: here case 1: ^~~~
将
/usr/local/apps/nginx-1.8.1/objs/Makefile
中的CFLAGS
中的-Werror
去掉 -
编译错误
src/os/unix/ngx_user.c: 在函数‘ngx_libc_crypt’中: src/os/unix/ngx_user.c:36:7: 错误:‘struct crypt_data’没有名为‘current_salt’的成员 cd.current_salt[0] = ~salt[0];
将
/usr/local/apps/nginx-1.8.1/os/unix/ngx_user.c
中报错这句话注释掉:
-
-
配置
nginx
访问fastdfs
的文件资源cd /usr/local/nginx/conf vim nginx.conf
server { listen 80; server_name localhost; location ~ /group[0-9]/ { ngx_fastdfs_module; } }
-
启动
nginx
/usr/local/nginx/sbin/nginx
-
测试
nginx
和fastdfs
整合的效果找到之前上传的文件其返回的图片路径:
浏览器输入:
http://xxx.xx.xx.x/group1/M00/00/00/rBAxBV-hInOARQxgAAAABncc3SA130_big.txt
效果如下:
至此
nginx
和fastdfs
的安装和整合就成功了
-
(3)SpringBoot和nginx的整合
-
运行SpringBoot项目
java -jar background-system-0.0.1-SNAPSHOT.jar --server.port=8899
指定一下项目监听的端口为8899,因为
nginx
监听的端口是80,所以这里需要设置为其他的端口
- 如果部署项目是在
XShell
上部署的,则在退出XShell
的时候项目会自动关闭。可以使用下面的命令在退出XShell
的时候也运行。
nohup java -jar background-system-0.0.1-SNAPSHOT.jar --server.port=8899 >log.txt &
&
:表示后台运行。可使用jobs
查看后台运行程序,fg [id]
调到前台运行
>log.txt
:表示将输出信息重定向到log.txt
文件中
nohup
:意思是不挂断运行命令,当账户退出或终端关闭时,程序仍然运行,当用nohup
命令执行作业时,缺省情况下该作业的所有输出被重定向nohup.out
的文件中,除非另外指定了输出文件。
2. 配置nginx
vim /etc/local/nginx/conf/nginx.conf
配置nginx
的转发,将nginx
80端口收到的请求转发到服务器的其他端口的程序上去。
- 此时直接使用80端口访问项目也能访问到以8899端口运行的SpringBoot项目了
(4)SpringBoot和fastDFS整合
-
添加
fastDFS
依赖<!-- 连接fastdfs文件系统 --> <dependency> <groupId>com.luhuiguo</groupId> <artifactId>fastdfs-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency>
-
添加配置
fdfs: # 连接Tracker服务器超时时间 connect-timeout: 10000 # storage服务器响应的超时时间 so-timeout: 3000 # trakcer服务器的数量 tracker-list: - 120.78.223.0:22122 pool: # 连接池最大数量 max-total: 200 # 每个tracker地址的最大连接数 max-total-per-key: 50 # 连接耗尽时等待获取连接的最大毫秒数 max-wait-millis: 5000
-
编写
Controller
/** * 用于上传资源 */ @Controller @RequestMapping("/upload") public class UploadController { @Autowired private FastFileStorageClient storageClient; @ResponseBody @RequestMapping("uploadImages") public String uploadsImages(HttpServletRequest request, @RequestParam(value = "editormd-image-file", required = false) MultipartFile myFile, Map<String,Object> map){ if(myFile.isEmpty()){ map.put("success",0); map.put("message","上传失败"); map.put("url","null"); return JSON.toJSONString(map); } // myFile.getOriginalFilename():取到文件的名字 // FilenameUtils.getExtension(""):取到一个文件的后缀名 String extension = FilenameUtils.getExtension(myFile.getOriginalFilename()); // group1:指storage服务器的组名 // myFile.getInputStream():指这个文件中的输入流 // myFile.getSize():文件的大小 // 这一行是通过storageClient将文件传到storage容器 StorePath uploadFile = null; try { uploadFile = storageClient.uploadFile("group1", myFile.getInputStream(), myFile.getSize(), extension); } catch (IOException e) { e.printStackTrace(); } // 返回它在storage容器的的路径 String fullUrl = "http://xx.xx.xx.xx/" + uploadFile.getFullPath(); System.out.println(fullUrl); map.put("success",1); map.put("message","上传成功"); map.put("url",fullUrl); return JSON.toJSONString(map); } }
3、其他
(1)添加nginx.sh
和fastdfs.sh
文件
-
作用
由于都是源码安装,
fastdfs
和nginx
的启动不太方便,所以编写两个脚本文件方便这两个程序的启动和关闭,并且方便调试的时候重启。这两个文件全部放在**/usr/bin
**目录下,方便直接访问 -
使用
fastdfs.sh start/stop/restart # 开启、停止、重启fastdfs nginx.sh start/stop/restart # 开启、停止、重启nginx
-
内容
## fastdfs.sh #!/bin/bash cmd=$1 if [ ! $cmd ] then echo "Please use: fastdfs < start | stop | restart >" exit fi function stop_fastdfs(){ local tracker_pid=`ps aux | grep tracker | awk '$11 ~ /tracker/ {print $2}'` local storage_pid=`ps aux | grep storage | awk '$11 ~ /storage/ {print $2}'` if [ $storage_pid ] then kill $storage_pid if [ $? -eq 0 ] then echo "stop storage success!" else echo "stop storage faild!" return -1 fi else echo "storage is stoped!" fi if [ $tracker_pid ] then kill $tracker_pid if [ $? -eq 0 ] then echo "stop tracker success!" else echo "stop tracker failed!" return -2 fi else echo "tracker is stoped!" fi return 0 } function start_fastdfs(){ local tracker_pid=`ps aux | grep tracker | awk '$11 ~ /tracker/ {print $2}'` local storage_pid=`ps aux | grep storage | awk '$11 ~ /storage/ {print $2}'` if [ ! $tracker_pid ] then /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf if [ $? -eq 0 ] then echo "start tracker success" else echo "start tracker failed" return -1 fi else echo "tracker is running!" fi if [ ! $storage_pid ] then /usr/bin/fdfs_storaged /etc/fdfs/storage.conf if [ $? -eq 0 ] then echo "start storage success" else echo "start storage failed" return -2 fi else echo "storage is running!" fi return 0 } function exec_status(){ if [ $1 -eq 0 ] then echo "$2 fastdfs success!" else echo "$2 fastdfs failed!" fi } if [ $cmd = "start" ] then start_fastdfs exec_status $? "start" elif [ $cmd = "stop" ] then stop_fastdfs exec_status $? "stop" elif [ $cmd = "restart" ] then stop_fastdfs if [ $? -ne 0 ] then echo "stop fastdfs error,exit." exit fi start_fastdfs if [ $? -ne 0 ] then echo "start fastdfs error,.exit:" exit fi echo "restart fastdfs ok!" else echo "nothing to do" fi
## nginx.sh #!/bin/bash nginx_pid=`ps aux | grep nginx | awk '$12 ~ /master/ {print $2}'` cmd=$1 if [ ! $cmd ] then echo "Plase use: nginx.sh < start | stop | restart >." exit fi if [ $cmd = "start" ] then if [ $nginx_pid ] then echo "nginx is running, pid is `$nginx_pid`" exit fi /usr/local/nginx/sbin/nginx if [ $? -ne 0 ] then echo "start nginx faild" exit else echo "start nginx success!" exit fi elif [ $cmd = "stop" ] then if [ $nginx_pid ] then kill $nginx_pid if [ $? -eq 0 ] then echo "stop nginx success!" exit else echo "stop nginx failed" exit fi else echo "nginx is stoped, not to stop it" exit fi elif [ $cmd = "restart" ] then if [ $nginx_pid ] then kill $nginx_pid if [ $? -eq 0 ] then echo "stop nginx server" else echo "stop nginx server faild" exit fi fi /usr/local/nginx/sbin/nginx if [ $? -eq 0 ] then echo "start nginx server" else echo "start nginx server failed" exit fi else echo "Plase use: nginx.sh < start | stop | restart >." fi
4、总结
- 之前开发SpringBoot项目上传图片一直有问题,突然看到
FastDFS
可以用于上传下载图片 - 花费了一天的时间将
FastDFS
整合到我的项目中去,同时将nginx
也和SpringBoot
项目整合在一起 - 之前使用
FastDFS
是准备用docker
容器搭建,最开始使用的是season/fastdfs
,但是这个镜像没有整合nginx
,所以换了另一个镜像delron/fastdfs
,这个虽然整合了nginx
,但是只要一重启storage
节点就失败,查看容器日志发现一直缺了一个storaged.log
文件,重启的时候会自动把这个文件删除,然后启动失败。试了很久发现不能用之后,只有不用docker
进行安装。