Análisis de pila: ubicación del problema del servidor

1. Ubicación de los problemas comunes del servidor:

1. Problemas comunes del servidor:

En el desarrollo diario, nuestros problemas comunes de servidor se pueden clasificar en las siguientes categorías:

  • Problema de sobrecarga de la CPU
  • problema de memoria alta
  • Problema de E/S de disco
  • problema de Internet

2. La idea general de la ubicación del problema del servidor:

Cuando hay un problema con el servidor, generalmente podemos ubicarlo de acuerdo con las siguientes ideas

  • ① Si se ha lanzado una versión recientemente, primero analice si hay un problema con la última versión del código del registro de envío de código
  • ② Use ps, top y otros comandos para analizar el estado del hilo
  • ③ Primero desconecte el servidor anómalo y mantenga el entorno del servidor, luego use jstack para exportar la información de la instantánea del subproceso y use jmap para exportar el registro de memoria de la pila para su análisis. Este comando afectará el rendimiento del servidor en línea, por lo que el servidor está desconectado antes ejecución para evitar el impacto en los usuarios

        Para problemas de E/S de disco y problemas de red, generalmente podemos localizarlos rápidamente, por lo que no los discutiremos en este artículo. Aquí presentamos principalmente cómo localizar y resolver el problema del uso elevado de memoria de CPU y Java.

En segundo lugar, el problema de posicionamiento de la CPU:

1. ¿Cuáles son las operaciones intensivas de CPU en Java?

  • GC frecuente: si el volumen de acceso es alto y la asignación de memoria es demasiado rápida, puede causar GC frecuente o incluso FGC, lo que hará que la CPU se dispare.
  • Cambio de contexto de subprocesos: el estado de una gran cantidad de subprocesos cambia entre Bloqueado (bloqueo en espera, IO en espera, etc.) y En ejecución. Esto puede suceder fácilmente cuando la contención de bloqueo es alta.
  • Algunos subprocesos están realizando operaciones sin bloqueo como bucles infinitos
  • Serializar y deserializar
  • expresión regular

2. Pasos de posicionamiento altísimos de la CPU del programa Java:

(1) Use el comando superior para encontrar el ID de subproceso que consume la mayor cantidad de CPU:

parte superior –Hp PID

(2) Convierta la identificación del subproceso que consume la mayor parte de la CPU en hexadecimal, porque el número de subproceso en el archivo de instantánea del subproceso se registra en hexadecimal:

printf '%x\n' PID

(3) Desconecta el servidor en cuestión, luego usa jstack para exportar la información de la instantánea del subproceso y verifica qué está haciendo el ID del subproceso encontrado en el paso (2):

jstack pid | tiempo de agarre -A 30

        En este punto, hemos localizado qué tipo de operación está realizando el subproceso anormal y podemos tomar soluciones específicas para tratar el problema.

En tercer lugar, el método de posicionamiento del uso de la memoria de Java es demasiado alto:

        La memoria alta generalmente es causada por pérdidas de memoria y desbordamientos de memoria. Primero verifique si el registro de instantáneas del subproceso es anormal, y luego use jmap -dump para exportar el registro de la pila para ver qué objetos están ocupando espacio. A menudo es causado por una operación incorrecta o imprecisa en el código, y puede haber demasiados subprocesos creados. Conducir a

Exportar registro de pila: jmap -dump:format=b,file=filename[pid]

Luego use IBM HeapAnalyzer o Eclipse Memory Analyzer para analizar

En cuarto lugar, descripción del análisis del archivo de instantáneas del subproceso jstack:

4.1 Rastreo de la pila del estado de la instantánea del subproceso Descripción:

4.1.1, interbloqueo: subproceso de interbloqueo, una situación en la que múltiples subprocesos ocupan recursos entre sí y esperan el uno al otro todo el tiempo, lo que lleva al bloqueo.

4.1.2, ejecutable: Indica que el hilo tiene todas las condiciones de ejecución, o el estado del hilo en ejecución

4.1.3 Esperando la entrada del monitor y en Object.wait(): Monitor es el medio principal del mecanismo de bloqueo sincronizado de Java para lograr la exclusión mutua y la cooperación de subprocesos. Puede considerarse como un objeto o bloqueo de clase. Cada objeto tiene uno y solo un monitor de bloqueo, cada monitor solo puede ser propiedad de un subproceso al mismo tiempo, el subproceso es "Subproceso activo" y otros subprocesos son "Subproceso en espera", "Subproceso en espera" se almacena en dos conjuntos "EntrySet" y "WaitSet" dentro de la espera. El estado del subproceso en espera en "EntrySet" es "Esperando la entrada del monitor", y el estado del subproceso en espera en "WaitSet" es "en Object.wait()". El segmento de código protegido por sincronizado es la sección crítica. Cuando un subproceso solicita ingresar a la sección crítica, ingresa a la cola "EntrySet". Cuando el subproceso obtiene el Monitor e ingresa a la sección crítica, si se encuentra que las condiciones para el subproceso para continuar ejecutándose no se cumplen, llama al método wait() del objeto, abandona el Monitor e ingresa a la cola "WaitSet". la cola "WaitSet" tiene la oportunidad de ir a competir.

4.1.4, esperando en condición: esperando recursos o esperando que ocurra una determinada condición, que debe analizarse en combinación con stacktrace:

(1) Lo más común es que el subproceso esté en estado de suspensión, esperando ser despertado.

(2) La situación común es esperar la red IO. Antes de que se introduzca NIO, para cada conexión de red, hay un subproceso correspondiente para manejar las operaciones de lectura y escritura de la red. Incluso si no hay datos legibles y escribibles, el subproceso sigue siendo bloqueado en operaciones de lectura y escritura. Después de la introducción de NIO, si encuentra que una gran cantidad de subprocesos están bloqueados en la red, puede ser un síntoma de un cuello de botella en la red, porque el bloqueo de la red evita que los subprocesos se ejecuten:

  • Una situación es que la red está muy ocupada, casi consumiendo todo el ancho de banda, y todavía hay muchos datos esperando que la red los lea y escriba;
  • Otra situación puede ser que la red esté inactiva, pero por problemas como el enrutamiento, los paquetes no puedan llegar con normalidad.

4.1.5 Bloqueado: El bloqueo de subprocesos significa que durante la ejecución del subproceso actual, los recursos requeridos han estado esperando durante mucho tiempo pero no se han obtenido, y son marcados como bloqueados por el administrador de subprocesos del contenedor, que puede ser entendido como un hilo que espera el tiempo de espera del recurso.

4.2 El fenómeno al que se debe prestar atención en el archivo de instantáneas del subproceso:

(1) subproceso IO que se ejecuta de forma continua ejecutable:

        Las operaciones de IO se pueden bloquear en el estado RUNNABLE, como interbloqueo de la base de datos, lectura y escritura de la red, por lo que se debe prestar especial atención al análisis del estado real del subproceso de IO. En términos generales, las llamadas de IO capturadas en RUNNABLE son problemáticas. .

        La siguiente pila muestra: el estado del subproceso es EJECUTABLE, la pila de llamadas está en SocketInputStream o SocketImpl, socketRead0 y otros métodos. La pila de llamadas contiene paquetes relacionados con jdbc y es probable que se produzca un punto muerto en la base de datos.

"d&a-614" daemon prio=6 tid=0x0000000022f1f000 nid=0x37c8 runnable
[0x0000000027cbd000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at oracle.net.ns.Packet.receive(Packet.java:240)
at oracle.net.ns.DataPacket.receive(DataPacket.java:92)
at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:172)
at oracle.net.ns.NetInputStream.read(NetInputStream.java:117)
at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1034)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:588)

La siguiente pila es el caso del grupo de subprocesos:

"http-bio-8082-exec-3858" #50615 daemon prio=5 os_prio=0 tid=0x00007f7cc002f800 nid=0xc5c0 runnable [0x00007f7c34659000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:516)
	at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501)
	at org.apache.coyote.http11.Http11Processor.setRequestLineReadTimeout(Http11Processor.java:167)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:946)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
	- locked <0x0000000093db7ce8> (a org.apache.tomcat.util.net.SocketWrapper)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

(2) Fenómeno de interbloqueo:

        jstack nos ayudará a analizar la situación de interbloqueo, que se puede ubicar directamente, y la situación específica se puede analizar y procesar.

(3) Bucle infinito:

        La manifestación del estado de bucle infinito es que la CPU se dispara, verifica el estado de ejecución del subproceso para encontrar un subproceso, toma mucho tiempo para el segmento de tiempo de ejecución de la CPU y un uso elevado de la CPU, imprime el registro de la pila de subprocesos y encuentra que un el hilo ha estado en el estado Runnable

en estado ejecutable

(4) El cambio de contexto del subproceso es demasiado frecuente:

① JVM tiene un programador de subprocesos, que se utiliza para determinar qué subproceso ejecutar en qué momento. Hay dos tipos principales de programadores: programador de subprocesos preventivo y programador de subprocesos cooperativo. Cada subproceso puede tener su propia prioridad, pero la prioridad no significa que el subproceso de alta prioridad se programará, sino que la CPU lo seleccionará aleatoriamente.

  • Programación preventiva de subprocesos: cuando un subproceso está ejecutando su propia tarea, aunque la tarea no se haya completado, la CPU lo obligará a suspender, permitiendo que otros subprocesos ocupen el derecho de usar la CPU.
  • Programación cooperativa de subprocesos: cuando un subproceso está ejecutando su propia tarea, no se permite que se interrumpa en el medio. Debe esperar a que el subproceso actual complete la ejecución de la tarea antes de liberar su posesión de la CPU, y otros subprocesos pueden adelantarse al UPC.

② La manifestación de este tipo de problema es a menudo que la CPU y la memoria están disparadas, y hay una gran cantidad de subprocesos en jstack que están en estado de espera, timed_waiting, porque la CPU maneja la coordinación de la programación de ejecución de los subprocesos. , y la CPU es responsable de asignar segmentos ejecutables a cada subproceso. , el procesamiento frecuente de la programación de estos subprocesos hará que la carga de la CPU sea demasiado alta

(5) Una gran cantidad de subprocesos de GC:

        La manifestación de este tipo de problema es que hay una gran cantidad de subprocesos de GC en jstack, y el subproceso de GC consume la CPU más alta, lo que a menudo se denomina GC frecuente:

El comando jstat puede ver el uso de varias partes de la memoria del montón y la cantidad de clases cargadas. El formato del comando es el siguiente:

jstat [-opciones de comando] [vmid] [tiempo de intervalo/ms] [número de consultas]

raíz @ 8d36124607a0: / # jstat -gcutil 9 1000 10
  S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
  0.00 0.00 0.00 7517 7.70 0.0.635
  0,00 0.00 0.00 0.06 0.930 6617 7.822 8.752
  0.00 0.00 0.00 0.08 59.09 59.60 3351 59.08 59.09 59.60 3351 0,943 6701 7,924 8,867
  0,00 0,00 0,00 0,08 59,09 59,60 3397 0,955 6793 8,029 8,984

Supongo que te gusta

Origin blog.csdn.net/a745233700/article/details/122660058
Recomendado
Clasificación