Мы запускаем ColdFusion 8 на сервере Windows Server 2003 VPS с API, который предоставляет записи учащихся партнерскому API через соединитель. Наш API возвращает около 50 тысяч студенческих записей, сериализованных в формате XML, без каких-либо проблем. Мой вопрос возникает, когда сегодня произошло нечто очень пугающее, когда мы тестировали наш коннектор для API наших партнеров. Весь наш веб-сайт и веб-хостинг перестали работать. Мы предположили, что у нашего хоста просто возникли некоторые проблемы, и через 4 часа без решения и без ответа от их службы поддержки мы наконец получили от них ответ, в котором утверждалось, что в их сети есть «неавторизованный пользователь». После резервного копирования нашего сервера мы не смогли подключиться к нашему веб-сайту, как если бы веб-сервис или сам холодный сплав завис. Это действительно причина моего беспокойства, поскольку я боюсь, что мы могли перегрузить веб-службу.
Как я уже упоминал ранее, мы пытались отправить более 50 тыс. HTTP-запросов POST в API нашего партнера, однако все прекратилось примерно через 1,6 тыс.
Это плохая практика или есть какое-то ограничение скорости, которое я могу расслабить где-нибудь в конфигурации сервера? Нам удалось найти обходной путь, но он обходит наш коннектор, который имеет решающее значение для нашего дизайна.
Это было бы разовой сделкой, так как целью такого большого количества запросов было заполнение веб-сайта нашего партнера текущими данными, после чего почасовая синхронизация будет поддерживать примерно 100 запросов в час.
ОБНОВИТЬ
Наш партнерский API принадлежит и управляется Пардо. Мы превращаем студентов в потенциальных клиентов, передавая данные об учащихся в их API, который, к сожалению, принимает только одного студента за раз. По этой причине мы должны обрабатывать все 50 тысяч запросов индивидуально.
Наш сервер имеет 4 ГБ оперативной памяти, процессор Intel Core 2 Duo с тактовой частотой 2,8 ГГц, работающий под управлением Windows Server 2003 SP2.
Я наблюдал за сервером во время синхронизации 100 учеников, синхронизации 400 учеников и синхронизации 1,4 тысячи учеников со следующими результатами:
100 студентов - 2,25 ГБ памяти, загрузка ЦП 30-40%, пропускная способность сети 0,2-0,3%
400 студентов - 2,30 ГБ памяти, загрузка ЦП 30-50%, пропускная способность сети 0,2-1,0%
1,4 тыс. Студентов - 2,30 ГБ памяти, загрузка ЦП 30-70%, пропускная способность сети 0,2-1,0%
Я знаю, что это далеко от 50 тысяч студентов, но я не хочу снова рисковать, ломая нашу систему CMS, полагая, что это было причиной.
Чтобы вы могли взглянуть на наш код:
<cfif (#getStudents.statusCode# eq "200 OK")>
<cftry>
<cfloop index="StudentXML" array="#XmlSearch(responseSTUD,'/students/student')#">
<cfset StudentXML = XmlParse(StudentXML)>
<cfhttp
url="#PARDOT_CMS_UPSERT#"
method="post"
timeout="10000" >
<cfhttpparam type="url" name="user_key" value="#PARDOT_CMS_USERKEY#">
<cfhttpparam type="url" name="api_key" value="#api_key#">
<cfhttpparam type="url" name="email" value="#StudentXML.student.email.XmlText#">
<cfhttpparam type="url" name="first_name" value="#StudentXML.student.first.XmlText#">
<cfhttpparam type="url" name="last_name" value="#StudentXML.student.last.XmlText#">
<cfhttpparam type="url" name="in_cms" value="#StudentXML.student.studentid.XmlText#">
<cfhttpparam type="url" name="company" value="#StudentXML.student.agencyname.XmlText#">
<cfhttpparam type="url" name="country" value="#StudentXML.student.countryname.XmlText#">
<cfhttpparam type="url" name="address_one" value="#StudentXML.student.address.XmlText#">
<cfhttpparam type="url" name="address_two" value="#StudentXML.student.address2.XmlText#">
<cfhttpparam type="url" name="city" value="#StudentXML.student.city.XmlText#">
<cfhttpparam type="url" name="state" value="#StudentXML.student.state_province.XmlText#">
<cfhttpparam type="url" name="zip" value="#StudentXML.student.postalcode.XmlText#">
<cfhttpparam type="url" name="phone" value="#StudentXML.student.phone.XmlText#">
<cfhttpparam type="url" name="fax" value="#StudentXML.student.fax.XmlText#">
<cfhttpparam type="url" name="output" value="simple">
</cfhttp>
</cfloop>
<cfcatch type="any">
<cfdump var="#cfcatch.Message#">
</cfcatch>
</cftry>
</cfif>
ОБНОВЛЕНИЕ 2
Я проверил журналы CF и нашел пару таких:
"Error","jrpp-8","06/06/13","16:10:18","CMS-API","Java heap space The specific sequence of files included or processed is: D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm, line: 675 "
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
at java.io.CharArrayWriter.write(CharArrayWriter.java:105)
at coldfusion.runtime.CharBuffer.replace(CharBuffer.java:37)
at coldfusion.runtime.CharBuffer.replace(CharBuffer.java:50)
at coldfusion.runtime.NeoBodyContent.write(NeoBodyContent.java:254)
at cfapi2ecfm292155732._factor30(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:675)
at cfapi2ecfm292155732._factor31(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:662)
at cfapi2ecfm292155732._factor36(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:659)
at cfapi2ecfm292155732._factor42(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:657)
at cfapi2ecfm292155732._factor37(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm)
at cfapi2ecfm292155732._factor44(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:456)
at cfapi2ecfm292155732._factor38(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm)
at cfapi2ecfm292155732._factor46(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:455)
at cfapi2ecfm292155732._factor39(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm)
at cfapi2ecfm292155732._factor47(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:453)
at cfapi2ecfm292155732.runPage(D:\Clients\www.xxx.com\www\dev.cms\api\v1\api.cfm:1)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:279)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.CfmServlet.service(CfmServlet.java:175)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
Похоже, я мог разбить JVM в CF, есть ли лучший способ сделать это? Мы думаем о том, чтобы сначала просто экспортировать все записи в виде файла CSV и импортировать его в Pardot, так как нам больше никогда не придется выполнять такие большие запросы.
Я нашел решение, которое в значительной степени обходит эту проблему и больше соответствует "передовой практике"
Я решил пойти по пути экспорта данных в файл CSV, поскольку эта проблема возникла из-за попытки первоначального заполнения базы данных. Импорт CSV работает безупречно, а синхронизация послесловий выдает только около 0-1000 запросов, с некоторой дополнительной оптимизацией и планированием у меня есть запросы до 0-50 за 30 минут, что идеально.
Вы отслеживали использование ЦП, диска и полосы пропускания на своем сервере? Первое, что я сделаю, это убедитесь, что ни один из этих ресурсов не перегружен. Perfmon - очевидное место для начала и проверки журналов CF.
Делали ли вы 50К почтовых запросов (то есть отдельные запросы) один за другим или это единственный запрос на 50К записей в файле XML? Если первое, то зачем делать 50К запросов? Можно ли это сделать, запросив сразу все 50К записей, поскольку это будет всего лишь 1 запрос и 1 передача файла? Если запросы 50 КБ являются последовательными (т.е. следующий запрос не выполняется до тех пор, пока не будет завершен текущий), то это кажется мягким способом выполнения большого количества запросов.