2014-05-19 10 views
5

kernel Linux> = 3.9 permettono la condivisione delle prese tra i processi con in-kernel bilanciamento del carico impostando SO_REUSEPORT: http://lwn.net/Articles/542629/È possibile utilizzare SO_REUSEPORT su socket di dominio Unix?

Come può essere utilizzato per prese di tipo AF_UNIX?

Sembra, funziona solo con TCP, non con socket di dominio Unix.

Ecco un programma di test Python:

import os 
import socket 

if not hasattr(socket, 'SO_REUSEPORT'): 
    socket.SO_REUSEPORT = 15 

if True: 
    # using TCP sockets 
    # works. test with: "echo data | nc localhost 8888" 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) 
    s.bind(('', 8888)) 
else: 
    # using Unix domain sockets 
    # does NOT work. test with: "echo data | nc -U /tmp/socket1" 
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) 
    try: 
     os.unlink("/tmp/socket1") 
    except: 
     pass 
    s.bind("/tmp/socket1") 

s.listen(1) 
while True: 
    conn, addr = s.accept() 
    print('Connected to {}'.format(os.getpid())) 
    data = conn.recv(1024) 
    conn.send(data) 
    conn.close() 

Start 2 casi, e il test eseguendo i seguenti più volte:

  • echo data | nc localhost 8888 per TCP
  • echo data | nc -U /tmp/socket1 per socket di dominio Unix

Quando si utilizza TCP, l'arrivo i client saranno bilanciati con entrambi i server. Con i socket di dominio Unix, tutti i client in arrivo si collegano all'ultimo server avviato.

+0

Prima frase dell'articolo che si riferisce: 'Una delle funzionalità unite nel ciclo di sviluppo 3.9 era il supporto TCP e UDP per l'opzione socket SO_REUSEPORT'. Sembra essere supportato solo per TCP e UDP. –

+0

Non ho una risposta esatta ma sembra che il kernel non abbia mezzi per bilanciare il carico dei socket UNIX. Questo ha molte informazioni utili: http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-the-differ-do-the-mean-t –

+0

@AlexShkop Grazie! FWIW, posso impostare l'opzione su UDS e questo consentirà a più processi di aprire lo stesso UDS (ascolto). Quando l'opzione non è impostata, non consente di farlo. Tuttavia, non carica il bilanciamento. Sto cercando una risposta autorevole che supporti il ​​comportamento osservato o mostri come eseguire l'UDS condiviso bilanciato LB. – oberstet

risposta

4

Questa patch del kernel specifica è documentato qui:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d

Come si può vedere dalla lista dei file rattoppate, la patch influenzato solo le prese net/ipv4 e net/ipv6. I socket di dominio Unix sono implementati in net/unix. Quindi, la risposta è: no, SO_REUSEPORT non funzionerà con socket di tipo AF_UNIX.

+0

OK. Grazie! Questa è una risposta autoritaria - sebbene sia negativa = ( – oberstet

+0

Mi spiace deluderti, ma forse puoi passare alle prese normali? –

+0

La risposta sembra essere ancora aggiornata.Ancora approverò l'aggiornamento autorevole :) –

1

Una piccola patch, che aggiunge il supporto per SO_REUSEPORT su socket UNIX was posted, ma è stata respinta. Questa patch, tuttavia, non implementava il bilanciamento del carico su più socket, causava il solo errore di bind(), se il file socket esiste già.

Questo caso d'uso è stata ritenuta

un caso d'angolo davvero strano dal punto di vista di un utente

Quindi c'è ancora la possibilità, che una patch diverso, che sarebbe implementare il bilanciamento del carico per UNIX prese tramite SO_REUSEPORT, sarebbero accettati.