Printemps webflux et de la lecture à partir de la base de données
Printemps 5 introduit le réactif de style de programmation pour Api rest avec webflux. Je suis assez nouveau pour moi-même et je me demandais si d'emballage des appels synchrones à une base de données en Flux
ou Mono
sens preformence-sage? Si oui, est-ce la façon de le faire:
@RestController
public class HomeController {
private MeasurementRepository repository;
public HomeController(MeasurementRepository repository){
this.repository = repository;
}
@GetMapping(value = "/v1/measurements")
public Flux<Measurement> getMeasurements() {
return Flux.fromIterable(repository.findByFromDateGreaterThanEqual(new Date(1486980000L)));
}
}
Est là quelque chose comme une asynchrones CrudRepository? Je ne pouvais pas le trouver.
Code JDBC est intrinsèquement synchrone, il n'y a pas réactive pilotes JDBC (et je doute qu'il y en aura jamais). L'accès à une base de données comme cela n'a pas vraiment de sens.
Je ne suis pas familier avec le flux, mais je sais que vous pouvez utiliser Java 8 Stream le type de retour au Printemps de Données JPA. Vous pouvez retourner
C'est un bon début, mais ce n'est pas asynchrone si l'appelant bloque alors que le JDBC opération est en cours qui rompt le webflux non-blocage de paradigme.
Je ne suis pas familier avec le flux, mais je sais que vous pouvez utiliser Java 8 Stream le type de retour au Printemps de Données JPA. Vous pouvez retourner
Stream<Measurement>
. Vous ne savez pas si ce commentaire vous aide ou pas bien 🙂C'est un bon début, mais ce n'est pas asynchrone si l'appelant bloque alors que le JDBC opération est en cours qui rompt le webflux non-blocage de paradigme.
OriginalL'auteur Lukasz | 2017-02-17
Vous devez vous connecter pour publier un commentaire.
Une option serait d'utiliser d'autres clients SQL qui sont entièrement non-bloquant. Voici quelques exemples:
https://github.com/mauricio/postgresql-async ou https://github.com/finagle/roc. Bien sûr, aucun de ces pilotes est officiellement pris en charge par les fournisseurs de base de données encore. Aussi, la fonctionnalité est de façon beaucoup moins attrayante en comparaison à maturité JDBC basée sur des abstractions telles que la mise en veille ou jOOQ.
L'alternative idée m'est venue de Scala monde. L'idée est d'envoyer les appels de blocage en isolé de pool de threads de ne pas mélanger de blocage et les non-blocage des appels. Cela va nous permettre de contrôler le nombre total de threads et de laisser le CPU servir de non-blocage des tâches dans les principaux contexte d'exécution avec un certain potentiel d'optimisations.
En supposant que nous avons JDBC en fonction de la mise en œuvre telles que Spring Data JPA qui est en effet de blocage, nous pouvons faire c'est de l'exécution asynchrone et de l'expédition sur le thread dédié à la piscine.
Notre Planificateur de JDBC doit être configuré à l'aide de Thread dédié à la Piscine, avec la taille de compter égal au nombre de connexions.
Cependant, il ya des difficultés avec cette approche. La principale est la gestion des transactions. En JDBC, les transactions sont possibles que dans un seul java.sql.Connexion. Pour rendre les plusieurs opérations en une seule transaction, ils ont de partager une connexion. Si nous voulons faire quelques calculs entre eux, nous nous devons de maintenir la connexion. Ce n'est pas très efficace, comme nous avons un nombre limité de connexions inactives et en faisant des calculs entre les deux.
Cette idée d'un asynchrones JDBC wrapper n'est pas nouvelle et est déjà mise en œuvre dans Scala bibliothèque de la Nappe de 3. Enfin, la non-bloquant JDBC peut venir sur la Java de la feuille de route. Comme il a été annoncé lors de JavaOne, en septembre 2016, et il est possible que nous allons voir dans Java 10.
à partir de plusieurs sources, je peux voir que ce travail n'est pas encore planifié, au moins par Pivot: jira.printemps.io/parcourir/DATAJPA-701 printemps.io/blog/2017/02/23/...
Le publishOn(scheduler) appel un peu bizarre pour moi, dans l'exemple de code. Devriez-vous à nous au lieu subscribeOn qui exécuter la requête() de cet éditeur sur le planificateur donné ?
Il devrait plutôt être subscribeOn() la méthode à l'aide d'un pool de threads pas publishOn (comme le code ci-dessus.
ce sujet insérer? avons-nous besoin de valider une transaction de nous-mêmes? parce que je soupçonne que @Transaction ne fonctionne pas pour ces cas, parce que nous avons cessé de méthode avant de réaliser des travaux dans le thread.
OriginalL'auteur Grygoriy Gonchar
Printemps de données de support réactif référentiel d'interface pour les Mongo et Cassandra.
Printemps de données MongoDb Réactives de l'Interface
Printemps de Données MongoDB fournit réactif support référentiel avec le Projet de Réacteur et RxJava 1 réactif types. Le réactif de l'API prend en charge réactif type de conversion entre les types.
OriginalL'auteur yousafsajjad
Sur cette base blog vous devez réécrire votre extrait de code dans façon suivante
OriginalL'auteur Dmytro Boichenko
L'obtention d'un Flux ou d'un Mono ne veut pas forcément dire qu'il va s'exécuter dans un Thread dédié. Au lieu de cela, la plupart des opérateurs de continuer à travailler dans le Thread sur lequel le précédent opérateur exécuté. Sauf indication, le premier opérateur (la source) qui s'exécute sur le Thread dans lequel l'subscribe() l'appel a été fait.
Si vous avez le blocage de persistence Api (JPA, JDBC) ou de l'Api de réseau à utiliser, Spring MVC est le meilleur choix pour les architectures communes au moins. Il est techniquement possible avec les deux Réacteurs et RxJava pour effectuer le blocage des appels sur un autre fil, mais vous ne seriez pas en tirer le maximum d'un non-bloquant web de la pile.
Donc... Comment emballer un synchrone, le blocage d'appel?
Utilisation
Callable
de différer l'exécution. Et vous devez l'utiliserSchedulers.elastic
parce qu'il crée un thread dédié à attendre pour le blocage de ressources sans monopoliser certains autres ressources.exemple:
OriginalL'auteur kkd927