Asynchronous-IO vs Asynchronous-Request Processing у Java

У цій статті я намагаюся пояснити різницю між обробкою Async-IO та Async-Request у запиті HTTP у світі Java.

У світі до Java 1.4 , Java надає API для надсилання / отримання даних через мережевий сокет. Оригінальні автори JVM відобразили цю поведінку API на API сокета ОС, майже один на один.

Отже, яка поведінка сокета ОС? ОС забезпечує API програмування сокетів, який має виклик блокування надсилання / відновлення . Оскільки java - це лише процес, який працює поверх Linux (OS), отже, ця програма Java повинна використовувати цей блокуючий api, наданий ОС.

Світ був щасливий, і розробники Java почали використовувати API для надсилання / отримання даних. Але вони повинні були тримати один потік Java для кожного сокета (клієнта).

Кожен писав власний смак HTTP-серверів. Обмін кодами ставав важким, світ Java вимагав стандартизації.

Входить в специфікацію сервлета Java.

Перш ніж рухатися далі, давайте визначимо кілька термінів:

Розробник Java Server : Люди, які використовують api сокет java і реалізують протокол http, як tomcat.

java Розробник додатків: Люди, які створюють діловий додаток поверх tomcat.

ПОВЕРТАЮТЬСЯ ЗАРАЗ

Як тільки специфікація сервлета Java увійшла у світ, він сказав:

Шановні розробники Java-серверів, надайте метод, як показано нижче:

doGet(inputReq, OutPutRes)

так що розробник програм Java може реалізувати їх doGetі написати свою бізнес-логіку. Як тільки “розробник додатків” хоче надіслати response, він може зателефонуватиOutPutRes.write().

Слід зазначити: оскільки soi api блокує, отже, OutPutRes.write () також блокує. Крім того, додатковим обмеженням було те, що об'єкт відповіді фіксується при виході методу doGet .

Через ці обмеження людям довелося використовувати один потік для обробки одного запиту.

Минав час, і Інтернет заволодів світом. одна нитка на запит почала відображати обмеження.

Проблема 1:

Модель потоку на запит не вдається, коли під час обробки кожного запиту є великі паузи.

Наприклад: отримання даних із підслуги займає багато часу.

У такій ситуації потік в основному сидить без діла, і JVM може легко закінчити нитку.

Проблема 2:

Стало ще гірше з постійним з’єднанням http1.1. Як і при постійному з'єднанні, базове TCP-з'єднання буде збережене, і сервер повинен заблокувати один потік для кожного з'єднання.

Але чому сервер повинен блокувати один потік на підключення?

Оскільки ОС забезпечує блокувальний сокет Recv api, jvm повинен викликати метод блокування OSv, який блокує ОС, щоб прослуховувати більше запитів про те саме з'єднання tcp від клієнта.

Світ вимагав рішення!

Перше рішення вийшло від творця JVM. Вони ввели NIO ( ASYNC-IO ). Nio - це неблокуючий API для надсилання / отримання даних через сокет.

Деякий фон:ОС поряд із блокуючим сокетом api також надає неблокувальну версію сокетного API.

Але як ОС забезпечує це .. Чи він розгалужує потік всередині, і цей потік блокується ???

ВІДПОВІДІ немає - ОС вказує апаратному забезпеченню перервати, коли є дані для читання або запису.

NIO дозволив « розробнику серверів Java»вирішити проблему 2 блокування одного потоку на TCP-з'єднання . Оскільки NIO є постійним з'єднанням HTTP, потік не вимагає його блокування під час виклику recv . Натомість він тепер може обробляти його лише тоді, коли є дані, які підлягають обробці. Це дозволило одному потоку контролювати / обробляти велику кількість постійних з'єднань.

Друге рішення вийшло із специфікацій сервлету. Сервлет Spec отримав оновлення, і вони запровадили підтримку асинхронізації (обробка запитів асинхронізації).

AsyncContext acontext = req.startAsync();
ВАЖЛИВО: Це оновлення зняло обмеження фіксації об'єкта відповіді при завершенні методу doGet .

Це дозволило “ Розробнику програм Java” вирішити проблему 1, розвантаживши роботу до фонових потоків. Тепер замість того, щоб потік очікував під час тривалої паузи, його можна використовувати для обробки інших запитів.

ВИСНОВОК:

Async-IO в Java в основному використовує неблокувальну версію API сокета ОС.

Асинхронна обробка запитів - це, в основному, стандартизація специфікацій сервлету, як обробляти більше запитів одним потоком.

ЛІТЕРАТУРА:

//www.scottklement.com/rpg/socktut/tutorial.pdf

//stackoverflow.com/questions/15217524/ what-is-the-difference-be Between-thread-per-connection-vs-thread-per-request

Мотивація статті: Командне навчання / Обмін знаннями