Outros processos assumem a porta 80 ao reiniciar o Apache - por que e como resolver?

3

Eu tenho um servidor CentOS 5.5 executando o Apache na porta 80, bem como alguns outros aplicativos. Tudo funciona bem até que eu por algum motivo precisa reiniciar o processo httpd. Isso retorna:

sudo /etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: (98)Address already in use: make_sock: could not bind to address [::]:80
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs

Primeiro, pensei que talvez o httpd tivesse congelado e ainda estivesse funcionando, mas esse não era o caso. Então eu corri netstat para descobrir o que estava usando a porta 80:

sudo netstat -tlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 *:7203                      *:*                         LISTEN      24012/java          
tcp        0      0 localhost.localdomain:smux  *:*                         LISTEN      3547/snmpd          
tcp        0      0 *:mysql                     *:*                         LISTEN      21966/mysqld        
tcp        0      0 *:ssh                       *:*                         LISTEN      3562/sshd           
tcp        0      0 *:http                      *:*                         LISTEN      3780/python26

Acontece que meu processo python assumiu a escuta http no instante em que o httpd estava reiniciando. Então, eu matei python e tentei iniciar o httpd novamente - mas corri para o mesmo erro. Netstat novamente:

sudo netstat -tlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 *:7203                      *:*                         LISTEN      24012/java          
tcp        0      0 localhost.localdomain:smux  *:*                         LISTEN      3547/snmpd          
tcp        0      0 *:mysql                     *:*                         LISTEN      21966/mysqld        
tcp        0      0 *:ssh                       *:*                         LISTEN      3562/sshd           
tcp        0      0 *:http                      *:*                         LISTEN      24012/java

Agora, meu processo de java tomou conta do http. Eu matei isso também e poderia, então, reiniciar com sucesso o httpd.

Mas esta é uma solução terrível. Por que esses processos python e java começam a escutar a porta 80 assim que o httpd é reiniciado? Como resolver?

Dois outros comentários. 1) Os processos java e python são iniciados pelo apache a partir de um script php. Mas quando o apache é reiniciado, eles não devem ser afetados. E 2) Eu tenho a mesma configuração em duas outras máquinas rodando Ubuntu e não há problema lá.

Alguma idéia?

Editar:

O processo Java ouve a porta 7203 e o processo python supostamente não ouve nenhuma porta. Por algum motivo, eles começam a escutar a porta 80 quando o apache é reiniciado. Isso não aconteceu antes. No Ubuntu corre bem. Por alguma razão, na minha máquina atual do CentOS 5.5, surge esse problema.

    
por user72149 25.02.2011 / 05:00

4 respostas

2

O problema pode ser o modo como o Apache inicia os subprocessos. Eles podem ser gerados por bifurcação e permitir que os processos clonados do Apache se tornem outros processos. Cada clone herda todas as alças de arquivo abertas do processo pai, incluindo o identificador aberto da porta TCP 80.

O Netstat mostra apenas um aplicativo associado ao identificador de arquivo aberto, enquanto três processos mantêm o identificador aberto.

Possíveis soluções para o seu problema:

  1. Se for importante manter os subprocessos em execução durante uma reinicialização do Apache, a solução mais simples seria iniciar os 3 Processos como serviços de sistema separados.

  2. Se eles dependem de um Apache em execução, um comando 'apache stop' também deve finalizá-los. Isso pode ser feito editando o script /etc/init.d/apache.

  3. Se você for forçado a iniciá-los a partir do Apache, será necessário iniciá-los como "processos daemon" reais!

Eu escrevi um criador de daemon para um aplicativo PyQt inspirado no link . Você poderia iniciar este script a partir do Apache, chamar exec_as_daemon para cada um dos seus subprocessos e fechá-lo.

# Copyright: (c) 2011 phobie <[email protected]>
# License: CC-by-sa 3.0
import os
def exec_as_daemon(s_path_cmd, l_args=[]):
    i_pid = os.fork()
    if i_pid != 0:
        # Always remember to gobble your zombie children
        os.wait()
        # Back to parent
        return
    # Detach from parent
    os.setsid()
    # Do not block any mounts
    os.chdir('/')
    # Reset file creation rights
    os.umask(0)
    i_pid = os.fork()
    if i_pid != 0:
        # Close the direct child process
        os._exit(0)
    # Get the maximum count of open file handles
    try:
        import resource
        i_fd_max = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
        if i_fd_max == resource.RLIM_INFINITY:
            i_fd_max = 1024
    except ImportError:
        i_fd_max = 1024
    # Try to close all possible file handles
    for i_cur_fd in range(0, i_fd_max):
        try:
            os.close(i_cur_fd)
        except OSError:
            pass
    # Assosiate STDIN with /dev/null
    os.open(os.devnull if hasattr(os, "devnull") else '/dev/null', os.O_RDWR)
    # STDOUT to /dev/null
    os.dup2(0, 1)
    # STDERR to /dev/null
    os.dup2(0, 2)
    l_args.insert(0, s_path_cmd)
    # Let the clone become a other process
    os.execv(s_path_cmd, l_args)

if __name__ == '__main__':
    exec_as_daemon('/usr/bin/java', ['-jar', '/usr/local/bin/apache_helper_daemon.jar'])
    exec_as_daemon('/usr/local/bin/apache_helper_daemon.py')
    
por 25.10.2011 / 01:04
0

Em teoria, apenas um processo deve estar escutando em um determinado IP / port. Se você precisar de mais de um aplicativo para escutar na mesma porta, precisará de um tipo de configuração de proxy reverso que determinará, com base no conteúdo recebido, qual processo receberá a mensagem.

Seria útil saber o que seus aplicativos em Python e Java estão fazendo. Se eles também são servidores que escutam na porta 80, eles estão ficando presos no ponto de abertura da porta 80 para escutar enquanto o Apache está em execução e assim que você mata o Apache, o próximo na fila de processo é acessado e abre a porta. Você precisará alterar seus códigos Python e Java para ouvir em portas diferentes.

    
por 25.02.2011 / 05:09
0

Você não está conseguindo limpar o desligamento do processo mestre do apache e as crianças ficam penduradas nos soquetes. Em vez de executar o reinício, execute um serviço httpd stop. Se isso não conseguir sair corretamente, será necessário investigar melhor os aplicativos java e python que você ativou por meio do apache.

Se um serviço httpd stop não funcionar corretamente, desinstale seus aplicativos java e python até que você possa reiniciar corretamente. Em seguida, investigue por que esses processos não terminam corretamente.

    
por 12.04.2011 / 08:35
0

É estranho o que está acontecendo. Como solução alternativa, use reload em vez restart :

sudo /etc/init.d/httpd reload

Tente descobrir sobre o novo processo java e python. Você pode tentar descobrir quando eles começaram e os parâmetros da linha de comando:

ps -edf|egrep 'python|java|PID'

Verifique também o /etc/init.d/httpd para qualquer coisa relacionada a java ou python.

Use uma ferramenta de auditoria para descobrir quando um programa é iniciado, por quem, etc.:

por 25.10.2011 / 02:54