Jmeter解决SSH连接数据库(已公布源码)

项目背景:

有3台机器:

远程数据库(192.168.125.130)

跳板机(192.168.125.129)

客户机(192.168.125.1),

客户机不能直接JDBC连接远程数据库,跳板机可以直接连接远程数据库。

 

解决策略:

客户机要想连接远程数据库只能通过SSH连接。

步骤1.在客户机,跳板机,远程数据库分别安装SSH

步骤2.在客户机命令行输入 SSH –L 3308:192.168.125.130:3306 root@192.168.125.129

3308:在客户机开启的端口号

3306:远程数据库端口号

root@192.168.125.129 跳板机用户名和主机

步骤3.输入跳板机密码

至此,已成功建立SSH连接。(SSH端口原理请自行百度)

这只是思路,具体实现请往下看。

 

上面已经说到了思路,那好办了,让jmter先建立SSH,然后再通过jdbc来访问。

以下是本人想到的两种方案:

1) 写一个类似于JDBCconfigure SSH JDBC configure组件(因本人时间有限未进行尝试)

2) 通过java sample来实现SSH连接(本文所实现的方法)

 

1.       跳过新建java Sample的步骤(读者不会的可自行百度)

本次我们要用到的外部jar

 

2.       新建一个项目

 

3.       编写SSHutil工具类

主要实现的方法

1) 创建session方法

 

2)连接SSH方法

 

3)关闭SSH方法

 

package com.jcraft.jsch;

import java.io.Serializable;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SSHutil implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 
	 */

	private static  JSch jsch ;
	private static Session session;
	
	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		SSHutil.session = session;
	}
	
	public Session creatsession(String SSHhost, String SSHPort, String SSHUsername, String SSHPassword){
		try{
		jsch = new JSch();
		session = jsch.getSession(SSHUsername, SSHhost, Integer.parseInt(SSHPort));
		session.setPassword(SSHPassword);
		session.setConfig("StrictHostKeyChecking", "no");
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return session;
	}

	public  void ConnectSSH(String localport, String remotehost, String remoteport) throws JSchException{
		
			
				session.connect();
				session.setPortForwardingL(Integer.parseInt(localport), remotehost, Integer.parseInt(remoteport));
				//System.out.println("localhost:" + assinged_port + " -> " + remotehost + ":" + remoteport);
				//System.out.println("startsession:" + session);
			

		
	}
	
	public void CloseSSH(Session session){
		System.out.println("Session:" + session);
			if (session != null &&session.isConnected()){
				session.disconnect();
			}
		}

}

 

4.       编写Net类(用于判断端口是否被占用)

package com.jcraft.jsch;

import java.io.IOException;  
import java.net.InetAddress;  
import java.net.Socket;  
import java.net.UnknownHostException;  
  
public class NetUtil {  
      
    /*** 
     *  true:already in using  false:not using  
     * @param port 
     */  
    public static boolean isLoclePortUsing(int port){  
        boolean flag = true;  
        try {  
            flag = isPortUsing("127.0.0.1", port);  
        } catch (Exception e) {  
        }  
        return flag;  
    }  
    /*** 
     *  true:already in using  false:not using  
     * @param host 
     * @param port 
     * @throws UnknownHostException  
     */  
    public static boolean isPortUsing(String host,int port) throws UnknownHostException{  
        boolean flag = false;  
        InetAddress theAddress = InetAddress.getByName(host);  
        try {  
            Socket socket = new Socket(theAddress,port);  
            flag = true;  
        } catch (IOException e) {  
              
        }  
        return flag;  
    }  
}  

5.       编写startSSH类(完整代码请联系作者)

package com.startSSH;



import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.NetUtil;
import com.jcraft.jsch.SSHutil;


public class StartSSH extends AbstractJavaSamplerClient {
	
	private static final Logger log = LoggerFactory.getLogger(StartSSH.class);

	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {
		SampleResult result = new SampleResult();
		result.sampleStart();
		SSHutil util = new SSHutil();
				String localport = arg0.getParameter("localport");
				String remotehost = arg0.getParameter("remotehost");
				String remoteport = arg0.getParameter("remoteport");
				String SSHhost = arg0.getParameter("SSHhost");
				String SSHPort = arg0.getParameter("SSHPort");
				String SSHUsername = arg0.getParameter("SSHUsername");
				String SSHPassword = arg0.getParameter("SSHPassword");
				util.creatsession(SSHhost, SSHPort, SSHUsername, SSHPassword);
				if(! util.getSession().isConnected() && NetUtil.isLoclePortUsing(Integer.parseInt(localport)) == false){
					try{
						util.ConnectSSH(localport, remotehost, remoteport);
						result.setResponseMessage("现在开始连接");
						result.setSuccessful(true);
					}
					catch(Exception e){
						e.printStackTrace();
						log.error(e.getMessage());
						result.setResponseMessage("出现异常");
						result.setSuccessful(false);
					}

					
				}
				else if(NetUtil.isLoclePortUsing(Integer.parseInt(localport)) == true && util.getSession().isConnected()){
					result.setResponseMessage("连接已存在");
					result.setSuccessful(true);
				}
				else{
					result.setSuccessful(false);
				}
			return result;
			}
	

	@Override
	public Arguments getDefaultParameters() {
		// TODO Auto-generated method stub
		Arguments params = new Arguments();
		params.addArgument("localport", "localport");
		params.addArgument("remotehost", "remotehost");
		params.addArgument("remoteport", "remoteport");
		params.addArgument("SSHhost", "SSHhost");
		params.addArgument("SSHPort", "SSHport");
		params.addArgument("SSHUsername", "SSHUsername");
		params.addArgument("SSHPassword", "SSHPassword");
		return params;
	}

	@Override
	public void setupTest(JavaSamplerContext context) {

	}

	@Override
	public void teardownTest(JavaSamplerContext context) {

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
       StartSSH test = new StartSSH();
       Arguments arg0 = test.getDefaultParameters();
       JavaSamplerContext context =  new JavaSamplerContext(arg0);
       test.setupTest(context);
       test.runTest(context);
       test.teardownTest(context);
	}

}

6.       编写closeSSH类(完整代码请联系作者)

package com.startSSH;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import com.jcraft.jsch.NetUtil;
import com.jcraft.jsch.SSHutil;

import org.slf4j.*;

public class CloseSSH extends AbstractJavaSamplerClient {
	private static final Logger log = LoggerFactory.getLogger(CloseSSH.class) ;

	@Override
	public Arguments getDefaultParameters() {
		// TODO Auto-generated method stub
		Arguments params = new Arguments();
		params.addArgument("localport", "localport");
		return params;
	}

	@Override
	public void setupTest(JavaSamplerContext context) {

	}

	@Override
	public void teardownTest(JavaSamplerContext context) {

	}

	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {
		// TODO Auto-generated method stub
		SampleResult result = new SampleResult();
		SSHutil util = new SSHutil();
		String localport = arg0.getParameter("localport");
		
		try {		
				if(NetUtil.isLoclePortUsing(Integer.parseInt(localport)) == true){
					util.CloseSSH(util.getSession());
					result.setResponseMessage("session status: "+util.getSession().isConnected()+" 关闭成功");
					result.setSuccessful(true);
				}
				else{
					result.setResponseMessage("session status: "+util.getSession().isConnected()+" 无须关闭");
					result.setSuccessful(true);
				}
			
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccessful(false);
			log.error(e.getMessage());
			result.setResponseMessage("关闭失败"+"session: "+util.getSession());
		}
		return result;
	}

	public static void main(String[] args) {
		CloseSSH test = new CloseSSH();
		Arguments arg0 = test.getDefaultParameters();
		JavaSamplerContext context = new JavaSamplerContext(arg0);
		test.setupTest(context);
		test.runTest(context);
		test.teardownTest(context);
	}

}

7.       把编写好的类分别打成两个jar包(StartSSH.jarCloseSSH.jar

8.       把打好的两个jar放到%JMTER_HOME%/lib/ext

9.       打开JMeter,新建两个java request

 

 

10.   开始测试

 

成功,打完收工。

自此完成jmter通过SSH连接数据库功能。

 

 

 

 

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值