I have and application deployed in tomcat and have a lot of thread busy with no release more than 700 thead like this.
I captured the thead dump the file is on ufile.io/8zz1t , and i use fastthread.io to read. Can you check if you see the problem, I see that the inflater have the thread with cpu consume.
S 188063346 ms 0 KB 0 KB 10.162.3.36 172.30.100.163 POST /ChiperService/rest/cs/Descifrar HTTP/1.1
S 280064346 ms 0 KB 0 KB 10.162.3.36 172.30.100.163 POST /ChiperService/rest/cs/Descifrar HTTP/1.1
S 185431144 ms 0 KB 0 KB 10.162.38.201 172.30.100.163 POST /ChiperService/rest/cs/Descifrar HTTP/1.1
S 267094596 ms 0 KB 0 KB 10.162.3.36 172.30.100.163 POST /ChiperService/rest/cs/Descifrar HTTP/1.1
S 261396699 ms 0 KB 0 KB 10.162.3.36 172.30.100.163 POST /ChiperService/rest/cs/Descifrar HTTP/1.1
What part of this code can cause the thread busy? I don'´t know if the deflater or inflater have to be close.
In the tomcat manager for the app ChiperService there are not active sessions.
Please help the server is crashing almost 5 time in the day becouse the thead busy and the high cpu consume.
This is the rest service:
package ChiperServicePkg;
import com.sun.jersey.api.core.ResourceConfig;
import java.io.IOException;
import javax.ws.rs.core.Context;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import principal.allus.com.co.SBCCypherModuleMain;
/**
* REST Web Service
*
* @author 1017200731
*/
@Path("/cs")
public class CiphersResource {
@Context ResourceConfig Config;
/**
* Creates a new instance of CiphersResource
*/
public CiphersResource() {
}
/**
*
* @param UUI
* @return
* @throws Exception
*/
@POST
@Path("Cifrar")
public String Cifrar(String UUI) throws Exception
{
String Key = (String) Config.getProperty("KeyCipher");
String dataEncrypted = null;
try
{
dataEncrypted= SBCCypherModuleMain.cifrar(UUI,Key );
}
catch(Exception ex)
{
if (ex instanceof IOException){
throw new IOException(ex);
}
else{
throw ex;
}
}
return dataEncrypted;
}
/**
*
* @param dataEncrypted
* @return
* @throws Exception
*/
@POST
@Path("Descifrar")
public Response Descifrar(String dataEncrypted) throws Exception
{
String Key = (String) Config.getProperty("KeyCipher");
String dataDecrypted= "";
try
{
dataDecrypted= SBCCypherModuleMain.descifrar(dataEncrypted, Key);
}
catch(Exception ex)
{
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(ex.getMessage()).type("text/plain").build();
}
return Response.ok(dataDecrypted).build();
}
/**
* Sub-resource locator method for {id}
*/
@Path("{id}")
public CipherResource getCipherResource(@PathParam("id") String id) {
return CipherResource.getInstance(id);
}
}
The method Descifrar call a jar provide by the client and with a decompiler I can extract the following code:
public static String descifrar(String bytes, String llave)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, Exception
{
byte[] vector = null;
String retorno = "";
retorno = SBCCypherModuleCompress.descomprimir(SBCCypherModuleCypher.descifrar(bytes, llave.substring(0, 16)));
return retorno;
}
The SBCCypherModuleCompress class is the following:
public class SBCCypherModuleCompress
{
public static String comprimir(byte[] data)
throws IOException, Exception
{
BASE64Encoder b64e = new BASE64Encoder();
byte[] output = null;
String salida = "";
Deflater deflater = new Deflater();
deflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
deflater.finish();
byte[] buffer = new byte['?'];
while (!deflater.finished())
{
int count = deflater.deflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
output = outputStream.toByteArray();
salida = b64e.encode(output);
return salida;
}
public static String descomprimir(String data)
throws DataFormatException, IOException, Exception
{
BASE64Encoder b64e = new BASE64Encoder();
BASE64Decoder b64d = new BASE64Decoder();
byte[] output = null;
String salida = "";
byte[] datad = null;
datad = b64d.decodeBuffer(data);
Inflater inflater = new Inflater();
inflater.setInput(datad);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(datad.length);
byte[] buffer = new byte['?'];
while (!inflater.finished())
{
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
output = outputStream.toByteArray();
salida = b64e.encode(output);
return new String(output);
}
}
The SBCCypherModuleCypher class is the following:
public class SBCCypherModuleCypher
{
public static String cifrar(String vector, String llaveSimetrica)
throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, Exception
{
BASE64Encoder b64e = new BASE64Encoder();
BASE64Decoder b64d = new BASE64Decoder();
byte[] datad = null;
String salida = "";
datad = b64d.decodeBuffer(vector);
SecretKeySpec key = new SecretKeySpec(llaveSimetrica.getBytes(), "AES");
byte[] campoCifrado = null;
Cipher cipher = Cipher.getInstance("AES");
cipher.init(1, key);
campoCifrado = cipher.doFinal(datad);
salida = b64e.encode(campoCifrado);
return salida;
}
public static String descifrar(String vector, String llaveSimetrica)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, Exception
{
BASE64Encoder b64e = new BASE64Encoder();
BASE64Decoder b64d = new BASE64Decoder();
byte[] datad = null;
String salida = "";
datad = b64d.decodeBuffer(vector);
SecretKeySpec key = new SecretKeySpec(llaveSimetrica.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(2, key);
byte[] datosDecifrados = cipher.doFinal(datad);
salida = b64e.encode(datosDecifrados);
return salida;
}
}
All your threads are in inflater.inflate(buffer)
in SBCCypherModuleCompress.java, line 92.
But why have you written new byte['?']
? That's in the following code:
byte[] buffer = new byte['?'];
while (!deflater.finished())
{
int count = deflater.deflate(buffer);
outputStream.write(buffer, 0, count);
}
and also in the following code:
byte[] buffer = new byte['?'];
while (!inflater.finished())
{
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
new byte['?']
makes no sense.
new byte[2048]
or perhaps new byte[8192]
would be better instead of new byte['?']
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With