portaldacalheta.pt
  • Principal
  • Rise Of Remote
  • Outils Et Tutoriels
  • Équipes Distribuées
  • Mode De Vie
Science Des Données Et Bases De Données

Scaling Play! à des milliers de demandes simultanées



Développeurs Web Scala oublient souvent de prendre en compte les conséquences de l'accès simultané de milliers d'utilisateurs à nos applications. C'est peut-être parce que nous aimons réaliser rapidement des prototypes; c'est peut-être parce que tester de tels scénarios est simplement dur .

Quoi qu'il en soit, je vais affirmer qu'ignorer l'évolutivité n'est pas aussi grave que cela en a l'air - si vous utilisez le bon ensemble d'outils et suivez de bonnes pratiques de développement.



Ignorer l'évolutivité n'est pas aussi grave qu'il y paraît, si vous utilisez les outils appropriés.

Lojinha et le jeu! Cadre

Il y a quelque temps, j'ai lancé un projet appelé Lojinha (qui se traduit par «petit magasin» en portugais), ma tentative de créer un site d'enchères. (Au fait, ce projet est Open source ). Mes motivations étaient les suivantes:



  • Je voulais vraiment vendre de vieux trucs que je n’utilise plus.
  • Je n'aime pas les sites d'enchères traditionnels, en particulier ceux que nous avons ici au Brésil.
  • Je voulais «jouer» avec le Jouer! Cadre 2 (jeu de mots volontaire).

Alors évidemment, comme mentionné ci-dessus, j'ai décidé d'utiliser le Jouer! Cadre . Je n'ai pas de compte exact du temps de création, mais il ne me fallut certainement pas longtemps avant que mon site soit opérationnel avec le système simple déployé sur http://lojinha.jcranky.com . En fait, j'ai passé au moins la moitié du temps de développement sur la conception, qui utilise Bootstrap Twitter (rappelez-vous: je ne suis pas designer…).



Le paragraphe ci-dessus devrait clarifier au moins une chose: je ne me souciais pas trop des performances, voire pas du tout lors de la création de Lojinha.

Et c’est exactement ce que je veux dire: il est possible d’utiliser les bons outils - des outils qui vous permettent de rester sur la bonne voie, des outils qui vous encouragent à suivre les meilleures pratiques de développement de par leur conception même.



Dans ce cas, ces outils sont le Play! Cadre et le Langage Scala , avec Akka faire quelques «apparitions d'invités».

Laissez-moi vous montrer ce que je veux dire.



Immuabilité et mise en cache

Il est généralement admis que minimiser la mutabilité est une bonne pratique. En bref, la mutabilité rend plus difficile de raisonner sur votre code, en particulier lorsque vous essayez d'introduire un parallélisme ou une concurrence.

Le jeu! Le framework Scala vous permet d'utiliser l'immuabilité une bonne partie du temps, tout comme le langage Scala lui-même. Par exemple, le résultat généré par un contrôleur est immuable. Parfois, vous pouvez considérer cette immuabilité comme «gênante» ou «ennuyeuse», mais ces «bonnes pratiques» sont «bonnes» pour une raison.



Dans ce cas, l’immuabilité du contrôleur était absolument cruciale lorsque j’ai finalement décidé d’exécuter des tests de performances: j’ai découvert un goulot d’étranglement et, pour y remédier, j’ai simplement mis en cache cette réponse immuable.

Par mise en cache , Je veux dire enregistrer l'objet de réponse et servir une instance identique, telle quelle, à tous les nouveaux clients. Cela évite au serveur d'avoir à recalculer à nouveau le résultat. Il ne serait pas possible de fournir la même réponse à plusieurs clients si ce résultat était modifiable.



L'inconvénient: pendant une brève période (le délai d'expiration du cache), les clients peuvent recevoir des informations obsolètes. Ceci n'est un problème que dans les scénarios où vous avez absolument besoin que le client accède aux données les plus récentes, sans tolérance de retard.

Pour référence, voici le code Scala pour charger la page d'accueil avec une liste de produits, sans mise en cache:



def index = Action { implicit request => Ok(html.index(body = html.body(Items.itemsHigherBids(itemDAO.all(false))), menu = mainMenu)) }

Maintenant, ajout du cache:

def index = Cached('index', 5) { Action { implicit request => Ok(html.index(body = html.body(Items.itemsHigherBids(itemDAO.all(false))), menu = mainMenu)) } }

C'est simple, n'est-ce pas? Ici, 'indice' est la clé à utiliser dans le système de cache et 5 est le délai d'expiration, en secondes.

y compris quoi, fausse l'efficacité de la représentation graphique des points de données ?
Après la mise en cache, le débit est passé à 800 requêtes par seconde. C'est une amélioration de plus de 4x pour moins de deux lignes de code.

Pour tester l'effet de ce changement, j'ai exécuté des tests JMeter (inclus dans le dépôt GitHub) localement. Avant d'ajouter le cache, j'ai atteint un débit d'environ 180 requêtes par seconde. Après la mise en cache, le débit est passé à 800 requêtes par seconde. C'est une amélioration de plus de 4x pour moins de deux lignes de code.

C

Consommation de mémoire

Un autre domaine où les bons outils Scala peuvent faire une grande différence est la consommation de mémoire. Ici encore, jouez! vous pousse dans la bonne direction (évolutive). dans le Java world, pour une application Web «normale» écrite avec le API de servlet (c'est-à-dire presque tous les frameworks Java ou Scala), il est très tentant de mettre beaucoup de courrier indésirable dans la session utilisateur car l'API propose des méthodes faciles à appeler qui vous permettent de le faire:

session.setAttribute('attrName', attrValue);

Parce qu'il est si facile d'ajouter des informations à la session utilisateur, elles sont souvent abusées. En conséquence, le risque d'utiliser trop de mémoire sans aucune raison valable est également élevé.

Avec le Play! framework, ce n’est pas une option - le framework n’a tout simplement pas d’espace de session côté serveur. Le jeu! La session utilisateur du framework est conservée dans un cookie de navigateur et vous devez vivre avec. Cela signifie que l'espace de session est limité en taille et en type: vous ne pouvez stocker que des chaînes. Si vous avez besoin de stocker des objets, vous devrez utiliser le mécanisme de mise en cache dont nous avons parlé précédemment. Par exemple, vous souhaiterez peut-être stocker l'adresse e-mail ou le nom d'utilisateur de l'utilisateur actuel dans la session, mais vous devrez utiliser le cache si vous devez stocker un objet utilisateur entier à partir de votre modèle de domaine.

Jouer! vous maintient sur la bonne voie, vous obligeant à examiner attentivement votre utilisation de la mémoire, ce qui produit un code de premier passage pratiquement prêt pour le cluster.

Encore une fois, cela peut sembler une douleur au début, mais en vérité, jouez! vous maintient sur la bonne voie, vous obligeant à examiner attentivement votre utilisation de la mémoire, ce qui produit un code de premier passage pratiquement prêt pour le cluster, d'autant plus qu'aucune session côté serveur ne devrait être propagée dans tout votre cluster, ce qui rend la vie infiniment plus facile.

Prise en charge Async

Suivant dans ce jeu! examen du cadre, nous examinerons comment Play! brille également dans le support async (hronous). Et au-delà de ses fonctionnalités natives, Play! vous permet d'intégrer Akka , un outil puissant pour le traitement asynchrone.

Altough Lojinha ne profite pas encore pleinement d'Akka, sa simple intégration avec Play! rendu vraiment facile:

  1. Planifiez un service de messagerie asynchrone.
  2. Traiter les offres pour différents produits simultanément.

En bref, Akka est une implémentation du Modèle d'acteur rendu célèbre par Erlang . Si vous n'êtes pas familier avec le modèle d'acteur d'Akka, imaginez-le comme une petite unité qui ne communique que par messages.

Pour envoyer un e-mail de manière asynchrone, je crée d'abord le message approprié et acteur . Ensuite, tout ce que j'ai à faire est quelque chose comme:

EMail.actor ! BidToppedMessage(item.name, itemUrl, bidderEmail)

La logique d'envoi d'e-mail est implémentée à l'intérieur de l'acteur, et le message indique à l'acteur quel e-mail nous aimerions envoyer. Ceci est fait dans un schéma fire-and-forget, ce qui signifie que la ligne ci-dessus envoie la demande et continue ensuite d'exécuter tout ce que nous avons après cela (c'est-à-dire qu'elle ne bloque pas).

Pour plus d'informations sur la fonction Async native de Play!, Consultez la documentation officielle .

Conclusion

En résumé: j'ai rapidement développé une petite application, Boutique , capable de très bien évoluer. Lorsque je rencontrais des problèmes ou découvrais des goulots d'étranglement, les correctifs étaient rapides et faciles, avec beaucoup de crédit grâce aux outils que j'ai utilisés (Play !, Scala, Akka, etc.), ce qui m'a poussé à suivre les meilleures pratiques en termes d'efficacité et évolutivité. Sans me soucier des performances, j'ai pu évoluer vers des milliers de demandes simultanées.

Lors du développement de votre prochaine application, considérez attentivement vos outils.

Le frontal: utilisation de Gatsby.js et Node.js pour les mises à jour statiques du site

La Technologie

Le frontal: utilisation de Gatsby.js et Node.js pour les mises à jour statiques du site
Pourquoi y a-t-il autant de pythons? Une comparaison d'implémentation Python

Pourquoi y a-t-il autant de pythons? Une comparaison d'implémentation Python

La Technologie

Articles Populaires
Création d'une API REST Node.js / TypeScript, partie 2: modèles, middleware et services
Création d'une API REST Node.js / TypeScript, partie 2: modèles, middleware et services
Un didacticiel sur la radio définie par logiciel: images de la Station spatiale internationale et écoute de jambons avec un RTL-SDR
Un didacticiel sur la radio définie par logiciel: images de la Station spatiale internationale et écoute de jambons avec un RTL-SDR
Les drones commerciaux révolutionnent les opérations commerciales
Les drones commerciaux révolutionnent les opérations commerciales
Faire des affaires dans l'Union européenne
Faire des affaires dans l'Union européenne
AI vs BI: différences et synergies
AI vs BI: différences et synergies
 
Stratège de contenu produit
Stratège de contenu produit
Risque vs récompense: un guide pour comprendre les conteneurs logiciels
Risque vs récompense: un guide pour comprendre les conteneurs logiciels
Explorer SMACSS: architecture évolutive et modulaire pour CSS
Explorer SMACSS: architecture évolutive et modulaire pour CSS
Si vous n'utilisez pas de données UX, ce n'est pas de la conception UX
Si vous n'utilisez pas de données UX, ce n'est pas de la conception UX
Simplification de l'utilisation des API RESTful et de la persistance des données sur iOS avec Mantle et Realm
Simplification de l'utilisation des API RESTful et de la persistance des données sur iOS avec Mantle et Realm
Articles Populaires
  • programmation informatique c++
  • structure de dossier de projet d'application de formulaires Windows
  • comment les sites de rencontre gagnent de largent
  • llc c ou s corp
  • comment faire des polices personnalisées
  • état actuel de l'industrie musicale
Catégories
  • Rise Of Remote
  • Outils Et Tutoriels
  • Équipes Distribuées
  • Mode De Vie
  • © 2022 | Tous Les Droits Sont Réservés

    portaldacalheta.pt