Dear Users,
I have the following problem:
I use Tomcat 5.5.7 on port 80.
There is no problem with 1-2 queries / 10 secs.
When I use it with more users (5-6 queries / sec), the frontend working
for e.g. 30 minutes on CPU load with 1-2 %, and after it it go up to 60-90%.
The queries is not to increasses in this time (e.g. in the last test it
was 3 queries / 5 sec in the critical point). In this critical time the
backends CPU usages are max. 10-20%.
On the frontend in the Tomcat manager there are many threads with
'service status' with long time (e.g.: 586 sec ).
After 10 minutes in the catalina.out there are the bean.search time i
sincreasses over 10-40 sec, and after some minutes there are many
messages with 'NullPointerException'.
I rewrite the jsp pages to the servlets.
There is my source of Search.java, there is a 'google' paginating. The
source code is optimized (minimal object creating, sb.append, etc.):
package org.nutch;
Beginning of java code
------------------------------------------------------------------------------
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import org.apache.velocity.exception.*;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.servlet.VelocityServlet;
import net.nutch.html.Entities;
import java.util.*;
import net.nutch.searcher.*;
import net.nutch.plugin.*;
import java.io.*;
import java.net.*;
public class Search extends VelocityServlet {
private NutchBean bean;
public void init() throws ServletException {
try {
bean = NutchBean.get(this.getServletContext());
} catch (IOException e) {
throw new ServletException(e);
}
}
private static final String getStringParameter(String name, String
charset, HttpServletRequest req) {
String value = req.getParameter(name);
if (value == null) {
value = "";
}
try {
value = new String( value.getBytes("8859_1"), charset );
} catch (Exception e) {;}
return value;
}
public Template handleRequest( HttpServletRequest request,
HttpServletResponse response,
Context par_tartalom ) throws java.io.IOException, ServletException {
Template loc_template = null;
if (bean == null) { return loc_template; }
int start = 0; // first hit to display
String startString = request.getParameter("start");
if (startString != null) {
start = Integer.parseInt(startString);
if (start < 0) {
start = 0;
}
}
int hitsPerPage = 10; // number of hits to display
String hitsString = request.getParameter("hitsPerPage");
if (hitsString != null) {
hitsPerPage = Integer.parseInt(hitsString);
}
// get the character encoding to use when interpreting request
values
String charset = request.getParameter("charset");
if (charset == null) {
charset = "UTF8";
}
// get query from request
String queryString = getStringParameter("query", charset, request);
try {
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer();
StringBuffer sb3 = new StringBuffer();
// Query string for html
String htmlQueryString = Entities.encode(queryString);
String htmlQueryStringISO = URLEncoder.encode(queryString,
"ISO-8859-2");
String htmlQueryStringUTF = URLEncoder.encode(queryString,
"UTF8");
// Get more parameters
if (hitsPerPage >100) { // No more hitsPerPage than 100
hitsPerPage = 10;
}
int hitsPerSite = 2; // max hits per site
String hitsPerSiteString = request.getParameter("hitsPerSite");
if (hitsPerSiteString != null) {
hitsPerSite = Integer.parseInt(hitsPerSiteString);
}
Query query = Query.parse(queryString);
int hitsLength = 0;
int end = 0;
int length = 0;
log(sb.append("Query:
").append(request.getRemoteAddr()).append(" -
").append(queryString).toString());
long startTime = System.currentTimeMillis();
Hits hits = bean.search(query, start + hitsPerPage,
hitsPerSite);
hitsLength = (int)hits.getTotal();
int length2 = hits.getLength();
par_tartalom.put("TIME",
String.valueOf((System.currentTimeMillis()-startTime) / 1000.0) );
if (length2 <= start) { // If after 'start' there are not hits
start = length2 - (length2 % hitsPerPage);
if (length2 == start) {
start = start - hitsPerPage;
if (start < 0) start = 0;
}
end = length2;
} else { // If after 'start' there are some hits
end = length2 < start+hitsPerPage ? length2 :
start+hitsPerPage;
}
length = end-start;
Hit[] show = hits.getHits(start, end-start);
HitDetails[] details = bean.getDetails(show);
String[] summaries = bean.getSummary(details, query);
sb.setLength(0);
log(sb.append("Query:
").append(request.getRemoteAddr()).append(" -
").append(queryString).append(" - Total hits:
").append(hits.getTotal()).append(" - Time:
").append(System.currentTimeMillis()-startTime).toString());
par_tartalom.put("START", new Long((end==0)?0:(start+1)) );
// Start of hits
par_tartalom.put("END", new Long(end)); // End of hits
par_tartalom.put("CNT", new Long(hits.getTotal())); // Count
of hits
par_tartalom.put("QRY", htmlQueryString); // UTF8
par_tartalom.put("QRY2", htmlQueryStringISO); // ISO charset
// ******************************************************
// List Hits
// ******************************************************
sb.setLength(0);
sb2.setLength(0);
sb3.setLength(0);
sb3.append("?idx=");
Hit hit = null;
HitDetails detail = null;
String title = null;
String url = null;
String summary = null;
for (int i = 0, j; i < length; i++) { // display the hits
hit = show[i];
detail = details[i];
title = detail.getValue("title");
url = detail.getValue("url");
summary = summaries[i];
sb3.setLength(5);
sb3.append( hit.getIndexNo() ).append("&id=").append(
hit.getIndexDocNo() );
if (title == null || title.equals("")) { // use url for
docs w/o title
title = url;
}
... Same with search.jsp ...
}
if (length2 <= start + hitsPerPage && hitsLength != 0) { //
If lower tahn hitsPerPage
sb.append("<span style=\"FONT-WEIGHT: bold; color:
black;\">This is the last page.</span><br><br>");
hitsLength = length2; // paginating length
}
par_tartalom.put("LIST", sb.toString());
// ******************************************************
// Paginating
// ******************************************************
int pageNumber = 0;
sb.setLength(0);
sb2.setLength(0);
sb2.append("&hitsPerPage=");
sb2.append(hitsPerPage);
sb3.setLength(0);
sb3.append("<a
href=\"Keres?query=").append(htmlQueryStringUTF).append("&start=");
// Prev (<<)
sb.append("<td width=60 class=pages align=right>");
if (start>0) {
long prevStart = start-hitsPerPage;
prevStart = prevStart > 0 ? prevStart : 0;
sb.append(sb3); // query
sb.append(prevStart); // start
sb.append(sb2); // others
sb.append("\" class=pages><font class=arrow><<</font> <<
</a>");
}
sb.append("</td><td class=pages width=250 align=center>");
if (hitsLength > hitsPerPage ) { // If there are more pages
if (start >= 9 * hitsPerPage) { // from page 10 (from 90)
int startPageNumber = start-(4 * hitsPerPage);
if (startPageNumber < 0) startPageNumber = 0;
pageNumber = (startPageNumber-1) / hitsPerPage+1;
for (int i = startPageNumber; i < hitsLength; i = i
+ hitsPerPage) {
pageNumber++;
if (start == i) {
sb.append("<font class=active_nr><b>");
sb.append(pageNumber);
sb.append("</b> </font>");
} else {
sb.append(sb3);// query
sb.append(i); // start
sb.append(sb2); // others
sb.append("\" class=inactive_nr>");
sb.append(pageNumber);
sb.append("</a> ");
}
if (i >= startPageNumber+8*hitsPerPage) {
break;
}
}
} else { // more than 9 pages
for (int i = 0; i < hitsLength; i = i + hitsPerPage) {
pageNumber++;
if (start == i) {
sb.append("<font class=active_nr><b>");
sb.append(pageNumber);
sb.append("</b> </font>");
} else {
sb.append(sb3);// query
sb.append(i); // start
sb.append(sb2); // others
sb.append("\" class=inactive_nr>");
sb.append(pageNumber);
sb.append("</a> ");
}
if (pageNumber >= 10) {
break;
}
}
}
}
sb.append("</td><td width=100 class=pages>");
// next (>>)
if (hitsLength > start+hitsPerPage) {
if (end <hitsLength) {
sb.append(sb3); // query
sb.append(end); // start
sb.append(sb2); // others
sb.append("\" class=pages> >> <font
class=arrow>>></font></a>");
}
}
sb.append("</td>");
par_tartalom.put("PAGES", sb.toString());
loc_template = Velocity.getTemplate("search.vm");
// } catch (ArrayIndexOutOfBoundsException ae){
// log(request.getRemoteAddr()+" - forwarding - "+queryString);
// }
} catch (Exception e) {
log(e.toString()+" - " + request.getRemoteAddr()+" -
"+queryString);
// throw new ServletException(e);
}
return loc_template;
}
}
------------------------------------------------------------------------------
End of java code.
Have you any idea what is the possible problem source?
Best Regards,
Ferenc