Eu tenho um programa em Java que deve fazer as seguintes 3 coisas:
- Faça o download de um arquivo de um website.
- Execute o arquivo através de testA e testB (ambos em java)
- Exclua o arquivo e salve os resultados do teste no disco.
Isso é feito para cerca de 1.000.000 sites diferentes. Era suposto ser uma tarefa bastante simples, já que eu simplesmente colei partes de outros programas: testA
e testB
já executados separadamente para dezenas de milhões de páginas diferentes sem problemas, e a rotina que baixou as páginas também foi executado por um milhão de páginas algumas vezes, e nunca teve problemas. Todos eles estão sendo executados em uma máquina Ubuntu 10.4.
No entanto, ao fazer esses 3 um após o outro, qualquer disco que os arquivos estavam sendo gravados para falhas. A primeira vez que o executei em um HD USB externo, que tive que desconectar manualmente e reconectar para que ele continuasse a operação (o Linux não reconheceria isso de outra forma). Na próxima vez, em um HD interno, todo o sistema foi desativado e tive que reiniciá-lo manualmente. O mesmo aconteceu ao gravar em um disco RAM.
O problema é que não consigo isolar o problema. Leva muito tempo para que ocorra uma falha (cerca de 50 horas ou mais, mas é bastante aleatório), portanto, os testes demoram muito tempo e não há registros do sistema da falha indicando onde / como isso acontece. A máquina ou HD simplesmente pára de responder.
Exceto pela falha, tudo funciona bem. Os arquivos são criados e excluídos normalmente, os threads não morrem e são executados corretamente, e ambos os testes funcionam bem. Alterar a memória ou o número de threads não teve efeito no tempo de bloqueio. Eu já verifiquei Sockets ou algo parecido não ser fechado, mas eu nem sei como começar a testar, eu não tinha ideia de travar um sistema tão catastroficamente seria possível com Java.
EDIT: Por hangup quero dizer que, quando eu executo em um HD externo o HD não é reconhecido pelo Linux, e quando eu executo no HD interno ou em um Ram Disk o o computador não responderá a nenhuma E / S, sem que nada seja gravado no disco, logs do cactii não sejam gravados, etc. Não é possível conectar-se usando SSH, por exemplo.
Um exemplo de como o programa é executado:
List<String> pagesToDownload = getFromDataBase();
for(i=0;i<NumThreads;i++){
launchTestThread();
}
E depois, em cada thread:
String pageName = getNextPageToDownload();
File downloadedFile = downloadPage(pageName);
TestAResults testAResults = runTestA(downloadedFile);
TestBResults testBResults = runTestB(downloadedFile);
writeToDatabase(downloadedFile, testAResults, testBResults);
downloadedFile.delete();
Individualmente, as funções runTestA
, runTestB
e downloadedPage
funcionam para quantidades ainda maiores de arquivos, mas, quando chamadas dessa forma, não funcionam. E isso no mesmo hardware.
EDIT2: Acho que descartei o problema de ser o hardware. Um software tão intensivo em hardware foi executado na mesma máquina nos últimos 7 dias sem nenhum problema. De qualquer forma, assim que eu conseguir uma máquina não utilizada, vou testar o programa nela.
Além disso, tudo no teste está sendo gravado no banco de dados até o ponto em que a falha ocorre e os dados estão corretos. O downloadedFile
não é passado como parâmetro durante o método writeToDatabase, apenas o nome e tamanho.
Por fim, fiz algumas verificações extensivas de vazamentos de memória ou de manipuladores de arquivos e não encontrei nenhum, inclusive dentro dos testes de trabalho. Neste momento, meu dinheiro está em algum bug estranho na exclusão do arquivo.
EDIT3: Eu finalmente consegui uma outra máquina onde testar a rotina. Outro hardware, mas mesma versão do Ubuntu (10.4 LTS). E também cai lá, então eu realmente duvido que seja um problema de hardware. Isso deixa um bug do sistema operacional, um bug da JVM ou um bug de programação (não há JNI ou algo parecido em execução). Vou tentar executar o teste em algum outro ambiente (configurar um teste no FreeBSD será bem fácil, e posso tentar encontrar uma máquina Windows para testar isso) para verificar isso.
EDIT4: Respondendo a pergunta de Bob Cross sobre o tamanho dos arquivos, eles são páginas típicas da web, com uma média de cerca de 20kb. Eu tenho que deletá-los já que a idéia é expandir o aplicativo, tornando o uso do disco insuportável. Mas vou tentar uma corrida livre de exclusão assim que puder. A máquina onde eu estava rodando esses testes está sendo usada agora, e estou tendo dificuldades em obter algum hardware ocioso.