|
|
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
jetty 9 spring 4 есть такой контроллер : когда context.setTimeout(3000); время выставлено больше чем суммарное время работы в треде все ок! клиент видит 10 записей . стоит выставить его меньше и начинается : в страницу попадает непонятно сколько записей ....а в логе на сервере Код: java 1. 2. 3. 4. 5. ловится Код: java 1. 2. 3. 4. 5. 6. вместо одного ... если убрать Код: java 1. 2. 3. 4. 5. то Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. а бывает что и всякие интересные ошибки самого спринга Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 18:17 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Во-первых асинхронная обработка в Servlet API появилась для того, чтобы не работать с потокам там, где может быть череповато. Поэтому непонятно, что делает new Thread() в вашем коде. Во-вторых, асинхронная обработка должна быть или диспетчеризирована запрос или явно завершена . В-третьих, HTTP предусматривает три значения тайм-аутов: 1. До получения строки запроса - секунды; 2. До получения всего заголовка - (две-три) минуты; 3. При чтении тела запроса или записи ответа - десять-пятнадцать минут. С какого перепугу выставлены отбалдянские три секунды - совершенно непонятно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 18:47 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovВо-первых асинхронная обработка в Servlet API появилась для того, чтобы не работать с потокам там, где может быть череповато. Поэтому непонятно, что делает new Thread() в вашем коде. Во-вторых, асинхронная обработка должна быть или диспетчеризирована запрос или явно завершена . В-третьих, HTTP предусматривает три значения тайм-аутов: 1. До получения строки запроса - секунды; 2. До получения всего заголовка - (две-три) минуты; 3. При чтении тела запроса или записи ответа - десять-пятнадцать минут. С какого перепугу выставлены отбалдянские три секунды - совершенно непонятно. Аммм... ну давайте Thread вынесу в отдельный класс ... в нем еще создам очередь в которую буду класть AsyncContext/ AsyncListener - добавил для наглядности ... вывод такой : AsyncListener Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 18:56 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum1 https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html#start(java.lang.Runnable) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 19:11 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
0FD, у меня сложилось впечатление - что гугл хром посылает повторные запросы .... может быть в это же соединение ... поставил бряку обновил страницу в браузере и ловлю несколько точек ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 19:25 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
У вас кардинальное непонимание что такое асинхронность в сервлетах. Начнём по порядку. Асинхронная обработка требуется не "шоп було", а при наличии веских причин. Основных - две. 1. Мы можем и должны обрабатывать данные в процессе чтения тела запроса. Разумеется, это можно сделать и без асинхронности, но, скорее всего, получится неудобоваримое спагетти. А при асинхронной обработке у нас будет два чётко специализированных метода и какой-то механизм синхронизации их работы. 2. Есть много относительно медленных клиентов и вам "кровь из носу" требуется сэкономить ресурсы контейнера. Реализуем слушатели "по готовности" и контейнер получает возможность "отбирать" рабочий поток исполнения пока метод ждёт данные. Как и насколько это реализуется на практике - не знаю. Так ни в одном из сценариев (включая любые другие) не имеете права создавать потоки самостоятельно - вы обязаны создать класс, реализующий j.l.Runnable (привет, интерфейсы) и предоставить этот класс методу start асинхронного контекста. Контейнер создаст (возьмёт из пула) рабочий поток и передаст ему ваш метод run. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 19:30 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 19:35 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovУ вас кардинальное непонимание что такое асинхронность в сервлетах. Начнём по порядку. Асинхронная обработка требуется не "шоп було", а при наличии веских причин. Основных - две. 1. Мы можем и должны обрабатывать данные в процессе чтения тела запроса. Разумеется, это можно сделать и без асинхронности, но, скорее всего, получится неудобоваримое спагетти. А при асинхронной обработке у нас будет два чётко специализированных метода и какой-то механизм синхронизации их работы. 2. Есть много относительно медленных клиентов и вам "кровь из носу" требуется сэкономить ресурсы контейнера. Реализуем слушатели "по готовности" и контейнер получает возможность "отбирать" рабочий поток исполнения пока метод ждёт данные. Как и насколько это реализуется на практике - не знаю. Так ни в одном из сценариев (включая любые другие) не имеете права создавать потоки самостоятельно - вы обязаны создать класс, реализующий j.l.Runnable (привет, интерфейсы) и предоставить этот класс методу start асинхронного контекста. Контейнер создаст (возьмёт из пула) рабочий поток и передаст ему ваш метод run. грубо говоря - что хочу - есть очень долгая операция - отчет , выборка ... итд .. клиент дернул ссылку - хочу отчет ... запрос прилетел - под него создался отдельный поток , поток сервлета освободился ... клиенты посылаются уведомления фоном что все ок делается ... потом когда он сгенеировался - ему его показали ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 19:39 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum1грубо говоря - что хочу - есть очень долгая операция - отчет , выборка ... итд .. клиент дернул ссылку - хочу отчет ... запрос прилетел - под него создался отдельный поток , поток сервлета освободился ... клиенты посылаются уведомления фоном что все ок делается ... потом когда он сгенеировался - ему его показали ...Это всё не так делается. Если клиент не хочет ждать дольше некоторого времени, то вы должны принять данные, поставить статус перенаправления, указав ссылку, по которой должен быть взят результат (опционно - время через которое надо проверить готовность) и зафиксировать ответ. Запросы отправляются на обработку, результаты которой помещаются в, например, хэш-таблицу. Естественно, каждому запросу и каждой ссылке ставится по которому будем искать и сопоставлять. Если клиент пришёл за результатом, который ещё не готов - немного ждём и, если, всё-таки, не готово опять ставим статус перенаправления. Ждём достаточно долго, чтобы не получалось слишком много перенаправлений, но не так долго, чтобы срабатывали тайм-ауты HTTP-протокола. Асинхронность, как таковая, здесь не нужна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2015, 20:03 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovВо-первых асинхронная обработка в Servlet API появилась для того, чтобы не работать с потокам там, где может быть череповато. Поэтому непонятно, что делает new Thread() в вашем коде. Во-вторых, асинхронная обработка должна быть или диспетчеризирована запрос или явно завершена . В-третьих, HTTP предусматривает три значения тайм-аутов: 1. До получения строки запроса - секунды; 2. До получения всего заголовка - (две-три) минуты; 3. При чтении тела запроса или записи ответа - десять-пятнадцать минут. С какого перепугу выставлены отбалдянские три секунды - совершенно непонятно. Поэтому непонятно, что делает new Thread() в вашем коде. Ну в таком упрошенном примере это можно понимать как: замыкание , у вас есть рул потоков в сервлете и каждый пользователь берет из этого пула по потоку вызывая при этом генерацию отчета - долгая операция ... по умолчанию в jetty из 200 <Set name="maxThreads">200</Set> т.е если придет 201 пользователь , он либо попалдает в очередь ArrayBlockingQueue (6000) либо получает 500. создавая внутри потока сервлета новый тред - мы тем самым освобождаем тред сервлета. тут конечно вопрос : когда работа в новом треде будет закончена , через что этот контектст возвращает результат и как он это делает ? через себя или через пул сервлета ??? Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Во-вторых, асинхронная обработка должна быть или запрос или явно завершена context.complete(); 1. До получения строки запроса - секунды; 2. До получения всего заголовка - (две-три) минуты; 3. При чтении тела запроса или записи ответа - десять-пятнадцать минут. С какого перепугу выставлены отбалдянские три секунды - совершенно непонятно просто не хочу ждать по несколько минут ... чтобы проверить работоспособность искусственно занизил время логика приложения должна быть такая : к примеру если клиент не получил ответ в течении 3 секунд - он на стороне js = должен оборвать соединение , тоже самое должен сдлеать и сервер - если он е успел за 3 секунда обработать запрос- он должен прекратить его выполнение выполнить context.complete(); и вернуть 500 ... итд возможно код сильно странно выглядит , но для того чтобы разобраться без всяких эффектов самое то : могу переписать в таком виде : где будет очередь BlockingQueue и один тред трудяга - который эту очередь будет разбирать ... или можно заменить его на private final static ExecutorService executorService = Executors.newFixedThreadPool(2); Было : Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. стало Код: java 1. 2. 3. 4. 5. 6. 7. 8. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. Смысл асинхронности : в системе с одной стороны на предприятии сидит более 200 человек и они шлют запросы на генерацию отчетов - к cерверу jetty jetty - выступает клиентов (внутри создается http post запрос к серверу отчетов) ... выяснилось - что сервер отчетов не может работать в многопоточном режиме :( что делать ? можно было бы обойтись без асинхронности : как было раньше так же ставить все запросы в очередь , а обрабатывать их в один поток ... а с клиента делать пулинг - готов отчето или нет ... такой ddos jetty / мне показалось что лучше уж пусть клиент повисит немного в очереди и посмотрит процесс выполнения запроса ... чем будет слать запросы как было сделано : на клиента стоит скрипт и по кнопке идут запросы к url дай отчет в цикле ... сервер возвращает либо жди ...либо готово ... Код: java 1. 2. 3. 4. 5. 6. 7. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. как так ... где ReportResult report = service.getUserReport(user); получение отчета . 0FDAtum1 https://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html#start(java.lang.Runnable) Код: java 1. если просто пихать туда созданный тред Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. то будет тот же эффект - при явно меньшем таймауте чем сам процесс работы ... только имена тредов будут другие из какого то пула ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 10:11 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Для спринга - асинхронность можно разрулить средствами самого спринга : тут только вопрос правильно ли я понимаю что : deferredResult - нужно засунуть в findPage и там внутри вызвать deferredResult.setResult(result.get()); ??? Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Но я в дебаге не вижу что это действительно асинхронно (не вижу что создаются треды новые) ?! и все таки вопрос что происходит когда мы выставляем context.setTimeout(3000); время меньше чем работа самого треда открытый ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 17:30 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
получается этот вариант асинхронный? в первом - мы будем ждать в сервлете - когда result.get() вернет значение?! так? Код: java 1. 2. 3. 4. 5. 6. 7. 8. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 17:42 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum1т.е если придет 201 пользователь , он либо попалдает в очередь ArrayBlockingQueue (6000) либо получает 500."Я худею дорогая редакция". Т.е. увеличить размер пула до адекватного - мы не можем, а:создавая внутри потока сервлета новый тред - мы тем самым освобождаем тред сервлетаЗанять тот же самый ресурс и потерять возможность ответа клиенту - это завсегда пожалуйста. Про грабли самостоятельного создания потоков там, где этого не надо делать - уговорили, отдельной строчки не заводим.тут конечно вопрос : когда работа в новом треде будет закончена , через что этот контектст возвращает результат и как он это делает ? через себя или через пул сервлета ??? Я ещё не говорил, что вы вообще пинцет, как не понимаете принципы работы HTTP? Пришедший запрос обязан обработаться. Вернёте вы клиенту ожидаемый результат, ответите "NO_CONTENT", сделаете перенаправление или вернёте ошибку - дело ваше, но "что-то" вы обязаны вернуть.логика приложения должна быть такая : к примеру если клиент не получил ответ в течении 3 секунд - он на стороне js = должен оборвать соединение , тоже самое должен сдлеать и сервер - если он е успел за 3 секунда обработать запрос- он должен прекратить его выполнение выполнить context.complete(); и вернуть 500 ... итд возможно код сильно странно выглядит , но для того чтобы разобраться без всяких эффектов самое то :Странно это мягко сказано. 1. Не клиенту решать, сколько времени должна занимать обработка, т.к. не он её выполняет. 2. После завершения обработки контекстом сделать уже ничего нельзя. И ошибку нельзя вернуть, т.к. ошибку возвращает или SetStatus() или SendError() до завершения обработки. 3. Не хотите, чтобы клиент ждал - принимайте запрос, отправляйте на обработку и сообщайте клиенту где и когда он может посмотреть результат.Смысл асинхронности : в системе с одной стороны на предприятии сидит более 200 человек и они шлют запросы на генерацию отчетов - к cерверу jetty jetty - выступает клиентов (внутри создается http post запрос к серверу отчетов) ... выяснилось - что сервер отчетов не может работать в многопоточном режиме :( что делать ?Сервер отчётов рефакторить - его, похоже, такой же "мастер" делал. Начать можно с анализа параметров запросов: если несколько клиентов запросили априори одинаковое - напрячь сервер отчётов только одним запросом. Костыль, но позволяет не лезть в чужой код. Ну и кэширование.можно было бы обойтись без асинхронности : как было раньше так же ставить все запросы в очередь , а обрабатывать их в один поток ... с клиента делать пулинг - готов отчето или нет ... такой ddos jetty /Перенаправление для того и существует, чтобы не клиенты не спрашивали у сервера того, чего он не знает.мне показалось что лучше уж пусть клиент повисит немного в очереди и посмотрит процесс выполнения запроса ... чем будет слать запросыКакое, нахрен, "посмотрит"?! В многопоточном режиме, значит, сервер отчётов работать не умеет, а статус выполнения возвращать может??? А если не может, то "ожидательное многоточие" клиент в состоянии нарисовать без посторонней помощи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 17:43 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorovсервер отчетов не может работать в многопоточном режиме :( что делать ? очередь заданий для него и пусть день и ночь будет загружен в одном потоке. Сваливает результат в табличку. Если в банке 1 окошко, и электронная очередь, то все сидят синхронно в ожидании друг за другом)). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 17:56 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov +1 это я выше аффтару ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 17:57 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
ну а для очереди заданий вообще никакие потоки не нужны. Если не тормозить клиента. Клиент в JS может сам после заказа через пару секунд проверять статус заказа по другому адресу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:00 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
есть вполне банальный пример сетевого принтера в винде. С его очередью, и окошком на всех сетевых клиентах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:01 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov , спасибо за ответы буду думать :) Basil A. SidorovСервер отчётов рефакторить - его, похоже, такой же "мастер" делал. Начать можно с анализа параметров запросов: если несколько клиентов запросили априори одинаковое - напрячь сервер отчётов только одним запросом. Костыль, но позволяет не лезть в чужой код. Ну и кэширование. 1. требования что отчеты должны быть онлайн . 2. кешировать нельзя . 3. одинаковых отчетов нет . 4. каждый бизнес запрос от пользователя - меняет состояние сервера - следовательно изменяться отчет . Сразу тогда архитектурный вопрос Это будет правильно если организовать цепочку так : LookupService - это асинхронная работа ... далее идет FacadeLookupService - Это простая обертка для контроллера в котором просто идет вызов result.get() Код: java 1. 2. 3. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Код: java 1. 2. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. и тогда контроллер : Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:05 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Petro123Basil A. Sidorovпропущено... очередь заданий для него и пусть день и ночь будет загружен в одном потоке. Сваливает результат в табличку. Если в банке 1 окошко, и электронная очередь, то все сидят синхронно в ожидании друг за другом)). Petro123, спасибо я как раз привел такой пример выше ,как вариант : но меня смущает одно но - это тред который висит постоянно и который нельзя перестартовать ! вот если бы можно было создать очередь и пул и заставить его самого из этого очереди выбирать задания ... но как? Было : Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. стало Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:10 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum11. требования что отчеты должны быть онлайн . от кого это требование и что под этим понимается? Т.к. уже решение, в ТЗ так не пишут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:16 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum14. каждый бизнес запрос от пользователя - меняет состояние сервера - следовательно изменяться отчет . ? Если я 2 раза нажал на кнопку Отчёт после того как перекурил, то они будут разные? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:18 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Petro123Atum14. каждый бизнес запрос от пользователя - меняет состояние сервера - следовательно изменяться отчет . ? Если я 2 раза нажал на кнопку Отчёт после того как перекурил, то они будут разные? да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:20 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum1Petro123, спасибо я как раз привел такой пример выше ,как вариант : не вижу. Я предложил вариант: - везде выкинуть Thread - банальная запись в сервлете в БД в табличку Очередь имя отчёта и его параметры. - вернуть клиенту сразу же номерок или токен задания. - далее проблема клиента всё это забрать - всё. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:23 |
|
||
|
странное поведение AsyncContext
|
|||
|---|---|---|---|
|
#18+
Atum1да. я не понял почему да, но ладно. Нет проблем - вам хуже)). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2015, 18:24 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39030047&tid=2125045]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
202ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
75ms |
get tp. blocked users: |
2ms |
| others: | 223ms |
| total: | 543ms |

| 0 / 0 |
