Асинхронное взаимодействие Java Execution Framework Сравнение производительности Асинхронные вызовы в Glassfish Кислин Григорий
АСИНХРОННЫЕ ВЫЗОВЫ
Execution framework (java.util.concurrent) A task that returns a result and may throw an exception public interface Callable { V call() throws Exception; } public interface Runnable { Future represents the result of an asynchronous computation public interface Future { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException } public interface ScheduledFuture extends Delayed, Future { }
Execution framework (java.util.concurrent) ScheduledExecutorService : Executors.newScheduledThreadPool(int corePoolSize) newSingleThreadScheduledExecutor() ExecutorService: Executors.newCachedThreadPool() Executors.newSingleThreadExecutor Executors.newFixedThreadPool(int nThreads) BlockingQueue Implementation: LinkedBlockingQueue public interface CompletionService { Future submit(Callable task); Future take() throws InterruptedException; Future poll(); … } Implementation: ExecutorCompletionService(Executor executor)
Сравнение производительности Cинхронный сервлет (веб-сервис), ожидание 10 сек Сервлет исполняется 10 сек и удерживает все это время свой поток а в пуле 200 потоков, то нагрузка 200/10 сек = 20 запросов/ сек.
Сравнение производительности Асинхронный сервлет, ожидание10 сек (GlassFish v3, ScheduledExecutorService) Нагрузка- примерно 500 запросов/сек. (возможно ограничение на стороне 1 клиента) При длительности в 10 с и 200 потоках в пуле – выигрыш в 25 раз
АСИНХРОННЫЕЙ КЛИЕНТ В GLASSFISH
Glassfish асинхронный клиент веб-сервиса wsimport wsimport -b @ResponseWrapper(localName =Result,.. public Response execute(); public Future = "asyncHandler", targetNamespace = "") AsyncHandler asyncHandler);
Glassfish асинхронный клиент веб-сервиса Пример public interface Response extends Future { Map getContext(); } public interface AsyncHandler { void handleResponse(Response res); } final AsyncHandler handler = new AsyncHandler () public void handleResponse(Response res) { res.get() …. }
Glassfish асинхронный клиент веб-сервиса + есть в Metro 2.1 (Glassfish 2) + достаточно прост и удобен в реализации + генерируется из wsdl, возможно выборочное применение к разным методам.
Glassfish асинхронный клиент Пример public void execute() no exceptions
Glassfish асинхронный клиент + есть в Metro 2.1 (Glassfish 2) очень прост в использовании (просто возвращается акноледж- статус код 202, который обрабатывается jax-ws) - при необходимости получения результата или Exception необходима реализация callback и его обработки на стороне клиента (передавать url для callback можно в через WS-addressing), либо result polling.
Glassfish v3 асинхронный клиент public interface IAsyncEJB public Future execute() throws Exception; } public class AsyncEJB implements IAsyncEJB public Future execute() throws Exception{... return new AsyncResult (res); }
Glassfish v3 асинхронный клиент EJB - появились только в EJB 3.1 (Glassfish v3) -недоступны как веб-сервисы -неудобны в использовании (возвращается удаленная реализация Future) -при нагрузке работали очень задумчиво
АСИНХРОННАЯ РЕАЛИЗАЦИЯ СЕРВИСА В GLASSFISH
Glassfish низкоуровневая реализация public class AsyncWebService implements AsyncProvider { public void invoke(final Source request, final AsyncProviderCallback callback, final WebServiceContext ctx) { Executor.submit(new Callable () public Void call() throws Exception { try{ …. // parse request, form result callback.send(result); return null; } catch (Exception e){ callback.sendError(e);
Glassfish низкоуровневая реализация веб-сервиса + появились в Metro 2.1 (Glassfish v2) + большая гибкость в использовании - длительность разработки (необходимо реализовать единственный метод invoke - самостоятельно маршалить-унмаршалить запрос-ответ, определять имя операции, делать web.xml и sun-jaxws.xml, отсутствует в GF консоли)
Glassfish v3 асинхронные = {"/async"}, asyncSupported = true) public class AsyncServlet extends HttpServlet { private static final ScheduledExecutorService executor = protected void doGet(HttpServletRequest req, HttpServletResponse res) { final AsyncContext ac = req.startAsync(); Executor.submit(new Callable () public Void call() throws Exception { HttpServletResponse res = (HttpServletResponse) ac.getResponse(); …. ac.complete(); return null; }
Glassfish v3 асинхронные сервлеты + легко писать, удобно использовать - появились только в Servlets 3.0 (Glassfish v3) - в основном взаимодействие происходит не через сервлеты