5 votos

Cómo Manejar una Súbita Explosión de Nuevas Conexiones HTTPS?

Tengo una flota de Java Vertx servidores detrás de un equilibrador de carga que maneja ovas de tráfico. Un minuto puede ser el manejo de 150k r/m, el siguiente puede ser el manejo de 2mm r/m, luego a la derecha de nuevo a 150k r/m. Me estoy encontrando que durante estos aumentos, la totalidad de la flota puede dejar de responder durante unos minutos y colocar conexiones, mientras que el cpu y mem presión sobre cualquiera de ellas apenas hits 50% de utilización.

Para probar exactamente qué está causando la interrupción, me la instalación de un único servidor de prueba que coincida con las especificaciones de uno en mi producción de la flota para ver cuánto podría lanzar en él antes de que se dio a cabo. Mi prueba implica el uso de otros 10 máquinas, cada una de las cuales open 500 conexiones https al servidor y enviar 1mm peticiones acerca de 2kb por solicitud de la carga útil. Esto totales en los 5k conexiones simultáneas abierto, el envío de un total de 10 mm de solicitudes, aproximadamente el 20 gb de transferencia de datos.

Una vez que la apertura de conexiones que puedo disparar sobre 700k solicitudes por minuto. Puedo controlar la disponibilidad de los servidores simplemente por hacer un pedido a un proveedor de estaciones de trabajo y la grabación el tiempo de respuesta. El tiempo de respuesta es rápido, decenas de milisegundos. Estoy contento con estos resultados.

Pero antes de que el diluvio de datos empieza a entrar, tesis 10 máquinas deben, en primer lugar 5k conexiones. Durante este tiempo, el servidor no responde y puede incluso tiempo de espera al intentar comprobar la salud de extremo. Creo que esto es lo que está causando que las interrupciones en mi producción de la flota - el aumento repentino de nuevas conexiones. Una vez que se establecen las conexiones, el servidor no tiene problemas en el manejo de todos los datos que llegan.

He actualización de la nofile ulimit, neto.núcleo.netdev_max_backlog, neto.ipv4.tcp_max_syn_backlog, y en la red.núcleo.somaxconn, pero todavía se bloquea cuando se recibe una ráfaga de 5k nuevas solicitudes de conexión dentro de un par de segundos cada uno.

Hay algo que yo pueda hacer para establecer nuevas conexiones más rápido?

Editar:

El real server se ejecuta en una ventana acoplable contenedor. Mi red configuración no se aplica al contenedor. Vamos a probar que la siguiente y ver si hace una diferencia.

Editar Editar:

Todo en SSL. De hacer tantas conexiones que rápidamente a través de HTTP plano está cerca de la instantánea. Por lo que he conseguido averiguar cómo establecer conexiones TLS más rápido.

Editar Editar Editar:

He encontrado que el nativo de java de seguridad ssl controlador era el cuello de botella. El cambio a netty-tcnative (aka OpenSSL) bastante resuelto mi problema con HTTPS.

4voto

Mehr Gol Puntos 8

Gracias @MichaelHampton por su ayuda.

He encontrado una solución para mi problema, y espero que pueda ayudar a otros (especialmente si usted está utilizando Java).

He escuchado muchas sugerencias para simplemente aumentar nofiles para permitir más conexiones, pero me gustaría empezar reiterando que el problema no es que el servidor no es capaz de hacer más conexiones, es que no es capaz de hacer las conexiones lo suficientemente rápido y soltar las conexiones.

Mi primer intento de resolver este problema fue el incremento de la cola de conexión a través de la net.ipv4.tcp_max_syn_backlog, net.core.somaxconn y de nuevo en la aplicación de configuración de servidor donde corresponda. Para vertx esto es server.setAcceptBacklog(...);. Esto se tradujo en la aceptación de más conexiones en la cola, pero no el establecimiento de las conexiones más rápido. A partir de una conexión de punto de vista del cliente, ya no estaban en restablecer las conexiones debido a desbordamiento, estableciendo conexiones sólo se tomó mucho más tiempo. Por esta razón, el aumento de la conexión de la cola no era una solución real y traspasado sólo un problema por otro.

Tratando de estrechar abajo donde en el proceso de conexión en el cuello de botella estaba, he probado los mismos parámetros con HTTP en lugar de HTTPS y encontró que el problema desapareció por completo. Mi problema era con el TLS Handshake de sí mismo y de los servidores de la capacidad para satisfacerla.

Con algo más de cavando mi propia aplicación, he encontrado que la sustitución de Javas defecto SSLHandler con un nativo de uno (OpenSSL) aumentó considerablemente la velocidad de conexión a través de HTTPS.

Aquí fueron los cambios que he hecho para mi específicos de la aplicación (utilizando Vertx 3.9.1).

  1. Agregar netty-tcnative dependencias
<!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-tcnative</artifactId>
    <version>2.0.31.Final</version>
    <classifier>osx-x86_64</classifier>
    <scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/io.netty/netty-tcnative -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-tcnative</artifactId>
    <version>2.0.31.Final</version>
    <classifier>linux-x86_64-fedora</classifier>
    <scope>compile</scope>
</dependency>

La primera dependencia es para osx a prueba en tiempo de ejecución. El segundo es para centos linux cuando se compila. linux-x86_64 también está disponible para otros sabores. Traté de usar boringssl porque openssl no admite ALPN pero después de muchas horas, no podía llegar a trabajar por lo que he decidido vivir sin http2 por ahora. Con la mayoría de las conexiones sólo el envío de 1-2 pequeños solicitudes antes de desconectar esto realmente no es un problema para mí de todos modos. Si usted puede usar boringssl en su lugar, probablemente ese sea el preferido.

  1. Porque no estoy usando un uber versión de la dependencia. Lo necesario para instalar el sistema operativo de las dependencias de centos. Esto se suma a la Dockerfile
RUN yum -y install openssl
RUN yum -y install apr
  1. Decirle a la vertx server para utilizar OpenSSL en lugar de la versión de Java, establecer el OpenSSL opciones en el servidor (incluso si sólo el objeto predeterminado)
httpServerOptions.setOpenSslEngineOptions(new OpenSSLEngineOptions());
  1. Finalmente, en mi ejecute el script, he añadido el io.netty.handler.ssl.openssl.useTasks=true opción para Java. Esto indica que el ssl controlador de utilizar tareas al manejo de las peticiones de modo que es no-bloqueo.
java -Dio.netty.handler.ssl.openssl.useTasks=true -jar /app/application.jar

Después de estos cambios, yo soy capaz de establecer conexiones mucho más rápido y con menos sobrecarga. Lo que llevó a decenas de segundos antes y se tradujo en frecuentes de conexión se restablece ahora tarda de 1-2 segundos, sin restablece. Podría ser mejor, pero una gran mejora desde donde yo estaba.

2voto

Kirill Osenkov Puntos 3902

Bonito solución!.

Por lo que parece ser la capa SSL, sin duda, tiene que hacer mucho más en el procesamiento, en términos de la red de apretones de manos, y crypto transformaciones que tomar los recursos. A menos que su SSL puede descargar de algunos de los tratamientos sobre el hardware, SSL sin duda puede aumentar la carga en los servidores, y como se enteró de que no todas las bibliotecas SSL son iguales!.

Estos problemas son un gran candidato para un front-end de proxy inverso. Este ideal puede ser el lugar antes de su aplicación, y manejar todas las conexiones SSL a los clientes, y, a continuación, haga http a su parte final.

Su aplicación original, tiene un poco menos, como tu front end proxy inverso puede absorber todo el SSL de trabajo, y la conexión tcp de gestión.

Apache y NGNIX puede hacer esto, y tiene muy pocas opciones para el equilibrio de carga de las conexiones a la menor carga de servidor back-end.

Usted encontrará que NGNIX puede hacer SSL terminaciones mucho más rápido que java puede, e incluso si java se puede, su distribuir el procesamiento de la administración de la conexión a través de máquinas, reduciendo así la carga (memoria/cpu/e / s de disco) en el servidor back-end. Usted consigue el efecto secundario de hacer que la configuración de la parte de atrás más simple.

La desventaja es el uso de http entre el proxy y aplicaciones, que en algunos ultra entornos seguros no es deseable.

Buena Suerte!

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: