Support de cours complet pour apprendre à utiliser le Framework Akka pour Java
Support de cours complet pour apprendre à utiliser le Framework Akka pour Java
INTRODUCTION
2.1 Qu'est-ce que Akka?
«Traitement élastique transactionnel des transactions en temps réel»
Nous pensons qu'il est trop difficile d'écrire des applications correctes distribuées, simultanées, tolérantes aux pannes et évolutives. La plupart du temps, c’est parce que nous utilisons les mauvais outils et le mauvais niveau d’abstraction. Akka est là pour changer cela. En utilisant le modèle d'acteur, nous élevons le niveau d'abstraction et fournissons une meilleure plate-forme pour la création d'applications évolutives, résilientes et réactives - consultez le Manifeste réactif pour plus de détails. En ce qui concerne la tolérance aux pannes, nous adoptons le modèle «let it crash» utilisé par l'industrie des télécommunications avec un grand succès pour créer des applications qui guérissent de soi et des systèmes qui ne s'arrêtent jamais. Les acteurs fournissent également l'abstraction pour une distribution transparente et la base d'applications réellement évolutives et tolérantes aux pannes.
Akka est Open Source et disponible sous la licence Apache 2.
Veuillez noter que tous les exemples de code sont compilés. Si vous souhaitez un accès direct aux sources, consultez le sous-projet Akka Docs sur github: for Java and Scala.
2.1.1 Akka implémente un hybride unique
Acteurs
Les acteurs vous donnent:
- Abstractions simples et de haut niveau pour la distribution, la concurrence et le parallélisme.
- Modèle de programmation basé sur les messages, asynchrone, non bloquant et hautement performant.
- Processus événementiels très légers (plusieurs millions d'acteurs par Go de mémoire).
Voir le chapitre sur Scala ou Java.
Tolérance aux pannes
- Hiérarchies de superviseurs avec une sémantique «let-it-crash».
- Les systèmes d'acteurs peuvent s'étendre sur plusieurs machines virtuelles afin de fournir des systèmes réellement tolérants aux pannes.
- Excellent pour l'écriture de systèmes hautement tolérants aux pannes qui guérissent d'eux-mêmes et ne s'arrêtent jamais.
Voir Fault Tolerance (Scala) et Fault Tolerance (Java).
Transparence de l'emplacement
Tout dans Akka est conçu pour fonctionner dans un environnement distribué: toutes les interactions des acteurs utilisent le transfert de messages pur et tout est asynchrone.
Pour une vue d'ensemble de la prise en charge du cluster, voir les chapitres de la documentation Java et Scala.
Persistance
Les changements d'état subis par un acteur peuvent éventuellement être persistés et rejoués lorsque l'acteur est démarré ou redémarré. Cela permet aux acteurs de récupérer leur état, même après une panne de la machine virtuelle Java ou lors de la migration vers un autre nœud.
Vous trouverez plus de détails dans les chapitres correspondants sur Java ou Scala.
2.1.2 API Scala et Java
Akka a à la fois un scala-api et une documentation Java.
2.1.3 Akka peut être utilisé de différentes manières
Akka est une boîte à outils, pas un framework: vous l'intégrez dans votre construction comme n'importe quelle autre bibliothèque sans devoir suivre une structure de code source particulière. Lorsque vous exprimez vos systèmes en tant qu'acteurs collaborateurs, vous pouvez vous sentir davantage poussé vers une encapsulation correcte de l'état interne. Vous constaterez peut-être qu'il existe une séparation naturelle entre la logique métier et la communication entre composants.
Les applications Akka sont généralement déployées comme suit:
- en tant que bibliothèque: utilisé comme un fichier JAR standard sur le chemin de classe ou dans une application Web.
- emballé avec sbt-native-packager.
- emballé et déployé avec Lightbend ConductR.
2.1.4 Support commercial
Akka est disponible auprès de Lightbend Inc. sous une licence commerciale incluant le support de développement ou de production, en savoir plus ici.
2.2 Pourquoi Akka?
2.2.1 Quelles fonctionnalités la plate-forme Akka peut-elle offrir par rapport à la concurrence?
Akka fournit un traitement de transaction en temps réel évolutif.
Akka est un modèle d'exécution et de programmation unifié pour:
- Scale up (Concurrency)
- Évolutivité (Remoting)
- tolérance aux pannes
Une chose à apprendre et à administrer, avec une grande cohésion et une sémantique cohérente.
Akka est un logiciel très évolutif, non seulement dans le contexte des performances, mais également dans la taille des applications pour lesquelles il est utile. Le noyau d’Akka, acteur akka, est très petit et se glisse facilement dans un projet existant dans lequel vous avez besoin d’une asynchronicité et d’une concurrence sans verrouillage et sans tracas.
Vous pouvez choisir d'inclure uniquement les parties d'Akka dont vous avez besoin dans votre application. Avec des processeurs de plus en plus de cœurs à chaque cycle, Akka est l’alternative offrant des performances exceptionnelles même si vous ne l’utilisez que sur un seul ordinateur. Akka fournit également un large éventail de paradigmes de concurrence, permettant aux utilisateurs de choisir le bon outil pour le travail.
2.2.2 Quel est le bon cas d’utilisation pour Akka?
Akka est adopté par de nombreuses grandes organisations dans un grand nombre de secteurs:
- Investment and Merchant Banking
- Vente au détail
- Des médias sociaux
- simulation
- Jeux et paris
- Automobile et systèmes de circulation
- Soins de santé
- Data Analytics et bien plus encore. Tout système nécessitant un débit élevé et une faible latence constitue un bon candidat pour utiliser Akka.
Les acteurs vous permettent de gérer les pannes de service (superviseurs), la gestion de la charge (stratégies de réduction, délais d'attente et isolation de traitement), ainsi que l'évolutivité horizontale et verticale (ajouter plus de cœurs et / ou ajouter plus de machines).
Voici ce que certains utilisateurs d’Akka ont à dire à propos de la façon dont ils utilisent Akka:
http://stackoverflow.com/questions/4493001/good-use-case-for-akka
Tout cela dans le projet Open Source sous licence ApacheV2.
2.3 Mise en route
2.3.1 Prérequis
Akka nécessite que Java 8 ou une version ultérieure soit installé sur votre ordinateur.
Lightbend Inc. fournit une version commerciale d’Akka et de projets connexes tels que Scala ou Play dans le cadre de la plate-forme réactive Lightbend mise à disposition pour Java 6 au cas où votre projet ne pourrait pas passer à Java 8 pour le moment. Il comprend également des fonctionnalités commerciales supplémentaires ou des bibliothèques.
2.3.2 Guides de démarrage et projets de modèles
La meilleure façon de commencer à apprendre Akka est de télécharger Lightbend Activator et d’essayer l’un des projets de modèles Akka.
2.3.3 Télécharger
Il existe plusieurs façons de télécharger Akka. Vous pouvez le télécharger dans le cadre de la plate-forme Lightbend (comme décrit ci-dessus). Vous pouvez télécharger la distribution complète, qui comprend tous les modules. Ou vous pouvez utiliser un outil de construction tel que Maven ou SBT pour télécharger des dépendances à partir du référentiel Akka Maven.
2.3.4 Modules
Akka est très modulaire et se compose de plusieurs JAR contenant différentes fonctionnalités.
- akka-actor - Acteurs classiques, Acteurs dactylographiés, Acteur IO, etc.
- akka-agent - Agents intégrés à Scala STM
- akka-camel - intégration Apache Camel
- akka-cluster - Gestion des membres du cluster, routeurs élastiques.
- akka-osgi - Utilitaires d’utilisation d’Akka dans des conteneurs OSGi
Akka-osgi-aries - Schéma du Bélier pour le provisionnement des systèmes d'acteurs
- akka-remote - Acteurs à distance
- akka-slf4j - enregistreur SLF4J (écouteur de bus d'événement)
- akka-stream - traitement de flux réactif
- akka-testkit - Boîte à outils pour tester les systèmes d'acteur
En plus de ces modules stables, il en existe plusieurs qui entrent dans le noyau stable mais qui portent encore la mention «expérimental». Cela ne signifie pas qu'ils ne fonctionnent pas comme prévu, cela signifie principalement que leur API n'a pas encore été suffisamment solidifié pour être considéré comme gelé. Vous pouvez aider à accélérer ce processus en donnant votre avis sur ces modules sur notre liste de diffusion.
- akka-contrib - un assortiment de contributions qui peuvent ou non être déplacées vers des modules de base, voir Contributions externes pour plus de détails.
Le nom de fichier du fichier JAR actuel est par exemple akka-actor_2.11-2.4.20.jar (et analogique pour les autres modules).
Comment voir les dépendances JAR de chaque module Akka est décrit dans la section Dépendances.
...
2.3.6 Utiliser une version d'instantané
Vous pouvez choisir une version horodatée à utiliser et décider du moment de la mise à jour vers une version plus récente.
Avertissement: Il est déconseillé d’utiliser Akka SNAPSHOTs, nightlies et jalons, à moins que vous ne sachiez ce que vous faites.
2.3.7 Utiliser un outil de construction
Akka peut être utilisé avec des outils de construction prenant en charge les référentiels Maven.
2.3.8 Dépôts Maven
Pour Akka version 2.1-M2 et suivantes:
Maven Central
Pour les versions précédentes d'Akka:
Akka Repo
2.3.9 Utiliser Akka avec Maven
Le moyen le plus simple de commencer à utiliser Akka et Maven est de consulter le didacticiel Lightbend Activator nommé Akka Main en Java.
Akka étant publié sur Maven Central (pour les versions depuis la version 2.1-M2), il suffit d’ajouter les dépendances Akka au POM. Par exemple, voici la dépendance pour akka-actor:
com.typesafe.akka
akka-actor_2.11
2.4.20
Pour les versions d'instantané, le référentiel d'instantané doit également être ajouté:
akka-snapshots
true
Remarque: pour les versions avec instantané, les versions SNAPSHOT et horodatée sont publiées.
2.3.10 Utiliser Akka avec SBT
Le moyen le plus simple de se familiariser avec Akka et SBT consiste à utiliser Lightbend Activator avec l’un des modèles SBT.
Résumé des éléments essentiels pour l’utilisation d’Akka avec SBT:
Fichier build.sbt:
name: = "Mon projet"
version: = "1.0"
scalaVersion: = "2.11.11"
libraryDependencies + =
"com.typesafe.akka" %% "akka-actor"% "2.4.20"
Remarque: le paramètre libraryDependencies ci-dessus est spécifique à SBT version 0.12.x et ultérieure. Si vous utilisez une version plus ancienne de SBT, libraryDependencies devrait ressembler à ceci:
libraryDependencies + = "com.typesafe.akka"% "akka-actor_2.11"% "2.4.20"
Pour les versions de capture instantanée, le référentiel de capture instantanée doit également être ajouté: resolvers + = "Référentiel de capture instantanée Akka" à l'adresse
2.3.11 Utiliser Akka avec Gradle
Nécessite au moins Gradle 1.4. Utilise le plugin Scala, plugin apply: ’scala’
référentiels {
mavenCentral ()
}
dépendances {
compile ’org.scala-lang: scala-library: 2.11.11’
}
tasks.withType (ScalaCompile) {
scalaCompileOptions.useAnt = false
}
dépendances {
groupe de compilation: "com.typesafe.akka", nom: "akka-actor_2.11", version: "2.4.20"
groupe de compilation: ’org.scala-lang’, nom: ’scala-library’, version: ’2.11.11’
}
Pour les versions de capture instantanée, le référentiel de capture instantanée doit également être ajouté: référentiels {
mavenCentral ()
maven {
}
}
2.3.12 Utiliser Akka avec Eclipse
Configurez le projet SBT, puis utilisez sbteclipse pour générer un projet Eclipse.
2.3.13 Utilisation d’Akka avec IntelliJ IDEA
Configurez le projet SBT, puis utilisez sbt-idea pour générer un projet IntelliJ IDEA.
2.3.14 Utiliser Akka avec NetBeans
Configurez le projet SBT puis utilisez nbsbt pour générer un projet NetBeans.
Vous devriez également utiliser nbscala pour la prise en charge générale des scala dans l'EDI.
2.3.15 Ne pas utiliser l'indicateur de compilation -optimize Scala
Avertissement: Akka n’a pas été compilé ni testé avec l’option -optimize du compilateur Scala. Un comportement étrange a été signalé par les utilisateurs qui l'ont essayé.
2.3.16 Construire à partir de sources
Akka utilise Git et est hébergé chez Github.
- Continuer la lecture de la page sur Building Akka
2.3.17 Besoin d'aide?
Si vous avez des questions, vous pouvez obtenir de l'aide sur la liste de diffusion Akka.
Vous pouvez également demander un support commercial.
Merci de faire partie de la communauté Akka.
2.4 Le bonjour obligatoire
La version basée sur l'acteur du difficile problème d'impression d'un message d'accueil bien connu sur la console est présentée dans un didacticiel Lightbend Activator nommé Akka Main en Java.
Le tutoriel illustre la classe de lanceur générique akka.Main qui n'attend qu'un seul argument de ligne de commande:
le nom de classe de l’acteur principal de l’application. Cette méthode principale créera ensuite l’infrastructure nécessaire à la gestion des acteurs, démarrera l’acteur principal donné et organisera la fermeture complète de l’application une fois celui-ci terminé.
Il existe également un autre didacticiel Lightbend Activator dans le même domaine problématique nommé Hello Akka !. Il décrit les bases d'Akka plus en profondeur.
2.5 Scénarios de cas d'utilisation et de déploiement
2.5.1 Comment puis-je utiliser et déployer Akka?
Akka peut être utilisé de différentes manières:
- En tant que bibliothèque: utilisé comme un fichier JAR standard sur le chemin de classe et / ou dans une application Web, à insérer dans WEB-INF / lib
- Package avec sbt-native-packager
- Emballez et déployez à l'aide de Lightbend ConductR.
2.5.2 emballeur natif
sbt-native-packager est un outil permettant de créer des distributions de tout type d'application, y compris les applications Akka.
Définissez la version de sbt dans le fichier project / build.properties:
sbt.version = 0.13.7
Ajoutez sbt-native-packager dans le fichier project / plugins.sbt:
addSbtPlugin ("com.typesafe.sbt"% "sbt-native-packager"% "1.0.0-RC1")
Utilisez les paramètres du package et spécifiez éventuellement le fichier mainClass dans le fichier build.sbt:
importer NativePackagerHelper._
name: = "akka-sample-main-scala"
version: = "2.4.20"
scalaVersion: = "2.11.8"
libraryDependencies ++ = Seq (
"com.typesafe.akka" %% "akka-actor"% "2.4.20"
)
enablePlugins (JavaServerAppPackaging
mainClass in Compile: = Some ("sample.hello.Main")
mappages dans Universal ++ = {
// exemple optionnel illustrant comment copier un répertoire supplémentaire ("scripts") ++
// copie les fichiers de configuration dans le répertoire de configuration
contentOf ("src / main / resources"). toMap.mapValues ("config /" + _)
}
// ajoute le répertoire ’config’ en premier dans le chemin de classe du script de démarrage,
// une alternative consiste à définir les emplacements des fichiers de configuration via les paramètres CLI
// au démarrage de l'application
scriptClasspath: = Seq ("../ config /") ++ scriptClasspath.value
licences: = Seq (("CC0", url (""))))
Remarque: Utilisez JavaServerAppPackaging. N'utilisez pas AkkaAppPackaging (qui s'appelait auparavant packageArchetype.akka_application), car il n'a pas la même souplesse et la même qualité que JavaServerAppPackaging.
Utilisez sbt task dist pour empaqueter l'application.
Pour démarrer l'application (sur un système Unix):
cd cible / universel / décompresser akka-sample-main-scala-2.4.20.zip
chmod u + x akka-sample-main-scala-2.4.20 / bin / akka-sample-main-scala
akka-sample-main-scala-2.4.20 / bin / akka-sample-main-scala sample.hello.Main
Utilisez Ctrl-C pour interrompre et quitter l'application.
Sur un ordinateur Windows, vous pouvez également utiliser le script bin \ akka-sample-main-scala.bat.
2.5.3 Dans un conteneur Docker
Vous pouvez utiliser Akka Remoting et Akka Cluster à l'intérieur des conteneurs Docker. Notez cependant que vous devrez faire particulièrement attention à la configuration du réseau lors de l’utilisation de Docker, décrite ci-dessous: remote-configuration-nat Pour un exemple de configuration d’un projet utilisant Akka Cluster et Docker, consultez la section «akka-docker “cluster” activateur.
2.6 Exemples de cas d'utilisation pour Akka
Nous voyons Akka être adopté par de nombreuses grandes organisations appartenant à un large éventail d’industries: banque d’investissement, banque de détail, médias sociaux, simulation, jeux et paris, automobile, systèmes de transport, soins de santé, analyse de données, etc. Tout système nécessitant un débit élevé et une faible latence constitue un bon candidat pour utiliser Akka.
Il y a une excellente discussion sur les cas d'utilisation pour Akka avec quelques bons résumés par les utilisateurs de la production ici
2.6.1 Voici quelques zones où Akka est déployé en production
Traitement des transactions (jeux en ligne, finance / banque, trading, statistiques, paris, médias sociaux, télécom)
Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
Service backend (toute industrie, toute application)
Service REST, SOAP, Cometd, WebSockets, etc. Agissez en tant que concentrateur de messages / couche d'intégration Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
Concurrence / parallélisme (toute application)
Correct Simple à utiliser et à comprendre Ajoutez simplement les fichiers jar à votre projet JVM existant (utilisez Scala, Java, Groovy ou JRuby)
Simulation
Master / Worker, Compute Grid, MapReduce etc.
Traitement par lots (toute industrie)
Intégration de chameaux à la connexion aux sources de données par lots Les acteurs divisent et conquièrent les charges de travail par lots
Hub de communication (télécom, média Web, média mobile)
Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
Jeux et paris (MOM, jeux en ligne, paris)
Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
Informatique décisionnelle / exploration de données / analyse générale
Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
Traitement de flux d'événements complexes
Mise à l'échelle, mise à l'échelle, tolérance aux pannes / HA
GÉNÉRAL
3.1 Terminologie, concepts
Dans ce chapitre, nous essayons d’établir une terminologie commune afin de définir une base solide pour la communication sur les systèmes distribués concurrents concourant avec Akka. Veuillez noter que, pour beaucoup de ces termes, il n’existe pas de définition unique convenue. Nous cherchons simplement à donner des définitions de travail qui seront utilisées dans le cadre de la documentation Akka.
3.1.1 Concurrence vs parallélisme
La simultanéité et le parallélisme sont des concepts liés, mais il existe de petites différences. La simultanéité signifie que deux tâches ou plus progressent même si elles ne s'exécutent pas simultanément. Ceci peut par exemple être réalisé avec un découpage temporel où des parties de tâches sont exécutées de manière séquentielle et mélangées avec des parties d'autres tâches.
Le parallélisme en revanche se produit lorsque l'exécution peut être réellement simultanée.
3.1.2 Asynchrone vs Synchrone
Un appel de méthode est considéré comme synchrone si l'appelant ne peut pas progresser jusqu'à ce que la méthode retourne une valeur ou lève une exception. D'autre part, un appel asynchrone permet à l'appelant de progresser après un nombre fini d'étapes et l'achèvement de la méthode peut être signalé via un mécanisme supplémentaire (par exemple, un rappel enregistré, un avenir ou un message).
Une API synchrone peut utiliser le blocage pour implémenter la synchronie, mais ce n'est pas une nécessité. Une tâche très gourmande en ressources processeur peut donner le même comportement que le blocage. En général, il est préférable d'utiliser des API asynchrones, car elles garantissent la progression du système. Les acteurs sont de nature asynchrone: un acteur peut progresser après l'envoi d'un message sans attendre la livraison.
3.1.3 Non bloquant ou bloquant
Nous parlons de bloquer si le délai d'un thread peut indéfiniment retarder certains des autres threads. Un bon exemple est une ressource qui peut être utilisée exclusivement par un seul thread utilisant une exclusion mutuelle. Si un thread conserve indéfiniment la ressource (par exemple, l'exécution accidentelle d'une boucle infinie), les autres threads en attente sur la ressource ne peuvent pas progresser. En revanche, non bloquant signifie qu'aucun thread ne peut retarder indéfiniment les autres.
Les opérations non bloquantes sont préférées aux opérations bloquantes, car la progression globale du système n'est pas garantie de manière triviale quand il contient des opérations bloquantes.
3.1.4 Impasse vs famine vs verrouillage réel
Une impasse se produit lorsque plusieurs participants s’attendent pour atteindre un état spécifique afin de pouvoir progresser.
Comme aucun d'entre eux ne peut progresser sans qu'un autre participant n'atteigne un certain état (problème «Catch-22»), tous les sous-systèmes concernés restent bloqués. Le blocage est étroitement lié au blocage, car il est nécessaire qu'un thread participant puisse retarder indéfiniment la progression des autres threads.
En cas d'impasse, aucun participant ne peut progresser, alors qu'au contraire, la famine survient lorsque certains participants peuvent progresser, mais qu'un ou plusieurs d'entre eux ne le peuvent pas. Le scénario typique est le cas d'un algorithme de planification naïf qui sélectionne toujours les tâches hautement prioritaires par rapport aux tâches moins prioritaires. Si le nombre de tâches hautement prioritaires entrantes est suffisamment élevé, aucune tâche de faible priorité ne sera jamais terminée.
Livelock ressemble à une impasse car aucun des participants ne progresse. La différence est que, au lieu d’être figés dans l’attente des progrès des autres, les participants changent constamment d’état. Exemple de scénario lorsque deux participants disposent de deux ressources identiques. Chacun essaie d'obtenir la ressource, mais il vérifie également si l'autre a également besoin de la ressource. Si la ressource est demandée par l'autre participant, celui-ci tente d'obtenir l'autre instance de la ressource. Dans le cas malheureux, il peut arriver que les deux participants se «rebondissent» entre les deux ressources sans jamais l’acquérir, mais cédant toujours à l’autre.
3.1.5 Condition de course
Nous appelons cela une condition raciale lorsqu'une hypothèse concernant la commande d'un ensemble d'événements peut être violée par des effets externes non déterministes. Les conditions de concurrence surviennent souvent lorsque plusieurs threads partagent un état mutable et que les opérations de thread sur l'état peuvent être entrelacées, entraînant un comportement inattendu. Bien que ce soit un cas courant, un état partagé n'est pas nécessaire pour avoir des conditions de concurrence. Un exemple pourrait être un client qui envoie des paquets non ordonnés (par exemple des datagrammes UDP) P1, P2 à un serveur. Comme les paquets peuvent potentiellement voyager par différentes routes de réseau, il est possible que le serveur reçoive P2 en premier et P1 ensuite. Si les messages ne contiennent aucune information sur leur ordre d'envoi, il est impossible de déterminer par le serveur qu'ils ont été envoyés dans un ordre différent. En fonction de la signification des paquets, cela peut entraîner des conditions de concurrence.
Remarque: la seule garantie fournie par Akka à propos des messages envoyés entre une paire d'acteurs donnée est que leur ordre est toujours conservé. voir la fiabilité de la remise des messages
3.1.6 Garanties non bloquantes (conditions de progression)
Comme indiqué dans les sections précédentes, le blocage est indésirable pour plusieurs raisons, notamment les dangers des blocages et du débit réduit du système. Dans les sections suivantes, nous discutons de diverses propriétés non bloquantes avec différentes résistances.
Attente-liberté
Une méthode est sans attente s'il est garanti que chaque appel se termine en un nombre fini d'étapes. Si une méthode est déliée sans attente, le nombre d'étapes a une limite supérieure finie.
Il découle de cette définition que les méthodes sans attente ne bloquent jamais, donc l'impasse ne peut pas arriver.
De plus, comme chaque participant peut progresser après un nombre fini d'étapes (à la fin de l'appel), les méthodes sans attente sont exemptes de famine.