Highlighted
Absent Member.
Absent Member.
372 views

Why Java VUser Scripts takes 100 % CPU in Load Generators for just 20 to 30 concurrent users

We are trying to run a scenario in performance center which has script created using Java Vuser Protocol. Everytime we run this test, all Load Generatots hit 100 % CPU Utilization and the test fails.

Why would Java Vuser Script consume 100% CPU ? Please explain.

0 Likes
3 Replies
Highlighted
Acclaimed Contributor.
Acclaimed Contributor.

Re: Why Java VUser Scripts takes 100 % CPU in Load Generators for just 20 to 30 concurrent users

Before answering the question, we need some basic information.

- Is it custom script hand written or recorded?

If custom script, please share the code snippet to understand which piece of code consuming the resources.

- What is the version of PC?

0 Likes
Highlighted
Absent Member.
Absent Member.

Re: Why Java VUser Scripts takes 100 % CPU in Load Generators for just 20 to 30 concurrent users

Performance Center version is 11.52 and it is manually created script.

Code Sample mentioned below

/*
 * Script Description: RTS-Credit-ECD-Interac
 * -Hostname XXX -Port XXX -Ports XXX -ThinkTime 10 -Reconnect N/Y
 */

import java.io.*;
import java.nio.*;
import java.security.*;
import java.security.KeyStore;
import javax.net.ssl.*;
import java.net.*;
import javax.xml.bind.DatatypeConverter;
import java.util.*;
import lrapi.lr;

public class Actions
{
	/*
	* Node position - 8 for SVC, 7 for Refunds
	*/
	private static int iNodePosition = 8;
	/*
	* Enable/disable logging (set to FALSE for execution)
	*/
	private static boolean logging = false;
	/*
	* Mark DECLINE transactions as FAIL (default is FALSE)
	*/
	private static boolean bDecline = false;
	/*
	* Enable/disable request filtering (Good/Bad) & file write
	*/
	private static boolean filtering = false;
	private static String sFilePath = "C:\\Temp\\";

	/*
	* Set socket timeout in seconds
	*/
	private static int iSocketTimeout = 20;
	/*
	* Enables the JSSE system debugging system property:
	*     -Djavax.net.debug=all
	*     -Djavax.net.debug=handshake
	*/
	private static boolean debug = false;

	private Socket socket = null;
	private String sHost = null;
	private int iPort = 0;
	private boolean bSSL = true;
	private boolean bReconnect = false;

	public int init() throws Throwable {
	    try {
			//Get controller arguments
			sHost = lr.get_attrib_string("Hostname");//IP
			String sPort = lr.get_attrib_string("Port");//Base port
			String sPorts = lr.get_attrib_string("Ports");//Active ports
			String sThinkTime = lr.get_attrib_string("ThinkTime");//Default 10
			String sSSL = lr.get_attrib_string("SSL");
			String sReconnect = lr.get_attrib_string("Reconnect");

			if((sThinkTime == null || sThinkTime.isEmpty()) || (sThinkTime.equals("FATAL")))
				lr.save_string("10", "ThinkTime");
			else
				lr.save_string(sThinkTime, "ThinkTime");

			if((sHost == null || sHost.isEmpty()) || (sHost.equals("FATAL")))
				sHost = lr.eval_string("<Server>");
			
			if((sPorts == null || sPorts.isEmpty()) || (sPorts.equals("FATAL")))
				lr.save_string("1234567890", "ActivePorts");//1234567890
			else
				lr.save_string(sPorts, "ActivePorts");
	
			if((sReconnect == null || sReconnect.isEmpty()) || (sReconnect.equals("FATAL")))
				bReconnect = false;
			else if(sReconnect.equals("Y"))
				bReconnect = true;

			if((sSSL == null || sSSL.isEmpty()) || (sSSL.equals("FATAL")))
				bSSL = true;
			else if(sSSL.equals("SEC"))
				bSSL = false;

			if((sPort == null || sPort.isEmpty()) || (sPort.equals("FATAL")))
				sPort = lr.eval_string("<Port>");
			String sPortSuffix = Integer.toString(lr.eval_int("<Node>") % 10 );
			while(lr.eval_string("<ActivePorts>").indexOf(sPortSuffix) < 0) {
				fWriteLog("MSG: Exiting vuser <VuserID> as " + iPort + " is not in active ports list");
				lr.exit(lr.EXIT_VUSER, lr.AUTO);

				//fWriteLog("MSG: Fetching next Node as port#" + sPortSuffix + " is not in active ports list");
				//lr.advance_param("Node");
				sPortSuffix = Integer.toString(lr.eval_int("<Node>") % 10 );
			}
			iPort = Integer.parseInt(sPort) + Integer.parseInt(sPortSuffix);
	
			if(debug) {
			    System.setProperty("javax.net.debug", "all");//all OR handshake
			}

			//Create socket
			socket = connect(sHost, iPort);
		}
	    catch(Exception e) {
			fWriteError("Caught Exception in Actions: " + e);
	    }
		return 0;
	}//end of init


	public int action() throws Throwable {
	    try {
			//Connect
			fWriteLog("MSG: Starting action");
			if(!socket.isConnected()) {
				fWriteLog("MSG: Connecting");
				socket = connect(sHost, iPort);
			}
			InputStream inStream = socket.getInputStream();
			OutputStream outStream = socket.getOutputStream();

			//Send request
			fWriteLog("MSG: Starting fSendRequest");
			int iReturnCode = fSendRequest(inStream, outStream);
			fWriteLog("MSG: Completed fSendRequest");

			if(bReconnect) {
				fWriteLog("MSG: Disconnect & Reconnect");
				socket.close();
				socket = connect(sHost, iPort);
			}
	    }
	    catch(java.net.SocketException e) {
			fWriteError("java.net.SocketException: Connection reset");
			socket.close();
	    }
	    catch(Exception e) {
			fWriteError("Caught Exception in Actions: " + e);
			socket.close();
	    }
	    return 0;
	}//end of action


	public int end() throws Throwable {
	    try {
			socket.close();
	    }
	    catch(java.net.SocketException e) {
			fWriteError("java.net.SocketException: Connection reset");
	    }
	    catch(Exception e) {
			fWriteError("Caught Exception in Actions: " + e);
	    }
		return 0;
	}//end of end


	// Functions for writing logs
	public void fWriteLog(String sLog) {
	    if(logging) {
			lr.output_message(sLog);
	    }
	}
	public void fWriteError(String sError) {
	    lr.error_message(sError + lr.eval_string(" for IterationNo <IterationNo>, VuserID <VuserID>, Host <Host> at Time <Time> for the GroupName <GroupName>"));
	}
	// Function for getting n'th value from csv
	public String fGetValue(String sInput, int iColumn, String cDelimiter) {
	    String sTemp = null;
	    String sOutput = null;

	    String [] sArray = sInput.split(cDelimiter);
	    return sArray[iColumn - 1];
	}
	// Function for writing to output file
	public void fWriteFile(String sBuffer, String sFileName) {
	    try {
		//Create file 
		FileWriter fStream = new FileWriter(sFilePath + sFileName, true);
		BufferedWriter out = new BufferedWriter(fStream);
		out.write(sBuffer);
		out.newLine();
		out.close();
	    } catch (Exception e) {
			fWriteError("Error: " + e.getMessage());
	    }
	}
	public String fSessionString(int iLength) {
	    char[] chars = "abcdefghijklmnopqrstuvwxyzABSDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
	    Random r = new Random(System.currentTimeMillis());
	    char[] id = new char[iLength];
	    for (int i = 0;  i < iLength;  i++) {
			id[i] = chars[r.nextInt(chars.length)];
	    }
	    return new String(id);
	}


	//Custom functions that varies with script/data sent (for each application)
	//Socket tunneling Request
	public int fSendTunnelingRequest(InputStream inStream, OutputStream outStream) throws Throwable {
		//Interac
		String clientOutPrefix = new String(new char[] {0xFD});
		String clientOutSuffix = new String(new char[] {0x00, 0x00, 0x00, 0x00});
		String buf1 = clientOutPrefix + "FEP@" + lr.eval_string("<Node>") + clientOutSuffix;

		//Convert to bytes & write to output log
		byte[] byteBuffer = buf1.getBytes();
		fWriteLog("MSG: Tunneling Request " + buf1);

	    try {
			outStream.write(byteBuffer);
	    } catch (Exception e) {
			fWriteError("Caught Exception in fSendTunnelingRequest: " + e);
			return -1;
	    }
	    return 0;
	}

	//Send actual Request
	public int fSendRequest(InputStream inSSLStream, OutputStream outSSLStream) throws Throwable {
	    /*
	    * EDIT BELOW SECTION ONLY
	    */

	    String buf2 = lr.eval_string("<Request>");
	    String sTransactionName = "XXXXXX";
	  
		String sSubTransactionName = sTransactionName + "_Port_" + lr.eval_int("<Node>") % 10;

	    /*
	    * DO NOT EDIT BELOW SECTION
	    */

		//String sTemp = buf2.replaceFirst("," + fGetValue(buf2, iNodePosition, ",") + ",", "," + lr.eval_string("<Node>") + ",");
	    String sTemp = buf2.replaceFirst("," + fGetValue(buf2, iNodePosition, ",") + "," + fGetValue(buf2, iNodePosition + 1, ",") + ",", "," + lr.eval_string("<Node>") + "," + lr.eval_string("<Register>") + ",");
		sTemp = sTemp.replaceFirst("," + fGetValue(sTemp, iNodePosition + 9, ",") + ",", "," + lr.eval_string("<STAN>") + ",");
		String sBlobSeparator = new String(new char[] {0x1C});
		sTemp = sTemp.replaceFirst("~1c", sBlobSeparator);
		
		String sLength = String.format("%04d", sTemp.length());
		sTemp = sLength + sTemp;
	    //Convert to Bytes
	    byte byteOut[] = sTemp.getBytes();
	    byte byteIn[] = new byte[4];

	    try {
			while(socket.isConnected()) {
			    fWriteLog("MSG: Out Request: " + sTemp);
			    lr.start_transaction("SendReceive");

			    outSSLStream.write(byteOut);
			    fWriteLog("MSG: Out Request success");

			    //Read length of response data
			    inSSLStream.read(byteIn,0,4);
			    int clientInLength = Integer.valueOf(new String(byteIn));
			    fWriteLog("MSG: In Length: " + clientInLength);

			    byte byteInData[] = new byte[clientInLength];
			    int iRead = inSSLStream.read(byteInData);

				Double iTransTime = lr.get_transaction_duration("SendReceive");
				lr.end_transaction("SendReceive", lr.AUTO);

				if(iRead == clientInLength) {
					String sResponse = new String(byteInData, "UTF-8");
					if((sResponse.indexOf("Invalid Transaction Type") == -1) && ((!bDecline) || (sResponse.indexOf("DECLINE") == -1))) {
					    //Include logic for APPROVAL/DECLINE in response???
					 	//lr.end_sub_transaction(sSubTransactionName, lr.PASS);
					 	
					 	String sTempResult_string = new String(byteInData);
					    if(sTempResult_string.contains("APPROVAL"))
					    {
					    	//lr.set_transaction(sSubTransactionName + "_Approved", iTransTime, lr.FAIL);
					    }
					    else if(sTempResult_string.contains("OFFLINE"))
					    {
					    	lr.set_transaction(sSubTransactionName + "_Offline", iTransTime, lr.FAIL);
					    }
					    else
					    {
					    	lr.set_transaction(sSubTransactionName + "_Others", iTransTime, lr.AUTO);
					    }
					    
				    	lr.set_transaction(sSubTransactionName, iTransTime, lr.PASS);
				    	lr.set_transaction(sTransactionName, iTransTime, lr.PASS);
				    	
				    	fWriteLog("MSG: In Data&colon; " + new String(byteInData));
				    	Double iBankTime = Double.parseDouble(fGetValue(new String(byteInData),63,",")) / 1000;
				    	lr.set_transaction(sSubTransactionName + "_XXX", iBankTime, lr.PASS);
				    	lr.set_transaction(sTransactionName + "_XXX", iBankTime, lr.PASS);
				    	lr.set_transaction(sSubTransactionName + "_XXX", iTransTime - iBankTime, lr.PASS);
				    	lr.set_transaction(sTransactionName + "_XXX", iTransTime - iBankTime, lr.PASS);
				    	fWriteLog("MSG: TotalRT: " + iTransTime + " XXX: " + iBankTime + " RTS: " + (iTransTime - iBankTime));

				    	Double iThinkTime = lr.eval_int("<ThinkTime>") - iTransTime;
				    	if(iThinkTime > 0)
				    		lr.think_time(iThinkTime.intValue());

					    if(filtering) {
							fWriteFile(buf2, "Good.txt");
					    }
					    break;
					}
			    }
		    	lr.set_transaction(sSubTransactionName, iTransTime, lr.FAIL);
		    	lr.set_transaction(sTransactionName, iTransTime, lr.FAIL);
		    	lr.think_time(10);
			    if(filtering)
					fWriteFile(buf2, "Bad.txt");
			    return -1;
			}
	    } catch (Exception e) {
			lr.end_transaction("SendReceive", lr.FAIL);
			fWriteError("Caught Exception in fSendRequest: " + e);
			socket.close();
	    }

	    return 0;
	}

	public Socket connect(String sHost, int iPort) throws Throwable {
		Socket returnSocket = null;
	    try {
			Socket tcpsocket = new Socket(sHost, iPort);
			InputStream inStream = tcpsocket.getInputStream();
			OutputStream outStream = tcpsocket.getOutputStream();
	
			//Send socket tunneling request
			int iReturnCode = fSendTunnelingRequest(inStream, outStream);
	
			//if priming request failed, restart Action
			if(iReturnCode != 0) {
			    fWriteError("Socket priming request failed");
			    lr.exit(lr.EXIT_ITERATION_AND_CONTINUE, lr.FAIL);
			}
			
			//Convert socket to SSL
			if(bSSL) {
				SSLContext ctx = SSLContext.getDefault();
				SSLSocketFactory factory = ctx.getSocketFactory();
				SSLSocket sslSocket = (SSLSocket)factory.createSocket(tcpsocket, sHost, iPort, true);
				String protocol[] = {"SSLv3","TLSv1"};//"SSLv3","TLSv1","TLSv1.1","TLSv1.2"
				sslSocket.setEnabledProtocols(protocol);
				sslSocket.setUseClientMode(true);
				sslSocket.setSoTimeout(iSocketTimeout * 1000);
				sslSocket.setNeedClientAuth(false);
		
				//Start SSL Handshake & create read/write streams
				fWriteLog("MSG: SSL Handshake starting");
				sslSocket.startHandshake();
				fWriteLog("MSG: SSL Handshake completed");
				returnSocket = sslSocket;
			}
			else
				returnSocket = tcpsocket;
		}
	    catch(java.net.SocketException e) {
			fWriteError("java.net.SocketException: Connection reset");
	    }
	    catch(Exception e) {
			fWriteError("Caught Exception in Actions: " + e);
	    }
		return returnSocket;
	} //end of connect
}

 

0 Likes
Highlighted
Acclaimed Contributor.
Acclaimed Contributor.

Re: Why Java VUser Scripts takes 100 % CPU in Load Generators for just 20 to 30 concurrent users

Few things to consider after a quick glance of your snip.

- Remove file handling operations which are in general cosly when run in a multi user environment.

- check the ssl connectivity. the timeouts and general connectivity. may be try disabling ssl and verify.

- switch running vuser as thread / process

It is difficult to suggest more without executing the script.

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.