nginx+vsftp搭建图片服务器,(附jsch java上传vsftp代码)

项目架构简介
服务器两台,一台上面搭载nginx和tomcat1
另一台上有一个tomcat2和redis

ngixn集群下图片上传的问题:当图片上传到tomcat1下,再次请求图片的时候nginx有可能把请求转发到tomcat2上,导致获取不到图片

解决方案:用tomcat1作为一台图片服务器,利用ftp将图片都上传到tomcat1下,配置nginx图片转发路径到tomcat1下。

nginx配置

 location / {
        proxy_pass http://tomcat_server;    
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~ .*\.(gif|jpg|jpeg|png)$ {  
        proxy_pass http://127.0.0.1:8080;
    }

ftp配置文件

ftp_host=192.168.0.116
ftp_port=22
ftp_username=shuheng
ftp_password=sh123456
ftp_path=/usr/tomcat8/apache-tomcat-8.5.24/webapps/SHYL/
ftp_timeout=500000

ftp_init_pool_size=1
ftp_max_pool_size=10

sshsession连接池代码,因为每次连接时间都特别长,所以写了一个连接池.
尝试过使用反射,在session 调用 disconnect()方法的时候自动将session返回连接池,但是没有成功,可能是因为session继承的是Runnable接口。

package com.shyl.framework.util.ftp;

import java.util.LinkedList;
import java.util.Properties;
import java.util.ResourceBundle;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.shyl.framework.util.Logger;

public class SSHSessionPool {
    protected static Logger logger = Logger.getLogger(SSHSessionPool.class);
    private static LinkedList<Session> sessionList = new LinkedList<Session>();
    private static final ResourceBundle resource = ResourceBundle.getBundle("globalconfig");
    //ftp主机地址
    private static final String host = resource.getString("ftp_host");
    //端口
    private static final int port = Integer.valueOf(resource.getString("ftp_port"));
    //ftp用户名
    private static final String username = resource.getString("ftp_username");
    //ftp密码
    private static final String password = resource.getString("ftp_password");
    //ftp连接超时时间
    private static final int timeout = Integer.parseInt(resource.getString("ftp_timeout"));
    //初始化session池大小
    private static final int initPoolSize = Integer.parseInt(resource.getString("ftp_init_pool_size"));
    //session池最大大小
    private static final int maxPoolSize = Integer.parseInt(resource.getString("ftp_max_pool_size"));

    private static int total = 0;
    //静态方法初始化连接池
    static{
        logger.info("sshsession pool创建开始");
        for(int i=0;i<initPoolSize;i++){
            Session session = createSession();
            sessionList.add(session);
            total++;
        }
        logger.info("sshsession pool创建完成");
    }
    /**
     * 创建session
     * @return
     */
    private static synchronized Session createSession(){
        JSch jsch = new JSch();  
        Session session = null;
        try {
            System.out.println("Session creating。。。。。。");  
            jsch.getSession(username, host, port);
            session = jsch.getSession(username, host, port);  
            session.setPassword(password);  
            Properties sshConfig = new Properties();  
            sshConfig.put("StrictHostKeyChecking", "no");  
            session.setConfig(sshConfig);  
            session.setTimeout(timeout); 
            session.connect();
            System.out.println("Session created"); 
        } catch (JSchException e) {
            e.printStackTrace();
        } 
        return session;
    }

    /**
     * 获取session
     * 如果连接池用尽,总量小于最大值,继续创建
     * @return
     */
    public Session getSession(){
        Session session = null;
        if(sessionList.size()>0){
            session = sessionList.removeFirst();
        }else{
            if(total < maxPoolSize){
                session = createSession();
                sessionList.add(session);
                total++;
            }
        }
        return session;
    }
    /**
     * 释放,将连接还回连接池
     * @param session
     */
    public void release(Session session){
        sessionList.add(session);
    }

    public int  poolSize() {
        return sessionList.size();
    }
}

配置在spring环境中,这样在tomcat启动的时候会变慢,但是用户上传图片的时候变快了

<bean id="sshSessionPool" class="com.shyl.framework.util.ftp.SSHSessionPool"></bean>

上传工具类

package com.shyl.framework.util.ftp;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ResourceBundle;


import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.shyl.framework.util.Logger;

public class SFtpUtil {
    protected static Logger logger = Logger.getLogger(SFtpUtil.class);

    public static final ResourceBundle resource = ResourceBundle.getBundle("globalconfig");

    public static String basePath = resource.getString("ftp_path");




    /** 
     * 连接sftp服务器 
     * @param host 主机 
     * @param port 端口 
     * @param username 用户名 
     * @param password 密码 
     * @return 
     */  
    public static ChannelSftp connect(Session session) {  
        ChannelSftp sftp = null;  
        try {  
            if(session.isConnected()){
                Channel channel = session.openChannel("sftp");  
                channel.connect();  
                sftp = (ChannelSftp) channel;  
                System.out.println("Connected to " + session.getHost());  
            }
        } catch (Exception e) {  
            e.printStackTrace() ;  
        }  
        return sftp;  
    }  

    /** 
     * 上传文件 
     * @param directory 上传的目录 
     * @param uploadFile 要上传的文件 
     * @param sftp 
     * @throws SftpException 
     */  
    public static void upload(String directory, InputStream input,String fileName, ChannelSftp sftp) throws SftpException {  
        try {  
            sftp.ls(directory);
        } catch (Exception e) {  
            sftp.mkdir(directory);
        }  
        sftp.cd(directory);  
        sftp.put(input, fileName);  
        System.out.println("上传 完毕");
    }  

    /** 
     * 下载文件 
     * @param directory 下载目录 
     * @param downloadFile 下载的文件 
     * @param saveFile 存在本地的路径 
     * @param sftp 
     */  
    public static void download(String directory, String downloadFile,String saveFile, ChannelSftp sftp) {  
        try {  
            sftp.cd(directory);  
            File file=new File(saveFile);  
            sftp.get(downloadFile, new FileOutputStream(file));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

    /** 
     * 删除文件 
     * @param directory 要删除文件所在目录 
     * @param deleteFile 要删除的文件 
     * @param sftp 
     */  
    public static void delete(String directory, String deleteFile, ChannelSftp sftp) {  
        try {  
            sftp.cd(directory);  
            sftp.rm(deleteFile);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  

//    public static void main(String[] args) throws FileNotFoundException, SftpException {
//      ChannelSftp channelSftp = SFtpUtil.connect();
//      File file = new File("D://aaa.txt");
//      FileInputStream fileInputStream = new FileInputStream(file);
//      
//      SFtpUtil.upload("/usr/tomcat8/apache-tomcat-8.5.24/webapps/SHYL/uploadFiles/wechat4", fileInputStream,"ccc", channelSftp);
//      //new ImageUtil().resize(ctxPath + fileName, 0.5);
//  }   

}

上传代码

@Resource(name = "sshSessionPool")
    private SSHSessionPool sshSessionPool;


    @RequestMapping(value = "/Upload")
    @ResponseBody
    public void upload(HttpServletResponse response,
            HttpServletRequest request) throws IOException, SftpException {
        // 图片路径
        String imgPath = Const.BLANK;
        // 图片名称
        String fileName = null;
        // 图片后缀
        String fileExt = null;
        // 文件格式错误信息
        String fileExtError = null;
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();

        response.setContentType("text/html"); 
        response.setCharacterEncoding("UTF-8"); 
        PrintWriter pw=response.getWriter();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // 上传文件
            MultipartFile mf = entity.getValue();
            // 获取图片大小
            int picSize = Integer.parseInt(String.valueOf(mf.getSize()));
            // 获取原文件名
            fileName = mf.getOriginalFilename();

            // 获取图片后缀
            fileExt = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
            if(!Const.JPG.equals(fileExt) && !Const.PNG.equals(fileExt) && !Const.JPEG.equals(fileExt) && !Const.GIF.equals(fileExt)){
                fileExtError = "no";
                pw.write(fileExtError);
            } else if(picSize > Const.INT_TEN_MB){
                fileExtError = "nosize";
                pw.write(fileExtError);
            } else {
                // 对原文件名进行重命名
                fileName = this.get32UUID()+"."+fileExt;
                // 返回图片路径
                imgPath = Const.FILMPATH + fileName;
                try {
                    //上传至ftp
                    logger.info("获取前"+sshSessionPool.poolSize());
                    com.jcraft.jsch.Session session = sshSessionPool.getSession();
                    ChannelSftp sftp = SFtpUtil.connect(session);
                    logger.info("获取后"+sshSessionPool.poolSize());
                    SFtpUtil.upload(SFtpUtil.basePath+Const.FILMPATH, mf.getInputStream(),fileName, sftp);
                    sshSessionPool.release(session);
                    logger.info("归还后"+sshSessionPool.poolSize());
//                  new ImageUtil(ctxPath + fileName).resize(ctxPath + fileName, 0.5);
                    pw.write(imgPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

备注:jcraft官网:http://www.jcraft.com/jsch/
使用的是jsch-0.1.54.jar这个版本
在maven上下载过0.1.50这个版本,总是报session is down的错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值