2010-02-18 12 views
37

Tengo una aplicación java en Linux que abre el socket UDP y espera mensajes.¿Cómo controlar el espacio disponible del búfer UDP de Linux?

Después de un par de horas bajo mucha carga, hay una pérdida de paquetes, es decir, los paquetes son recibidos por kernel pero no por mi aplicación (vemos los paquetes perdidos en sniffer, vemos paquetes UDP perdidos en netstat, no lo hacemos) t ver esos paquetes en nuestros registros de la aplicación).

Intentamos ampliar los buffers de socket, pero esto no ayudó, comenzamos a perder paquetes más tarde que antes, pero eso es todo.

Para la depuración, quiero saber cuán lleno está el buffer OS udp, en cualquier momento dado. Busqué en Google, pero no encontré nada. ¿Me puedes ayudar?

P.S. Chicos, soy consciente de que UDP no es confiable. Sin embargo, mi computadora recibe todos los mensajes UDP, mientras que mi aplicación no puede consumir algunos de ellos. Quiero optimizar mi aplicación al máximo, ese es el motivo de la pregunta. Gracias.

Respuesta

27

Linux proporciona los archivos /proc/net/udp y /proc/net/udp6, que enumera todos los sockets abiertos para UDP (IPv4 e IPv6, respectivamente). En ambos, las columnas tx_queue y rx_queue muestran las colas salientes y entrantes en bytes.

Si todo funciona como se espera, generalmente no verá ningún valor diferente a cero en esas dos columnas: tan pronto como su aplicación genere paquetes, se enviarán a través de la red, y tan pronto esos paquetes lleguen de la red, la aplicación se despertará y recibirá (la llamada recv vuelve inmediatamente). Puede ver que rx_queue se activan si su aplicación tiene el socket abierto pero no está invocando recv para recibir los datos, o si no está procesando dichos datos lo suficientemente rápido.

+2

Gracias por la rx_queue, para el resto - ver la actualización) –

+1

@Juliano ¿Quién dice que puede elegir el protocolo que utilizará? Tal vez está implementando un protocolo basado en udp para servir a los clientes existentes. – steffen

+2

El póster quiere saber sobre la supervisión de las estadísticas de UDP, no las opiniones sobre qué protocolo usar. Al identificar primero en qué parte de las capas se está produciendo la pérdida, se puede trabajar en una solución. – RickS

-1

El proceso es simple:

  1. Si se desea, hacer una pausa en el proceso de aplicación.

  2. Abra el zócalo UDP. Puede engancharlo del proceso en ejecución usando /proc/<PID>/fd si es necesario. O puede agregar este código a la aplicación y enviarle una señal: ya tendrá el socket abierto, por supuesto.

  3. Llame al recvmsg en un circuito cerrado lo más rápido posible.

  4. Cuenta cuántos paquetes/bytes tienes.

Esto descartará cualquier datagrama actualmente almacenado en el búfer, pero si eso rompe su aplicación, su aplicación ya estaba rota.

+0

Estaba a punto de rechazar esta respuesta, pero pensándolo mejor es graciosa. Solo espero que nadie haya intentado implementar esto :) – Navin

4

rx_queue le dirá la longitud de la cola en un instante dado, pero no le indicará qué tan completa ha estado la cola, es decir, la marca de agua alta. No hay forma de controlar constantemente este valor, y no hay forma de obtenerlo mediante programación (consulte How do I get amount of queued data for UDP socket?).

La única forma en que puedo imaginar el control de la longitud de la cola es mover la cola a su propio programa. En otras palabras, inicie dos hilos: uno lee el zócalo lo más rápido posible y descarga los datagramas en su cola; y el otro es su programa que extrae de esta cola y procesa los paquetes. Por supuesto, esto supone que puede asegurar que cada hilo está en una CPU separada. Ahora puede monitorear la longitud de su propia cola y realizar un seguimiento de la marca Highwater.

46

UDP es un protocolo perfectamente viable. ¡Es el mismo viejo caso de la herramienta correcta para el trabajo correcto!

Si tiene un programa que espera datagramas UDP, y luego se apaga para procesarlos antes de volver a esperar otro, entonces su tiempo de procesamiento transcurrido debe ser siempre más rápido que la peor tasa de llegada de datagramas. Si no es así, la cola de recepción del socket UDP comenzará a llenarse.

Esto puede tolerarse para ráfagas cortas. La cola hace exactamente lo que se supone que debe hacer: poner los datagramas en cola hasta que esté listo. Pero si la tasa de llegada promedio regularmente causa un retraso en la cola, es hora de rediseñar su programa. Aquí hay dos opciones principales: reducir el tiempo de procesamiento transcurrido a través de técnicas de programación astutas, y/o multi-hilo de su programa. También se puede emplear el equilibrio de carga en varias instancias de su programa.

Como se mencionó, en Linux puede examinar el sistema de archivos proc para obtener el estado sobre qué está haciendo el UDP. Por ejemplo, si cat el nodo /proc/net/udp, me sale algo como esto:

$ cat /proc/net/udp 
    sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops    
    40: 00000000:0202 00000000:0000 07 00000000:00000000 00:00000000 00000000  0  0 3466 2 ffff88013abc8340 0   
    67: 00000000:231D 00000000:0000 07 00000000:0001E4C8 00:00000000 00000000 1006  0 16940862 2 ffff88013abc9040 2237  
122: 00000000:30D4 00000000:0000 07 00000000:00000000 00:00000000 00000000 1006  0 912865 2 ffff88013abc8d00 0   

partir de esto, puedo ver que una toma de propiedad de identificador de usuario 1006, está escuchando en el puerto 0x231D (8989) y que el recibir la cola está a aproximadamente 128KB. Como 128 KB es el tamaño máximo en mi sistema, esto me dice que mi programa es lamentablemente débil para mantenerse al día con los datagramas que llegan. Hasta el momento, se han producido 2237 caídas, lo que significa que la capa UDP no puede poner más datagramas en la cola de los sockets, y debe soltarlos.

Puede ver el comportamiento de su programa a lo largo del tiempo, p. usando:

watch -d 'cat /proc/net/udp|grep 00000000:231D' 

Tenga en cuenta también que el comando netstat hace de la misma cosa: netstat -c --udp -an

Mi solución para mi programa de pito, será multi-hilo.

¡Salud!

+0

¿Cómo sabes que el tamaño máximo de cola de udp de tu sistema es de 128 KB? – Chinaxing

+2

@Chinaxing 'cat/proc/sys/net/core/rmem_max' – wakjah

Cuestiones relacionadas