У меня есть веб-служба Java SOAP, изначально разработанная в Axis 1, которая не соответствует моим требованиям к производительности.
Больше всего меня беспокоит запрос, который используется для добавления большого количества (миллионов строк) данных в базу данных. На стороне клиента я просто буду просматривать файлы и отправлять эти данные в мой веб-сервис. Каждая строка имеет три элемента, поэтому запрос выглядит примерно так:
<SOAP Envelope/Header/Body>
<AddData>
<Data>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<Age>42</Age>
</Data>
</AddData>
</SOAP Envelope/Body>
Я нахожу следующие тенденции производительности:
- Когда я делаю одну строку на запрос, я могу получить около 720 строк в минуту.
- Когда я инкапсулирую несколько строк в один запрос, я могу получить до 2400 строк в минуту (100 строк на запрос).
К сожалению, эта производительность не будет соответствовать нашим требованиям, поскольку мы можем вставить сотни миллионов строк (при 2500 строк в минуту загрузка всех данных займет около 2 месяцев).
Итак, я изучал приложение, чтобы увидеть, где находится наше узкое место. Каждый запрос из 100 строк занимает около 2,5 секунд (я пробовал несколько разных серверов и получаю похожие результаты). Я нашел следующее:
- Расходы на стороне клиента незначительны (из-за мониторинга производительности моего собственного клиента и использования SOAP UI)
- Активность базы данных составляет всего около 10% (0,2 с) от общего времени, поэтому кэширование в Hibernate и т. Д. Не сильно поможет.
- Сетевые издержки незначительны (<1ms время пинга от клиента к серверу, пропускная способность> 10 МБ / с при каждой отправке запроса <20 КБ). </li>
Таким образом, это оставляет около 2 секунд неучтенными. Единственная другая часть этой головоломки, на которую я могу указать пальцем, - это издержки десериализации входящих запросов на стороне сервера. Я заметил, что Axis 2 требует улучшения скорости в этой области, поэтому я перенес эту функцию через веб-сервис Axis 2, но не получил нужное мне ускорение (общее время на запрос увеличилось примерно на 10%).
Я недооцениваю количество времени, необходимое для десериализации 100 элементов, описанных выше? Я не могу представить, что эта десериализация может занять около 2 секунд.
Что я могу сделать, чтобы оптимизировать производительность этого веб-приложения и сократить эти 2-секундные накладные расходы?
Заранее спасибо!
========= На следующий день .... ===========
Сюжет утолщается ...
По рекомендации @millhouse я исследовал запросы на одну строку еще на одном производственном сервере. Я обнаружил, что они могут быть достаточно быстрыми на хорошем оборудовании. Поэтому я попытался добавить 1000 строк, используя приращения в диапазоне от 1 (1000 отдельных запросов) до 1000 (один запрос).
- 1 строка / Запрос - 14,5 секунд
- 3 / req - 5,8 с
- 5 / req - 4,5 с
- 6 / req - 4,2 с
- 7 / req - 287 с
- 25 / req - 83 с
- 100 / req - 22,4 с
- 1000 / req - 4,4 с
Как видите, дополнительные 2 секунды задерживаются на 7 строк на запрос (примерно 2 дополнительные секунды на запрос по сравнению с 6 строками на запрос). Я могу воспроизвести это последовательно. Все большее количество запросов имели одинаковые накладные расходы, но это стало менее заметно при вставке 1000 строк на запрос. Время базы данных росло линейно и все еще было незначительным по сравнению с общим временем запроса.
Итак, я обнаружил, что я получаю наилучшую производительность, используя либо 6 строк на запрос, либо тысячи строк на запрос.
Есть ли какая-либо причина, по которой производительность 7 будет ниже, чем 6 строк на запрос? Машина имеет 8 ядер, и у нас есть 10 подключений в пуле сеансов (т.е. я понятия не имею, откуда берется порог 6).