Falha no ColdFusion Server após milhares de solicitações HTTP

1

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.

    
por Jason Bristol 07.06.2013 / 01:53

2 respostas

0

Eu encontrei uma solução que praticamente ignora esse problema e se encaixa mais na "melhor prática"

Eu decidi seguir a rota de exportar dados para um arquivo CSV, já que esse problema se originou na tentativa de inicialmente preencher um banco de dados. A importação de CSV funciona de forma impecável e as sincronizações pós-palavras emitem apenas cerca de 0-1000 solicitações. Com algumas otimizações e agendamentos adicionais, tenho solicitações de 0 a 50 por 30 minutos, o que é ideal.

    
por 28.06.2013 / 17:39
0

Você monitorou o uso de CPU, disco e largura de banda em seu servidor? A primeira coisa que faço é ter certeza de que nenhum desses recursos está sendo sobrecarregado. Perfmon é um lugar óbvio para começar e confira seus logs de CF.

Você fez 50 mil solicitações de postagem (ou seja, solicitações separadas) uma após a outra ou é uma solicitação única para os registros de 50 mil em um arquivo XML? Se o primeiro, por que você faria pedidos de 50K? Poderia ser feito solicitando todos os registros de 50K de uma só vez, já que seria apenas 1 pedido e 1 transferência de arquivo? Se as solicitações de 50K forem sequenciais (ou seja, a próxima solicitação não é feita até que a atual esteja completa), então isso parece ser uma maneira gentil de fazer um grande número de solicitações.

    
por 07.06.2013 / 02:44