L'éditeur php Youzi vous propose des questions et réponses Java sur la surveillance du flux Spring Data JPA. Pendant le développement, la surveillance des flux de données en temps réel est essentielle pour l'optimisation des performances du système et le dépannage. Cet article explique comment surveiller le flux Spring Data JPA, vous permettant de mieux comprendre le processus de traitement des données, de détecter les problèmes à temps et de les gérer en conséquence. Discutons de la manière de surveiller efficacement le flux Spring Data JPA et d'améliorer la stabilité et les performances du système !
J'essaie d'utiliser le streaming jpa de données Spring comme expliqué sur ce blog. Cependant, je ne peux pas surveiller le processus ou la progression avec aucun journal. Dois-je voir plusieurs requêtes SQL imprimées dans le journal lorsque le processus tente d'extraire des données par lots ? Si ce n'est pas le cas, comment puis-je savoir que toutes les lignes ne sont pas chargées en même temps ?
D'autres blogs (comme celui-ci et celui-ci ) m'ont suggéré de convertir mysql en hint_fetch_size
设置为 integer.min_value
, ce qui, à mon avis, pourrait être la solution, mais cela génère l'exception suivante :
2024-01-29 14:40:20.843 avertissement 78247 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.sqlexceptionhelper : erreur sql : 0, sqlstate : s1000 2024-01-29 14:40:20.843 Erreur 78247 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.sqlexceptionhelper : jeu de résultats de streaming com.mysql.cj.protocol.a.result resultsetrowsstreaming@. 4ca63fa5 est toujours actif. Aucune déclaration ne doit être émise lorsqu'un ensemble de résultats de streaming est ouvert et utilisé sur une connexion donnée. Avant d'essayer d'autres requêtes, assurez-vous d'avoir appelé .close() sur tous les jeux de résultats de streaming actifs. Heure de fin : 48 org.springframework.orm.jpa.jpasystemexception : impossible d'extraire l'ensemble de résultats ; l'exception imbriquée est org.hibernate.exception.genericjdbcexception : impossible d'extraire l'ensemble de résultats sur org.springframework.orm.jpa.vendor.hibernatejpadialect.converthibernateaccessexception(hibernatejpadialect.java:331)
Voici mon code de dépôt :
@QueryHints(value = { @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "false"), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_READONLY, value = "true"), }) @Query("SELECT s FROM Salary s") Stream<Salary> findAllStream();
Je suppose que j'aimerais obtenir une garantie si ce qui précède est la bonne façon d'utiliser les requêtes de flux dans Spring Data JPA, car je ne peux pas surveiller moi-même de manière fiable les performances du streaming ?
Mise à jour
L'exception ci-dessus se produit en raison d'appels répétés à la méthode findallstream dans la même méthode d'appel. La suppression de l’un d’eux a corrigé l’exception.
Je ne trouve aucune configuration de journal indiquant si les données sont récupérées par lots. Mais j'ai trouvé un moyen de tester les performances localement.
Pour tester la fonctionnalité de streaming, je dois accéder à une base de données contenant des millions d'enregistrements. J'utilise l'image Docker https://www.php.cn/link/7092d5eb1bbca1a22bdc69ba3f517e68 pour utiliser les données des employés MySQL
Après avoir configuré l'image Docker, j'ai du mal à connecter MySQL Workbench au serveur. Il semble que l'image Docker ne soit pas configurée pour accepter les connexions SSL par défaut. J'ai dû désactiver le drapeau use ssl
pour établir la connexion. Ce paramètre apparaît dans le workbench mysql sous l'onglet ssl.
La chaîne de connexion dans l'application doit également être configurée comme suit :
spring.datasource.url=jdbc:mysql://localhost:3307/employees?verifyservercertificate=false&usessl=false&requiressl=false
Les données de la base de données des employés consistent en une table nommée salaries
qui compte environ 2,8 millions de lignes.
Pour les tests, j'ai écrit une petite application jpa Spring Data qui possède les méthodes suivantes dans la classe du référentiel et un contrôleur simple pour appeler ces méthodes :
@Override List<Salary> findAll(); @QueryHints(value = { @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "" + Integer.MIN_VALUE), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_CACHEABLE, value = "false"), @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_READONLY, value = "true"), }) @Query("SELECT s FROM Salary s") Stream<Salary> findAllStream();
J'ai ensuite écrit un petit morceau de code qui a converti les données lues en un objet json, puis je les ai réécrites dans le fichier à l'aide de plusieurs threads. Il s’agit de simuler le traitement dans des cas réels.
C'est ce que j'ai observé.
L'utilisation de la mémoire augmente considérablement lors de l'utilisation de la méthode de liste. La requête initiale a pris la plupart du temps, mais une fois toutes les données chargées, le traitement proprement dit des données s'est terminé rapidement.
Lors de l'utilisation de la méthode stream, l'impact sur l'utilisation de la mémoire est presque imperceptible. Mais dans l’ensemble, les performances de la partie traitement de complétion sont similaires, voire pires, par rapport à la méthode de liste.
Conclusion
Mes découvertes ci-dessus m'amènent à conclure que l'approche du référentiel est stream
返回类型仅应在存在内存不足风险时使用,即获得 out 内存异常
. Sinon, si votre application s'exécute déjà sur un serveur suffisamment grand, l'impact global sur l'utilisation de la mémoire sera à peine perceptible et ne sera que temporaire si votre processus se termine rapidement.
Statistiques d'utilisation de la mémoire du profileur IntelliJ
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!