Até ontem, até meio da manhã, até pouco tempo atrás, o aplicativo Ruby On Rails rodava normalmente, mas não importava o que eu fizesse, de repente ele virava um erro chamado "Routing Error: Uninitialized constant XXXXX Controller", e eu caí em um sintoma misterioso que não conseguia dizer sim ou não, e tive uma experiência entorpecida que quase chorei por cerca de um mês até investigar a causa, então pensei em anotar as DICAS até a solução (originalmente, dificuldade?) Pensei em anotar aqui.
Procurando o Culpado
Primeiramente, essa tela de erro do Rails já está perto de trauma...

Primeiro, quando você recebe esse erro, o Rails especifica diretamente a URL e troca o controlador que é chamado, ou nada mais, ele só vai continuar aparecendo o mesmo "Erro de Roteamento" e o erro de que só o nome do controlador é diferente. Você só vai dizer isso como se soubesse mais a mensagem de erro. No entanto, o arquivo de configuração de rotas do Rails 'config/routes.rb' é normal (porque estava rodando até agora e o roteamento não foi alterado, então é natural). Mesmo olhando o log do Rails, só pode ver a mesma quantidade de informação da tela de erro, e toda vez que você olha o log de erro no servidor, ele só diz que há um erro 404 e que não há conteúdo na rota (URL) (o controlador Rails não está funcionando). Mesmo que você volte pela pilha de processamento do log de erros, não há nada particularmente estranho... Que diabos é isso!? Meu coração já está partido, já quebrei muito, odeio o Rails, mas não posso jogar fora, é meu trabalho, então não posso seguir em frente a menos que descubra a causa (T_T)
Se você procurar no StackOverflow ou em outros fóruns de suporte, encontrará perguntas de pessoas que estão sofrendo com os mesmos sintomas... Mas não há resposta. Sério~ Ninguém está resolvendo isso~!? Alguém, por favor, me ajude~... Esse é o estado.
E a parte ainda mais misteriosa desse sintoma é que pode ser resolvido reconstruindo o ambiente Rails (reinstalando tudo do zero) (ou melhor, naquela época, só havia uma forma de se recuperar). Portanto, no começo, pesquisei bastante para ver se o problema era a configuração e o cache do lado do servidor (como o Passenger que retransmitia Apache e Rails), mas tudo errava (quando o bug foi corrigido, se a intuição de "Não está aqui?" estiver errada, será amassado... Acho que também sou velho).
Agora, na reconstrução do Rails várias vezes, tentei mudar a versão Ruby e a versão do Rails. No começo, era Ruby 1.9.3 + Rails 4.1.0, mas mudei para Ruby 2.0.0 + Rails 4.2.0. Há bastante compatibilidade entre versões, então tentei atacar por essa área. Não houve problema imediatamente após a reconstrução, mas os mesmos sintomas ocorreram novamente ao meio-dia do dia seguinte. O banco de dados SQLite do Rails pode estar quebrado, então é inútil tentar voltar para o banco de dados que foi salvado imediatamente após a reconstrução. Tente inicializar o banco de dados novamente e reinserir os dados. … Hmm? seeds.rb não funciona (no Rails, ao registrar os dados iniciais no banco de dados, você executa o comando 'rake db:seed' usando 'db/seeds.rb', que é um erro). Isso é um binário Rake quebrado?
── Bem, esse foi o sentimento que mais me fez chorar... Sinto que só tenho uma sensação de futilidade e desespero. Nem tenho um flash.
Continuei a mesma investigação por quase um mês, mas finalmente a luz apareceu. Bem, o pensamento do musgo... Acho que é esse cara~. Surpreendentemente, encontrei um lugar assim!
Ruby de repente parou de funcionar "/usr/bin/ruby: No such file or directory" prelink? No ambiente CentOS, ele é instalado como obrigatório e roda sozinho com cron.daily (um trabalho cron que roda uma vez por dia). Como algo ruim, há casos em que o arquivo binário Ruby está quebrado. É bem suspeito. Desta vez, quando procurei por prelink+ruby, finalmente apareceu... Sinto que cheguei ao ponto certo.
É muito suspeito no pré-link.
cron.daily é executado aleatoriamente entre 3:00 ~ 4:00 todas as manhãs. Aliás, o fuso horário do ambiente Rails é UTC, então se você +9:00, o pré-link vai rodar entre 12:00 ~ 13:00 no Japão. A única vez que o problema ocorreu foi durante o almoço... Isso significa...
**Prelink, é você~? **
Por isso eu realmente verifiquei. No ambiente Rails reconstruído, enquanto a gravação no banco de dados SQLite está sendo feita (esse tempo é bastante importante. Quando a aplicação principal mudava para o binário, houve casos em que o pré-link não se sobrepôs e os sintomas não ocorreram), tentei rodar o pré-link manualmente...
**Afinal, você foi o culpado, prelink! **
Parabéns pelo "erro de roteamento"! Não, não quero ficar feliz que o app Rails está quebrado, mas fico muito feliz ♪ por todos os envolvidos, inclusive por mim
Então, como peguei o checksum do Rails antes de rodar o prelink, quando comparei com o checksum após rodar, parece que os binários do Gemfile.lock e do db/development.sqlite3 estão quebrados. Mesmo que você retorne apenas os arquivos no banco de dados SQLite, não consegue recuperá-los.
Em particular, se o Gemfile.lock estiver quebrado, não sabemos como o Rails vai se comportar porque é um binário que gerencia centralmente dependências, versões e destinos (caminhos de arquivo) das gems. Desta vez, foi uniformemente "Erro de Roteamento", mas dependendo do ambiente, o Rails pode acabar apresentando apenas outro erro.
Agora, essa é a luta para descobrir a causa. A partir de agora, serão DICAS para corrigir bugs.
Desativar o Prelink
Primeiro de tudo, o que é prelink? ── Claro, ele é suspeito até agora, mas pode não ser ele quem faz algo tão ruim assim. Quando pesquisei, descobri que prelink é middleware que analisa o processamento dinâmico do link gerado pelo binário antes de executar o arquivo binário e o incorpora no corpo do binário para otimizar o desempenho do aplicativo. Hmm, mesmo sendo para melhorar o desempenho, tudo bem reescrever o binário sozinho. "Às vezes a reescrita falha e o binário está quebrado, mas teheper ♥" ou algo assim**!** ── Quando pesquisei, parece ser um app prejudicial e sem lucro. Por que o CentOS instala uma bomba assim por padrão?
Ah, o CentOS finalmente percebeu. Para o perigo dele (risos)
Bem, é por isso que quero que você saia de um cara tão perigoso o quanto antes. Agora, como desativar os pré-links. Tem alguns abaixo.
- Desinstalar o pré-link do cron.daily
- Especifique como uma lista negra de arquivos e caminhos que você não quer reescrever binariamente para /etc/prelink.conf
- Defina PRELINKING=no em /etc/sysconfig/prelink
Primeiro, não quero mexer muito porque o cron.daily também contém outras configurações de middleware (porque não quero se afetar outras coisas). Segundo, o prelink em si não é uma lista negra, mas é difamatório e desconfortável ligar para apps que estão rodando normalmente sem uma lista negra direta. … Então, isso é uma rejeição (risos) A última configuração é a mais apropriada. O CentOS 7 também desativa dessa forma, e quando quero mudar de novo, simplesmente volto para sim (bem, esse momento não chega mais...).
Então, vamos desativar o pré-link no método 3. Depois de desligá-lo, reinicie o servidor só por precaução, e você pode dormir com o travesseiro bem alto.
Conclusão
Obrigado por ler até o final e por dedicar seu tempo para ler os artigos longos e diversos. O resumo deste extenso artigo está resumido em uma palavra da seguinte forma.
Se seu ambiente Ruby on Rails parar de repente, é provável que o pré-link esteja corrompendo seus arquivos binários Rails
No entanto, mesmo em um ambiente que não usa Rails, é basicamente mais seguro desativar o prelink em um ambiente CentOS.