Для начала я проверил обсуждения по этому вопросу и не смог найти ответ на свою проблему, поэтому я открываю этот вопрос.
Я настроил веб-сервис, используя рестлет 2.0.15. Реализация только для сервера. Соединения с сервером осуществляются через веб-страницу, поэтому я не использовал ClientResource.
Большинство ответов на проблему исчерпания пула потоков предполагали включение
#exhaust + #release
Процесс веб-службы можно описать как одну функцию. Получать GET запросов с веб-страницы, запрашивать базу данных, оформлять результаты в XML и возвращать окончательное представление. Я использовал фильтр, чтобы переопределить beforeHandle и afterHandle.
Код для создания компонента:
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8188);
component.getContext().getParameters().add("maxThreads", "512");
component.getContext().getParameters().add("minThreads", "100");
component.getContext().getParameters().add("lowThreads", "145");
component.getContext().getParameters().add("maxQueued", "100");
component.getContext().getParameters().add("maxTotalConnections", "100");
component.getContext().getParameters().add("maxIoIdleTimeMs", "100");
component.getDefaultHost().attach("/orcamento2013", new ServerApp());
component.start();
Параметры являются результатом обсуждения на этом форуме и модификации с моей стороны в попытке максимизировать эффективность.
Что касается приложения, код выглядит следующим образом:
@Override
public synchronized Restlet createInboundRoot() {
// Create a router Restlet that routes each call to a
// new instance of HelloWorldResource.
Router router = new Router(getContext());
// Defines only one route
router.attach("/{taxes}", ServerImpl.class);
//router.attach("/acores/{taxes}", ServerImplAcores.class);
System.out.println(router.getRoutes().size());
OriginFilter originFilter = new OriginFilter(getContext());
originFilter.setNext(router);
return originFilter;
}
Я также использовал пример фильтра, найденный в обсуждении здесь. Реализация следующая:
public OriginFilter(Context context) {
super(context);
}
@Override
protected int beforeHandle(Request request, Response response) {
if (Method.OPTIONS.equals(request.getMethod())) {
Form requestHeaders = (Form) request.getAttributes().get("org.restlet.http.headers");
String origin = requestHeaders.getFirstValue("Origin", true);
Form responseHeaders = (Form) response.getAttributes().get("org.restlet.http.headers");
if (responseHeaders == null) {
responseHeaders = new Form();
response.getAttributes().put("org.restlet.http.headers", responseHeaders);
responseHeaders.add("Access-Control-Allow-Origin", origin);
responseHeaders.add("Access-Control-Allow-Methods", "GET,POST,DELETE");
responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
responseHeaders.add("Access-Control-Allow-Credentials", "true");
response.setEntity(new EmptyRepresentation());
return SKIP;
}
}
return super.beforeHandle(request, response);
}
@Override
protected void afterHandle(Request request, Response response) {
if (!Method.OPTIONS.equals(request.getMethod())) {
Form requestHeaders = (Form) request.getAttributes().get("org.restlet.http.headers");
String origin = requestHeaders.getFirstValue("Origin", true);
Form responseHeaders = (Form) response.getAttributes().get("org.restlet.http.headers");
if (responseHeaders == null) {
responseHeaders = new Form();
response.getAttributes().put("org.restlet.http.headers", responseHeaders);
responseHeaders.add("Access-Control-Allow-Origin", origin);
responseHeaders.add("Access-Control-Allow-Methods", "GET,POST,DELETE"); //
responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
responseHeaders.add("Access-Control-Allow-Credentials", "true");
}
}
super.afterHandle(request, response);
Representation requestRepresentation = request.getEntity();
if (requestRepresentation != null) {
try {
requestRepresentation.exhaust();
} catch (IOException e) {
// handle exception
}
requestRepresentation.release();
}
Representation responseRepresentation = response.getEntity();
if(responseRepresentation != null) {
try {
responseRepresentation.exhaust();
} catch (IOException ex) {
Logger.getLogger(OriginFilter.class.getName()).log(Level.SEVERE, null, ex);
} finally {
}
}
}
У responseRepresentation нет #release method, потому что он приводит к сбою процессов, выдающих предупреждение WARNING: A response with a 200 (Ok) status should have an entity (...)
Код реализации ServerResource следующий:
public class ServerImpl extends ServerResource {
String itemName;
@Override
protected void doInit() throws ResourceException {
this.itemName = (String) getRequest().getAttributes().get("taxes");
}
@Get("xml")
public Representation makeItWork() throws SAXException, IOException {
DomRepresentation representation = new DomRepresentation(MediaType.TEXT_XML);
DAL dal = new DAL();
String ip = getRequest().getCurrent().getClientInfo().getAddress();
System.out.println(itemName);
double tax = Double.parseDouble(itemName);
Document myXML = Auxiliar.getMyXML(tax, dal, ip);
myXML.normalizeDocument();
representation.setDocument(myXML);
return representation;
}
@Override
protected void doRelease() throws ResourceException {
super.doRelease();
}
}
Я пробовал решения, представленные в других темах, но ни одно из них не работает. Во-первых, не похоже, что пул потоков дополнен параметрами, установленными как warnings state that the thread pool available is 10. Как упоминалось ранее, увеличение значения maxThreads только отсрочивает результат.
Example: INFO: Worker service tasks: 0 queued, 10 active, 17 completed, 27 scheduled.
Может быть какая-то ошибка, связанная с Restlet version, но я скачал стабильную версию, чтобы убедиться, что это не проблема. Веб-служба обрабатывает около 5000 запросов в день, что немного.Примечание: вставка из #release method либо в ServerResource or OriginFilter возвращает ошибку, и упомянутое предупреждение ("WARNING: A response with a 200 (Ok) status should have an entity (...)")
Пожалуйста, направляйте. Спасибо!