Pensando después de un hilo java.lang.OutOfMemoryError (OOM) co-check

El lunes pasado, mi colega me pidió que ayudara a investigar un problema de OOM en línea. El procedimiento de la investigación no se discutirá aquí. En realidad, es similar a un procedimiento de OOM que he coordinado previamente. Para la investigación anterior, consulte este artículo: A través del código fuente de mybatis, analícelo una vez por mybatis Co-investigación de OutOfMemoryError causado por un uso inadecuado

Hoy hablo principalmente de los resultados y resumo los resultados:

Esta vez, OOM se produjo principalmente debido a una función de consulta utilizada con poca frecuencia, una consulta de tabla completa, porque la cantidad de datos era demasiado grande, lo que provocó un desbordamiento de la memoria del montón

Primero veamos un sql (se enumera un sql similar, no un sql en línea), un fragmento de mybatis xml:

Este fragmento es el sql que una función de consulta de la página eventualmente ejecutará Los tres valores en la condición where provienen de la entrada del usuario en la página.

select * from t_user usr
<where>
<if test=" email != null" >
and usr.email = #{email ,jdbcType= varchar}
</if>
<if test=" certNo!= null" >
and usr.cert_no = #{ certNo,jdbcType= varchar}
</if>
</where> 

Todas las condiciones donde aquí son juicios vacíos. En producción, sucedió que el usuario no completó, y el sql ejecutado final se convirtió en select * from t_user usr, lo que provocó que se consultaran todos los datos de la tabla, y había 1000W en esta tabla Los datos anteriores, el usuario hace clic en dos puntos más, el sistema se bloquea

Habla sobre algunos problemas aquí

1. Los datos no están paginados

Cuando tenemos demasiados datos, la consulta debe ser paginación y es paginación de datos. Es mejor no hacer paginación en el lado de la memoria y de la página. Cómo optimizar el rendimiento de una sola tabla después de que las otras tablas de datos de mysql alcancen decenas de millones de filas no será particularmente bueno , Aquí todos pueden considerar hacer alguna optimización de la subbase de datos de la subtabla

2. La página no se envía repetidamente

Cuando comprobamos algún big data o consulta SQL ha sido muy lento, al menos debemos controlarlo en el front-end. Cuando no se devuelvan resultados en el back-end, no dejes que el usuario vuelva a hacer clic, para no provocar que el sistema se cuelgue.

3. La interfaz no comprueba la entrada del usuario

La interfaz debe realizar la verificación de entrada y el usuario no puede ingresar una condición. De hecho, algunos estudiantes han pensado que habrá algunas formas de omitir la verificación de la página. Aquí está la necesidad del paso 4.

4. El backend no realiza la verificación de entrada

Debido a que siempre habrá algunas personas que puedan omitir la página (la verificación del front-end solo puede evitar al caballero), es necesaria alguna verificación del back-end.

5. La capa sql no protegió las consultas.

Para asegurarnos de que el programa es más robusto, de hecho, en la capa sql, cuando encontramos que las condiciones comerciales son dinámicas, podemos retirarnos y hacer un buen trabajo de protección. El sql anterior se puede escribir de la siguiente manera para prevenir (todas las consultas son causadas por pantalones o escaneos de tablas completas) Servicio golpeado hasta la muerte):

select * from t_user usr
<where>
<if test=" email != null" >
and usr.email = #{email ,jdbcType= varchar}
</if>
<if test=" certNo!= null" >
and usr.cert_no = #{ certNo,jdbcType= varchar}
</if>
<if test=" email = null" >
<if test=" certNo= null" >
and  1=2
</if>
</if>
</where>

6. El desarrollo de este negocio no resolvió bien el negocio ni comprendió las necesidades.

Durante la investigación, descubrí que esta tabla contiene datos de 1000w. Me sorprendió en el momento del desarrollo. Me enteré de que cuando desarrollé esta función por primera vez, el desarrollador sintió que esta función no se usaba comúnmente y no estaba claro cuántos datos entrarían en la tabla. Este es el hecho de no comprender las necesidades y evaluar los datos de antemano. Si se comunica bien con las necesidades, confirma los datos diarios y diseña con anticipación, no debe cavar un agujero aquí.

En conclusión:

Al desarrollar, debemos aprender más sobre el negocio y comunicarnos con el lado de la demanda, y luego exigir el desarrollo después de comprender la naturaleza de la función. En el proceso de desarrollo de los compañeros, también debemos considerar la situación anormal de la interfaz. Los usuarios nunca operarán como usted quiere. ¡Otra cosa es que todos usan más herramientas para resolver el problema!

 

 

Supongo que te gusta

Origin blog.csdn.net/kevin_mails/article/details/99682178
Recomendado
Clasificación