Estamos executando o ColdFusion 8 em um servidor Windows 2003 VPS com uma API que expõe os registros dos alunos a uma API parceira por meio de um conector. Nossa API retorna cerca de 50 mil registros de alunos serializados em formato XML de forma bastante integrada. Minha pergunta se origina quando algo muito assustador aconteceu hoje quando testamos nosso conector para a API de nossos parceiros. Todo o nosso site e web host caiu. Assumimos que o nosso anfitrião estava apenas a ter alguns problemas e após 4 horas sem resolução e sem resposta do seu serviço ao cliente, finalmente obtivemos uma resposta, alegando que tinham um "utilizador não autorizado" na sua rede. Depois que nosso servidor estava de volta, não conseguimos nos conectar ao nosso site como se o serviço web ou coldfusion tivesse congelado. Isso é realmente o motivo de minha preocupação, já que temo que tenhamos sobrecarregado o serviço da Web.
Como mencionei antes, tentamos enviar mais de 50k solicitações HTTP POST para a API do nosso parceiro, mas tudo parou depois de 1,6k
Isso é uma prática ruim ou existe algum tipo de limitação de taxa? Eu posso relaxar em algum lugar na configuração do servidor? Conseguimos encontrar uma solução alternativa, mas ela ignora nosso conector, que é essencial para o nosso projeto.
Esta seria uma negociação única, pois o objetivo de muitas solicitações era preencher o site de nosso parceiro com os dados atuais, depois disso as sincronizações por hora manteriam as solicitações em torno de 100 por hora.
UPDATE
Nossa API de parceiro é de propriedade e operada pelo Pardot . Estamos convertendo alunos em clientes em potencial, passando os dados dos alunos para a API, o que infelizmente parece aceitar apenas um aluno de cada vez. Por esse motivo, temos que fazer todas as solicitações de 50k individualmente.
Nosso servidor tem 4 GB de RAM, um Intel Core 2 Duo a 2,8 GHz com o Windows Server 2003 SP2.
Eu monitorei o servidor durante uma sincronização de 100 alunos, uma sincronização de 400 alunos e uma sincronização de alunos de 1,4k com os seguintes resultados:
100 alunos - 2,25 GB de memória, 30 a 40% de utilização da CPU, 0,2 a 0,3% de largura de banda de rede
400 alunos - 2.30 GB de memória, 30-50% de utilização da CPU, 0,2-1,0% de largura de banda de rede
1.4k alunos - 2.30GB de memória, 30-70% de utilização da CPU, 0,2-1,0% de largura de banda de rede
Eu sei que isso está muito longe dos 50 mil alunos, mas eu não quero correr o risco de derrubar nosso sistema CMS novamente, assumindo que essa foi a causa.
Para dar uma olhada no nosso código:
<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>
UPDATE 2
Eu verifiquei os logs do CF e encontrei alguns deles:
"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)
Parece que eu poderia ter travado a JVM no CF, existe uma maneira melhor de fazer isso? Estamos pensando em exportar todos os registros inicialmente como um arquivo CSV e importá-lo para o Pardot, já que nunca teremos que fazer um pedido tão grande novamente.