最近有一个需求,需要将图片存在服务器里,所以我准备搭建一个自己的图片服务器,基于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的源码,进行编译安装(传送门)

docker 区别 服务器 docker和服务器_docker 区别 服务器

# 编译安装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自启动了

docker 区别 服务器 docker和服务器_docker_02


  然后通过网络访问nginx也成功了,说明我们的默认配置没有问题,Nginx安装成功

docker 区别 服务器 docker和服务器_docker_03

配置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,然后重启

docker 区别 服务器 docker和服务器_java_04


  图片访问就到这里了,然后开始图片上传,通过前端将图片传递到后端,然后后端通过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端口,这部分的代码后面在更新

  图片资源服务器就搭建好了,并且支持上传和下载操作,除了通过工具去上传下载,还可以自己写个项目进行上传下载,这部分就不演示了