最近有一个需求,需要将图片存在服务器里,所以我准备搭建一个自己的图片服务器,基于centos系统,安装nginx来做映射,在开始之前建议先更新centos的yum源
# 更新yum源
yum update
创建镜像
都到了搭建自己的服务器了,docker的指令就不想说了,注意的是需要放21端口和自己的外网访问端口,21端口是用来上传文件的,外网访问端口是用来通过外网访问图片
docker run -itd -p 8082:8082 -p 223:22 --privileged --restart=always --name imagesSource mycentos /usr/sbin/init
安装Nginx
我使用的是Nginx,Nginx的好处就不多说了,首先得配置安装Ngnix的环境
# 安装Nginx需要的环境
yum install gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
然后去官网下载Nginx的源码,进行编译安装(传送门)
# 编译安装Nginx
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0/
# Nginx的配置我使用的是默认配置,执行配置
./configure
# 使用make编译安装,如果没有make指令,先安装make
yum install -y make
make
make install
启动Nginx,并设置开机自启动
上面完成了Nginx的安装,接下来就开始启动Nginx
# 查找Nginx的安装目录
whereis nginx
# 进入安装目录
cd usr/local/nginx/
# 启动
./nginx
# 停止
./nginx -s stop
# 此方式停止步骤是待nginx进程处理任务完毕进行停止
./nginx -s quit
# 此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程
./nginx -s stop
# 设置开机自启动
vi /etc/rc.local
# 添加nginx的执行路径
/usr/local/nginx/sbin/nginx
# 设置执行权限
chmod 755 rc.local
Nginx就安装成功了,测试我们的配置是否成功,首先重启容器,通过 “top” 指令可以看到Nginx自启动了
然后通过网络访问nginx也成功了,说明我们的默认配置没有问题,Nginx安装成功
配置Nginx
Nginx安装完成后,就开始搭建图片服务器,首先是访问服务器上面图片,需要在配置文件中增加配置,我的图片路径是 “/root/images”
# 在配置文件中添加以下配置
server {
listen 8082; # 监听的端口
server_name localhost;# 服务名
location /images/ { # 位置,访问时以 ip + /images/ + 文件名
root /root; # 文件的位置 /root/images
autoindex_exact_size off; # 显示出文件的确切大小,默认为on开启
autoindex_localtime on; # 显示的文件时间为文件的服务器时间,off时显示为GMT时间
charset utf-8,gbk; # 编码设置
}
配置完成后重启,然后通过 “ip + 端口 + /images/ + 文件名” 访问图片,注意,如果出现403的错误需要将配置文件中的用户改为root,然后重启
图片访问就到这里了,然后开始图片上传,通过前端将图片传递到后端,然后后端通过ftp服务上传到服务器,所以接下来就开始安装ftp服务,并在java代码中集成ftp执行上传功能
文件上传
文件上传我使用了两种方式,一种是scp上传,一种是通过ftp上传
首先通过scp上传,需要开放22端口,开启sshd服务,通过 “top” 指令查看sshd服务是否开启
# 开始sshd服务
systemctl start sshd
# 安装密码插件
yum install -y passwd
# 修改密码,连续输入两次相同的密码
passwd
然后进行java代码集成
# 导入jar包
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>
为了方便,就直接封装成工具,我通过外网测试,上传100M约耗时1分钟,下载100M耗时约40秒,速度还是挺快的
import ch.ethz.ssh2.*;
/**
* 上传文件到服务器
* @param host 服务器主机地址
* @param port 服务器端口
* @param filePath 本地文件路径
* @param username 用户名
* @param password 密码
* @param remotePath 服务器保存地址
*/
private void uploadFile(String host, Integer port, String filePath, String remotePath, String username, String password) {
FileInputStream stream = null;
Connection conn = null;
SCPOutputStream put = null;
try {//建议使用try-catch-finally,即使异常结束,也可以在finally中关闭流
File file = new File(filePath);//获取文件
stream = new FileInputStream(file);//获取文件流
conn = new Connection(host, port);//创建连接
conn.connect();//连接服务器
boolean isAuth = conn.authenticateWithPassword(username, password);//验证用户
if (!isAuth) {
System.out.println("连接失败");
return;
}
//判断服务端文件路径是否存在,不存在则创建
SFTPv3Client ftp = new SFTPv3Client(conn);
boolean isDir = ftp.lstat(remotePath).isDirectory();
if (!isDir) {
ftp.mkdir(remotePath, 0600);
}
SCPClient client = new SCPClient(conn);//scp对象
//复制到服务器的文件名,文件大小,服务器路径
put = client.put(file.getName(), file.length(), remotePath, null);
byte[] b = new byte[102400000];
int i;
while ((i = stream.read(b)) != -1) {//已二进制流的方式上传,如果文件已存在,默认会被覆盖
put.write(b, 0, i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (put != null)
put.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (stream != null)
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (conn != null)
conn.close();
}
}
/**
* 下载服务器文件到本地
* @param name 文件名
* @param host 主机
* @param port 段鸥
* @param filePath 本地的路径
* @param remotePath 服务器的路径
* @param username 用户名
* @param password 密码
*/
private void downloadFile(String name, String host, Integer port, String filePath, String remotePath, String username, String password) {
FileOutputStream stream = null;
Connection conn = null;
SCPInputStream put = null;
try {//建议使用try-catch-finally,即使异常结束,也可以在finally中关闭流
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
file = new File(filePath + name);
stream = new FileOutputStream(file);//获取文件流
conn = new Connection(host, port);//创建连接
conn.connect();//连接服务器
boolean isAuth = conn.authenticateWithPassword(username, password);//验证用户
if (!isAuth) {
System.out.println("连接失败");
return;
}
SCPClient client = new SCPClient(conn);//scp对象
//复制到服务器的文件名,文件大小,服务器路径
put = client.get(remotePath + name);
byte[] b = new byte[409600000];
int i;
while ((i = put.read(b)) != -1) {//已二进制流的方式上传
stream.write(b, 0, i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.flush();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
if (put != null)
put.close();
} catch (IOException e) {
e.printStackTrace();
}
if (conn != null)
conn.close();
}
}
第二种方式,通过ftp上传,首先的在服务器中安装开启ftp服务器
# 安装ftp服务
yum install -y vsftpd
# 运行服务
systemctl start vsftpd
# 设置开机启动
chkconfig vsftpd on
# 编辑配置
vim /etc/vsftpd/vsftpd.conf
# 修改一下配置
anonymous_enable=NO # 设定不允许匿名访问
local_enable=YES # 设定本地用户可以访问
chroot_list_enable=YES # 使用户不能离开主目录
ascii_upload_enable=YES
ascii_download_enable=YES # 设定支持ASCII模式的上传和下载功能
# 添加以下配置
guest_enable=YES #设定启用虚拟用户功能
guest_username=ftp # 指定虚拟用户的宿主用户
user_config_dir=/etc/vsftpd/vuser_conf # 设定虚拟用户个人vsftp的CentOSFTP服务文件存放路径
# 创建账号密码文本 单行是用户名,双行是密码
vim /etc/vsftpd/vuser_passwd.txt
# 生成虚拟用户账号密码的db文件,并且关联db文件
db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.db
# 修改认证方式,编辑认证文件/etc/pam.d/vsftpd,全部注释掉原来语句,再增加以下两句
auth required pam_userdb.so db=/etc/vsftpd/vuser_passwd
account required pam_userdb.so db=/etc/vsftpd/vuser_passwd
# 创建虚拟用户管理路径
mkdir /etc/vsftpd/vuser_conf
# 编辑用户对应文件
vim /etc/vsftpd/vuser_conf/test
# 添加以下内容
local_root=/ftp
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
# 启动服务
systemctl start vsftpd.service
# 停止服务
systemctl stop vsftpd.service
# 重启服务
systemctl restart vsftpd.service
# 查看服务状态
systemctl status vsftpd.service
然后集成java代码进行测试
# 导入依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.7</version>
</dependency>
由于忘记映射21端口,这部分的代码后面在更新
图片资源服务器就搭建好了,并且支持上传和下载操作,除了通过工具去上传下载,还可以自己写个项目进行上传下载,这部分就不演示了