Centos 7 部署Nginx + FTP 搭建Java文件服务器(含源码)

主要内容

  • 安装Linux
  • 配置网络
  • 编译安装Nginx
  • 安装配置Vsftp
  • Java代码测试

一、安装Linux

         通过VMWare WorkStation安装测试环境,为了模拟正式库系统盘及数据盘,可以调整配置如下:

         硬盘,按照通用云服务器的做法一般会分两块硬盘,一块系统盘,一块数据盘,初期都在40G;

         内存,由于此次部署微服务架构内存设为4g;

         网卡,Linux需要联网安装软件环境,又需要有固定服务IP,鉴于公司的设备情况,配置一块桥接网卡及一块NAT网卡设备;

       如图:

虚拟机配置示例

安装过程 不在演示如果不明白可以都选择默认即可。

二、配置网络

       此处必须提一下,很多人就是卡在这里,一开始接触Linux的人也很容易卡在网络配置上,在网上搜索很多文章 其实他们说的都是对的,可能你就是不明白 呵呵! 这里给大家补充一下。

大部分人是从虚拟机起步,所以大家先了解一下虚拟机的网络类型:

1.桥接模式   此模式下获取的IP是和你电脑IP同一个网段,意思就是说当前路由器下的电脑都可以访问此虚拟机。比如你电脑IP是192.168.0.110  那么此模式获取的ip也是192.168.0.x 。但此模式的缺点就是不可以有多个,优点是可以访问外网(DNS配好的情况下),也可以被外网(局域网或者配置花生壳被外网)访问。

2.NAT模式   NAT 我猜的单词是 NET Adapter Ttransfer 网络转换传输的意思 他在本地虚拟了一个网络,也就是给你配置了一个路由器,只是虚拟的。这种模式的优点是可以访问外网,也可以有多个。

3.主机模式  主机模式跟NAT模式类似,只是不能访问外网。

自定义网络  就是可以在配几个网络模拟真实硬件环境;

另外,还需要了解的一个概念,就是路由的IP分配方式,个人电脑获取IP的方式大部分都是自动分配也就是路由的DHCP服务在管理的,IP有租期的,租期过了而电脑又没有使用,就会被释放。服务器的IP 是不能这样的管理的,要静态的IP(static).

好吧,进入操作模式:

查看网卡信息

cd  /etc/sysconfig/network-scripts/ (这个是亘古不变的目录)

看到ifcfg-xxx的命名就是网卡信息,此处需要注意的是,最好在安装系统之前把两块网卡给添加上去,如果装完系统后在添加网卡,这个信息是不在的 需要手动编辑,而手动编辑的坑劝你还是不要钻了。

新手推荐方式:首先改变两个文件的一个参数就是开机启动 把onboot 后面的值改为yes 然后保存退出,接着重启!

查看IP信息

ip a(ip address的缩写) 或者 ifconfig 还是用ip a 吧 centos7mini版本是没有了ifconfig命令了的

看到两个网卡信息 是已经获取到了IP 网段和你相同的那个网卡就是桥接模式。另外 ,lo 地址127.0.0.1 有一个专业称呼 回环地址(就是自己解析到自己的意思)。

接下来,就是要改静态IP地址了,此处 把桥接模式作为静态模式修改,一来可以局域网访问,而来免了配置DNS的麻烦,因为DNS 就算配置好 有时候也要改,就用NAT上网,而桥接作为内网链接。

又有几个单词,你得记住了  IPADDR/NETMASK/GATEWAY

保存,重启网络服务,或者干脆的reboot 都可以!

(附注:以上截图来自连接终端,而不是控制台,连接终端推荐大家用SecureCRT、Xshell,或者临时的使用putty).

三、配置安装Nginx

下载地址:http://nginx.org/en/download.html   前面的版本是Linux格式,后面是Windows。生产环境用stable版本 实验用最新版本即可。

2  编译环境

重要的是gcc 

yum install gcc-c++ -y

    下面的我们尽管装即可,呵呵

yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
yum install -y make automake

解压

tar -xzvf nginx-1.15.tar.gz

编译安装

cd nginx-1.15

./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi

make & make install

3.启动、停止nginx

cd /usr/local/nginx/sbin/
./nginx 

cd /usr/local/nginx/sbin
./nginx -s quit

#重新加载配置
./nginx -s reload

 

四、安装Vsftp

#安装vsftp
yum -y install vsftpd
#启动vsftp
systemctl start vsftpd 

#添加用户并制定宿主目录 
useradd ftpuser -d /ftpfile -s /sbin/nologin
#改变目录所属用户和组
chown -R ftpuser:ftpuser /ftpfile


更改密码
passwd ftpuser

修改目录权限 
#执行权限授予命令
chmod 755 -R /ftpfile
chmod 777 -R /ftpfile/clb

vi /etc/vsftpd/chroot_list
添加刚刚的用户
ftpuser


#注意关闭selinux 及防火墙端口开放。

修改配置文件 vsftpd.conf

#(当本地用户登入时,将被更换到定义的目录下,默认值为各用户的家目录) 
local_root=/ftpfile/clb
#(使用匿名登入时,所登入的目录) 
anon_root=/ftpfile/clb
#(默认是GMT时间,改成使用本机系统时间)
use_localtime=YES
#(不允许匿名用户登录)
anonymous_enable=NO
#(允许本地用户登录)
local_enable=YES
#(本地用户可以在自己家目录中进行读写操作)
write_enable=YES
#(本地用户新增档案时的umask值)
local_umask=022
#(如果启动这个选项,那么使用者第一次进入一个目录时,会检查该目录下是否有.message这个档案,如果有,则会出现此档案的内容,通常这个档案会放置欢迎话语,或是对该目录的说明。默认值为开启)
dirmessage_enable=YES
#(是否启用上传/下载日志记录。如果启用,则上传与下载的信息将被完整纪录在xferlog_file 所定义的档案中。预设为开启。)
xferlog_enable=YES
#(指定FTP使用20端口进行数据传输,默认值为YES)
connect_from_port_20=YES
#(如果启用,则日志文件将会写成xferlog的标准格式)
xferlog_std_format=YES
#(这里用来定义欢迎话语的字符串)
ftpd_banner=Welcome to mmall FTP Server
#(用于指定用户列表文件中的用户是否允许切换到上级目录)
chroot_local_user=NO
#(设置是否启用chroot_list_file配置项指定的用户列表文件)
chroot_list_enable=YES
#(用于指定用户列表文件)
chroot_list_file=/etc/vsftpd/chroot_list
#(设置vsftpd服务器是否以standalone模式运行,以standalone模式运行是一种较好的方式,此时listen必须设置为YES,此为默认值。建议不要更改,有很多与服务器运行相关的配置命令,需要在此模式下才有效,若设置为NO,则vsftpd不是以独立的服务运行,要受到xinetd服务的管控,功能上会受到限制)
listen=YES
#(虚拟用户使用PAM认证方式,这里是设置PAM使用的名称,默认即可,与/etc/pam.d/vsftpd对应) userlist_enable=YES(是否启用vsftpd.user_list文件,黑名单,白名单都可以
pam_service_name=vsftpd
#(被动模式使用端口范围最小值)
pasv_min_port=61001
#(被动模式使用端口范围最大值)
pasv_max_port=62000
#(pasv_enable=YES/NO(YES)
pasv_enable=YES
#允许用户有写的权限
allow_writeable_chroot=YES

整合Nginx,可以添加一个虚拟主机用于解析文件 ,也可以直接在主server里面添加该配置

location  ~ .*\.(jpg|gif|png|bit|jpeg){
                gzip on;
                root /ftpfile/clb;
        }
nginx -s reload

如果上传了文件,通过nginx 访问不到可以通过改变目录所属

chown nginx /ftpfile/clb

测试访问

五、编写Java文件服务

  @CrossOrigin(maxAge = 3600,origins = "*",allowCredentials = "true")
    @PostMapping("/singileFileUpload")
    @ResponseBody
    public ResponseData singileFileUpload(@RequestParam("fileInfo") MultipartFile fileInfo,Integer dirFlag,String operator,String dynamicParams){ //
        if (fileInfo.isEmpty()) {
            return ResponseData.result(500,"上传文件为空,请重新上传!");
        }

        // 获取文件原名称
        String originalFileName = fileInfo.getOriginalFilename();
        // 文件后缀
        String fileSuffix = originalFileName.substring(originalFileName.lastIndexOf("."));

        if(!LEGAL_SUFFIX_CONFIG.contains(fileSuffix.toUpperCase())){
            return ResponseData.result(500,"不支持该"+fileSuffix+"文件类型上传!");
        }

        // 根据dirFlag 获取目录
        String fileDir = "/unknown/"+ DateUtils.getTodayDateString()+"/";

        switch (dirFlag){

            case 1:  // 常用目录
                fileDir = ConstDirFlag.PATH_FILE_COMMON_DIR;
                break;
            case 2: // 车辆档案信息
                fileDir = ConstDirFlag.PATH_FILE_CAR_INFO_CARNO;
                break;

        }
        String dynaDirPath = "";
        // 判断动态目录是否包含参数
        if(!StringUtils.isEmpty(dynamicParams)){
            if(dynamicParams.contains("_")) {
                String[] dynaDir = dynamicParams.split("_");
                for (int i = 0; i < dynaDir.length; i++) {
                    dynaDirPath+=dynaDir[i]+"/";
                }
            }else{
                dynaDirPath = dynamicParams+"/";
            }
        }

        fileDir+=dynaDirPath;

        String fileName = Random.getId()+originalFileName.substring(originalFileName.lastIndexOf("."));

        try {
            boolean b = FtpUtil.uploadFile(ftphost, ftpport, ftpuser, ftppassword, basePath, fileDir, fileName, fileInfo.getInputStream());
            if(b){
                 // 相关业务操作

                return ResponseData.result(1,"success",vo);
            }else{
                LOGGER.error("上传文件"+originalFileName+"出错");
                return ResponseData.result(500,"文件服务器出了点问题,请稍后再次尝试!");
            }

        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error("上传文件"+originalFileName+"出错,错误信息:"+e.getMessage());
        }
        return ResponseData.result(500,"上传出了点问题,请再次尝试!");
    }
    
    

FtpUtils

/** 
	 * Description: 向FTP服务器上传文件 
	 * @param host FTP服务器hostname 
	 * @param port FTP服务器端口 
	 * @param username FTP登录账号 
	 * @param password FTP登录密码 
	 * @param basePath FTP服务器基础目录
	 * @param filePath FTP服务器文件存放路径
	 * @param filename 上传到FTP服务器上的文件名 
	 * @param input 输入流 
	 * @return 成功返回true,否则返回false 
	 */  
	public static boolean uploadFile(String host, int port, String username, String password, String basePath,
			String filePath, String filename, InputStream input) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);// 连接FTP服务器
			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
			ftp.login(username, password);// 登录
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			//切换到上传目录
			if (!ftp.changeWorkingDirectory(basePath+filePath)) {
				//如果目录不存在创建目录
				String[] dirs = filePath.split("/");
				String tempPath = basePath;
				for (String dir : dirs) {
					if (null == dir || "".equals(dir)) continue;
					tempPath += "/" + dir;
					if (!ftp.changeWorkingDirectory(tempPath)) {
						if (!ftp.makeDirectory(tempPath)) {
							return result;
						} else {
							ftp.changeWorkingDirectory(tempPath);
						}
					}
				}
			}
			//设置上传文件的类型为二进制类型
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			//上传文件
			if (!ftp.storeFile(filename, input)) {
				return result;
			}
			input.close();
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		}
		return result;
	}
发布了70 篇原创文章 · 获赞 16 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/ucicno000/article/details/86735883
今日推荐