Connect with us

Technologie

SQLite sur Rails : Maximisez vos performances avec ces astuces incontournables !

Over the last year or so, I have found myself on a journey to deeply understand how to run Rails applications backed by SQLite performantly and resiliently. In that time, I have learned various lessons that I want to share with you all now. I want to walk through where the problems lie, why they

Published

on

SQLite on Rails: The how and why of optimal performance

Optimisation des Applications Rails avec SQLite

Introduction à l’Optimisation des Performances

Au cours de l’année écoulée, j’ai entrepris un voyage pour comprendre comment exécuter des applications Rails avec SQLite de manière performante et résiliente. J’ai acquis plusieurs enseignements que je souhaite partager. Dans cet article, nous allons explorer les problèmes rencontrés, leurs causes et les solutions possibles.

La Réalité Actuelle de SQLite sur Rails

Il est important de reconnaître que l’utilisation de SQLite avec Rails, sans ajustements, n’est pas une option viable aujourd’hui. Cependant, avec quelques modifications et optimisations, il est possible de déployer une application Rails performante et robuste utilisant SQLite. Mon objectif personnel pour Rails 8 est de rendre l’expérience prête pour la production dès la sortie de la boîte.

Identifier les Problèmes et Trouver des Solutions

Au cours de l’année passée, j’ai analysé en profondeur les défis liés à l’utilisation de SQLite dans les applications Rails et les solutions à ces problèmes. Voici ce qu’il faut savoir pour construire une application Rails prête pour la production avec SQLite.

Commandes Essentielles pour la Production

Pour préparer votre application à la production, trois commandes clés peuvent faire toute la différence. Elles permettent d’améliorer considérablement les performances, d’ajouter des fonctionnalités SQL et de mettre en place des sauvegardes à un instant donné. Voici comment vous pouvez établir une application SQLite sur Rails prête pour la production.

Étude de Cas : Application Démonstration « Lorem News »

Pour rendre cette exploration concrète, nous allons travailler sur une application de démonstration nommée « Lorem News ». Il s’agit d’un clone simple de Hacker News, où les utilisateurs peuvent publier des articles et des commentaires, mais tout le contenu est en Lorem Ipsum. Ce code servira de base pour nos exemples et nos tests de performance.

Évaluation des Performances de l’Application

Pour évaluer les performances de notre application de démonstration, nous utiliserons l’outil de test de charge oha et les routes de benchmarking intégrées à l’application. Commençons par un test simple où nous envoyons une requête après l’autre pendant 5 secondes à notre point de terminaison post#create.

Les résultats initiaux montrent des performances solides, avec un bon nombre de requêtes par seconde (RPS) et un taux de succès élevé. Cependant, la requête la plus lente est significativement plus longue que la moyenne, ce qui n’est pas idéal. Cela remet en question l’idée que l’expérience par défaut avec Rails et SQLite est prête pour la production.

Tests de Charge Concurrente

En effectuant le même test de charge, mais en envoyant 4 requêtes simultanées par vagues pendant 5 secondes, les résultats changent. Nous commençons à voir des erreurs 500 dans nos réponses, indiquant des problèmes sous-jacents.

Analyse des Logs et Identification des Problèmes

En examinant les logs, nous découvrons le premier problème majeur auquel les applications Rails utilisant SQLite doivent faire face : l’exception SQLITE_BUSY.

SQLite utilise un verrou d’écriture pour s’assurer qu’une seule opération d’écriture se produit à la fois. Si plusieurs connexions tentent d’écrire simultanément, l’exception SQLITE_BUSY est levée. Sans configuration appropriée, une application web avec un pool de connexions vers une base de données SQLite rencontrera de nombreuses erreurs lors de la réponse aux requêtes.

Solutions : Gérer les Transactions

À mesure que la charge concurrente augmente sur votre application Rails, le pourcentage de requêtes échouant avec l’exception SQLITE_BUSY augmente également. Il est donc crucial de trouver un moyen de gérer les requêtes d’écriture de manière à ce qu’elles s’enchaînent sans générer d’erreurs.

Transactions Immédiates

Pour résoudre ce problème, nous devons utiliser des transactions immédiates. En raison du verrou d’écriture global, SQLite nécessite différents modes de transaction pour différents comportements.

Mode de Transaction par Défaut

Par défaut, SQLite utilise un mode de transaction différé, ce qui signifie qu’il n’acquiert le verrou qu’au moment d’une opération d’écriture. Cela peut être efficace dans des contextes où il n’y a qu’une seule connexion ou lorsque les transactions ne contiennent que des opérations de lecture. Cependant, ce n’est pas le cas des applications Rails en production.

Dans une application Rails, plusieurs connexions sont souvent actives, et chaque transaction inclut généralement une opération d’écriture. Cela entraîne des conflits et des erreurs, rendant nécessaire l’adoption d’une approche différente pour gérer les transactions.

Conclusion

bien que l’utilisation de SQLite avec Rails présente des défis, il est possible de surmonter ces obstacles grâce à des ajustements appropriés. En comprenant les problèmes liés à l’exception SQLITE_BUSY et en adoptant des stratégies de gestion des transactions, vous pouvez créer une application Rails robuste et performante utilisant SQLite.

Optimisation des Transactions dans SQLite pour les Applications Rails

Comprendre les Exceptions SQLITE_BUSY

Les exceptions SQLITE_BUSY se produisent lorsque SQLite tente d’acquérir un verrou d’écriture pendant qu’une autre connexion le détient. Dans ce cas, SQLite ne peut pas relancer la requête liée à la transaction en toute sécurité, car cela pourrait compromettre l’isolation sérielle que garantit SQLite. Ainsi, lorsqu’une exception de type busy se produit lors de la tentative d’élévation d’une transaction, SQLite ne peut pas mettre en file d’attente cette requête pour une tentative ultérieure ; elle renvoie immédiatement une erreur et interrompt la transaction.

Amélioration des Transactions avec le Mode IMMEDIATE

Pour contourner ce problème, il est possible de commencer la transaction en déclarant explicitement qu’il s’agit d’une transaction immédiate. Cela permet à SQLite de mettre en file d’attente la requête pour réessayer d’acquérir le verrou d’écriture plus tard. En utilisant un système de mise en file d’attente, SQLite peut gérer les requêtes concurrentes, même si certaines d’entre elles sont encapsulées dans des transactions.

Configuration des Transactions dans Rails

Depuis la version 1.6.9, la gem sqlite3-ruby permet de configurer le mode de transaction par défaut. Étant donné que Rails transmet les clés de configuration de niveau supérieur dans votre fichier database.yml directement à l’initialiseur de base de données sqlite3-ruby, il est facile de s’assurer que toutes les transactions SQLite de Rails s’exécutent en mode IMMEDIATE.

Résultats des Tests de Charge

Après avoir effectué cette modification dans notre application de démonstration et relancé notre test de charge, nous avons constaté que notre application Rails gère désormais la charge concurrente sans générer presque aucune erreur 500. Cependant, des erreurs commencent à apparaître à partir de 16 requêtes concurrentes, ce qui indique qu’il reste des problèmes à résoudre.

En examinant les résultats de latence de nos tests de charge, un nouveau problème se manifeste rapidement. À mesure que le nombre de requêtes concurrentes atteint et dépasse le nombre de travailleurs Puma, la latence p99 augmente considérablement. Étonnamment, le temps de requête réel reste stable, même avec une charge trois fois supérieure au nombre de travailleurs Puma. Cependant, dès que certaines requêtes prennent environ 5 secondes, nous commençons également à recevoir des réponses SQLITE_BUSY.

Gestion des Délais d’Attente

Ce délai de 5 secondes correspond exactement à notre paramètre de délai d’attente. Il semble qu’à mesure que notre application subit une charge concurrente supérieure au nombre de travailleurs Puma, de plus en plus de requêtes de base de données dépassent le délai d’attente. C’est un nouveau défi à relever.

Le paramètre de délai d’attente dans notre fichier database.yml est lié à l’une des options de configuration de SQLite, à savoir busy_timeout. Au lieu de renvoyer immédiatement l’exception BUSY, vous pouvez indiquer à SQLite d’attendre jusqu’à un certain nombre de millisecondes. SQLite tentera de réacquérir le verrou d’écriture en utilisant une sorte de stratégie de retour exponentiel. Si le verrou ne peut pas être acquis dans la fenêtre de délai d’attente, alors seulement l’exception BUSY sera lancée.

Mécanisme de Mise en File d’Attente

Imaginons que notre application envoie quatre requêtes d’écriture à la base de données simultanément. L’une d’elles obtiendra le verrou d’écriture en premier et s’exécutera, tandis que les trois autres seront mises en file d’attente, exécutant la logique de réacquisition. Une fois la première requête d’écriture terminée, l’une des requêtes en file d’attente tentera de réacquérir le verrou et réussira, tandis que les deux autres continueront à rester en file d’attente.

Ce mécanisme de mise en file d’attente est essentiel pour éviter les exceptions SQLITE_BUSY. Cependant, un goulot d’étranglement de performance majeur se cache dans les détails de cette fonctionnalité pour les applications Rails.

Problèmes de Performance avec le GVL

Étant donné que SQLite est intégré dans votre processus Ruby, il est crucial de libérer le verrou global de la machine virtuelle Ruby (GVL) lorsque les liaisons Ruby-SQLite exécutent le code C de SQLite. Par défaut, la gem sqlite3-ruby ne libère pas le GVL lors de l’appel à SQLite. Bien que cela soit généralement une décision raisonnable, cela nuit considérablement au débit lors de l’utilisation de busy_timeout.

En ne permettant pas à un autre travailleur Puma d’acquérir le GVL pendant qu’un travailleur attend le retour d’une requête de base de données, le premier travailleur continue de détenir le GVL même lorsque les opérations Ruby sont complètement inactives. Cela signifie que les travailleurs Puma concurrents ne peuvent même pas envoyer de requêtes d’écriture simultanées à la base de données SQLite, ce qui force notre application Rails à traiter les requêtes web de manière quelque peu linéaire. Cela ralentit considérablement le débit de notre application Rails.

Conclusion

Pour optimiser les performances de votre application Rails utilisant SQLite, il est essentiel de configurer correctement les transactions et de gérer les délais d’attente. En appliquant ces ajustements, vous pouvez améliorer la gestion des requêtes concurrentes et réduire les erreurs, tout en maintenant une performance optimale.

Optimisation de la gestion des requêtes dans les applications Ruby avec SQLite

Introduction à la gestion des requêtes concurrentes

Dans le cadre des applications Ruby utilisant SQLite, il est essentiel de permettre à nos processus de traitement de requêtes de fonctionner simultanément. Cela implique de gérer le verrou global (GVL) de manière efficace, surtout lorsque des requêtes d’écriture sont en attente d’acquérir le verrou d’écriture de SQLite.

Utilisation des gestionnaires de délai

SQLite offre une fonctionnalité intéressante appelée busy_timeout, qui est en réalité une implémentation spécifique d’un gestionnaire de délai (busy_handler). Ce dernier permet aux applications d’implémenter leur propre logique de gestion des délais. Le gem sqlite3-ruby sert de pilote SQLite, fournissant des liaisons Ruby pour l’API C de SQLite. Grâce à cela, nous pouvons créer un rappel Ruby qui sera exécuté chaque fois qu’une requête est mise en attente.

Implémentation de la logique de délai

Voici un exemple d’implémentation en Ruby qui reflète la logique de busy_timeout de SQLite. À chaque appel de ce rappel, un compteur est transmis, indiquant combien de fois la requête a été mise en attente. Ce compteur est crucial pour déterminer la durée d’attente avant de réessayer d’acquérir le verrou d’écriture. En utilisant la méthode sleep de Ruby, nous garantissons que le GVL est libéré pendant que la requête attend.

Amélioration de la latence

En libérant le GVL pendant que les requêtes attendent, nous avons considérablement amélioré notre latence p99, même sous une charge concurrente. Cependant, des cas extrêmes persistent. En examinant la latence p99.99, nous constatons une tendance à la hausse.

Analyse des requêtes lentes

Nos requêtes les plus lentes deviennent progressivement plus lentes à mesure que la charge concurrente augmente. Ce phénomène est une courbe de croissance que nous souhaitons aplanir. Pour y parvenir, il est crucial de comprendre les raisons sous-jacentes de cette situation.

Problèmes liés aux requêtes anciennes

Le problème réside dans notre ré-implémentation Ruby de la logique busy_timeout, qui pénalise les requêtes plus anciennes. Cela nuit à notre performance sur le long terme, car les réponses se segmentent naturellement entre les requêtes « jeunes » et « anciennes ». Pour illustrer ce point, examinons le fonctionnement de notre logique busy_timeout en Ruby.

Premier appel du rappel

Lors de la première mise en attente d’une requête, le compteur est à zéro. Comme ce chiffre est inférieur à 12, nous entrons dans le bloc conditionnel. Nous récupérons le premier élément du tableau des délais, qui est de 1 milliseconde. À ce stade, la requête n’a pas encore été retardée.

Appels successifs

Au dixième appel, le compteur est de 10. Nous récupérons alors le dixième élément du tableau des délais, qui est de 50 millisecondes. En additionnant les retards précédents, nous constatons que la requête a déjà été retardée de 178 millisecondes. À ce moment-là, nous dormons pendant 50 millisecondes avant de rappeler le gestionnaire.

Appels ultérieurs

Lors du 58ème appel, le compteur dépasse 12, ce qui nous fait entrer dans le bloc else. À partir de ce moment, chaque appel entraînera un délai fixe de 100 millisecondes. Cela signifie que les requêtes plus anciennes subiront des retards de manière systématique, ce qui peut nuire à la performance globale.

Conclusion

Pour optimiser la gestion des requêtes dans les applications Ruby utilisant SQLite, il est crucial de réévaluer notre approche de la logique de délai. En comprenant les impacts des requêtes anciennes et en ajustant notre stratégie, nous pouvons améliorer la performance et réduire la latence, même sous des charges concurrentes élevées.

La somme de l’ensemble du tableau des délais est de 328, et en soustrayant 12, nous obtenons 46. En multipliant 46 par 100, nous avons 4600. En ajoutant cela à 328, nous arrivons à un total de 4928. À ce stade, notre requête a été retardée de 4928 millisecondes.

100 + 4928 donne 5028, ce qui dépasse effectivement 5000, nous entrons donc dans le bloc conditionnel.

Enfin, nous levons l’exception.

Il est vrai que passer en revue ce code peut sembler un peu fastidieux, mais il est essentiel que nous comprenions tous comment le mécanisme de busy_timeout de SQLite gère les requêtes en attente. Lorsque je dis qu’il pénalise les anciennes requêtes, je veux dire qu’il les rend beaucoup plus susceptibles de devenir des requêtes expirées sous une charge constante. Pour comprendre pourquoi, revenons à nos requêtes en attente…

Suivons combien de fois chaque requête a été réessayée dans notre exemple simple ci-dessus.

Nos trois requêtes restantes ont été réessayées une fois…

Et maintenant, les deux requêtes restantes sont, au mieux, à leur deuxième réessai.

Notre troisième requête est, encore une fois au mieux, à son troisième réessai. Lors de ce troisième réessai, le délai est déjà de 10 millisecondes. Imaginons qu’à ce moment-là, une nouvelle requête d’écriture soit envoyée à la base de données.

Cette nouvelle requête tente immédiatement d’acquérir le verrou d’écriture, se voit refuser l’accès et fait son premier appel à la fonction de rappel busy_timeout. On lui demandera d’attendre 1 milliseconde. Notre requête originale attend 10 millisecondes, donc cette nouvelle requête aura la possibilité de réessayer avant notre requête plus ancienne.

Tant que le verrou d’écriture est maintenu, notre nouvelle requête se voit demander d’attendre 2 millisecondes ensuite.

Même lorsque le compteur est à 2, elle n’est que sollicitée d’attendre 5 millisecondes. Cette nouvelle requête sera autorisée à réessayer d’acquérir le verrou d’écriture trois fois avant que la requête originale ne puisse réessayer une seule fois.

Ces délais d’attente croissants pénalisent considérablement les requêtes plus anciennes, de sorte que toute requête qui doit attendre même juste 3 réessais est maintenant beaucoup plus susceptible de ne jamais acquérir le verrou d’écriture s’il y a un flux constant de requêtes d’écriture.

Alors, que se passerait-il si, au lieu de retarder progressivement nos réessais, nous faisions simplement en sorte que chaque requête réessaie à la même fréquence, indépendamment de son ancienneté ? Cela signifierait également que nous pourrions nous passer de notre tableau de delays et repenser notre fonction busy_handler dans son ensemble.

C’est précisément ce que nous avons réalisé dans la branche principale de la gemme sqlite3-ruby. Malheureusement, à ce jour, cette fonctionnalité n’est pas encore dans une version taguée de la gemme, mais elle devrait être publiée relativement bientôt. Ce rappel Ruby libère le GVL tout en attendant une connexion en utilisant l’opération sleep et dort toujours 1 milliseconde. Ces 10 lignes de code font une énorme différence dans les performances de votre application SQLite sur Rails.

Rerunons nos scripts de benchmarking et voyons comment se présente notre latence p99.99 maintenant…

Voilà ! Nous avons aplati la courbe. Il y a encore un pic avec une charge supérieure à la moitié du nombre de travailleurs Puma que nous avons, mais après ce pic, notre latence de longue traîne se stabilise autour de la moitié de seconde.

En ce qui concerne les performances, il y a quatre éléments clés que vous devez vous assurer d’appliquer à votre prochaine application SQLite sur Rails…

Nous avons couvert les trois premiers, mais pas le dernier. Le journal d’écriture anticipée (WAL) permet à SQLite de prendre en charge plusieurs lecteurs concurrents. Le mode de journalisation par défaut ne permet qu’une seule requête à la fois, qu’il s’agisse d’une lecture ou d’une écriture. Le mode WAL permet des lecteurs concurrents, mais seulement un écrivain à la fois.

Heureusement, à partir de Rails 7.1, Rails applique une meilleure configuration par défaut pour votre base de données SQLite. Ces changements sont essentiels pour faire fonctionner SQLite de manière optimale dans le contexte d’une application web. Si vous souhaitez en savoir plus sur chacune de ces options de configuration, pourquoi nous utilisons les valeurs que nous faisons, et comment ce groupe spécifique de détails de configuration améliore les choses, j’ai un article de blog qui explore ces détails.

Bien que cela ne soit pas une exigence, il existe un cinquième levier que nous pouvons actionner pour améliorer les performances de notre application. Étant donné que nous savons que SQLite en mode WAL prend en charge plusieurs connexions de lecture simultanées mais seulement une connexion d’écriture à la fois, nous pouvons reconnaître qu’il est possible que le pool de connexions Active Record soit saturé de connexions d’écriture, bloquant ainsi les opérations de lecture concurrentes.

Optimisation des Performances de SQLite avec Rails

Gestion des Connexions dans un Environnement Concurrent

Lorsque vous disposez d’un pool de connexions limité à trois et que vous recevez cinq requêtes simultanées, que se passe-t-il si les trois connexions sont attribuées à des requêtes d’écriture ? Les requêtes de lecture restantes devront patienter jusqu’à ce qu’une des requêtes d’écriture libère une connexion. En théorie, grâce à l’utilisation de SQLite en mode WAL (Write-Ahead Logging), les requêtes de lecture ne devraient jamais être bloquées par des requêtes d’écriture. Pour garantir cela, il est essentiel de créer deux pools de connexions distincts : un pour les opérations de lecture et un autre pour les opérations d’écriture.

Mise en Place de Pools de Connexions Distincts

Rails offre la possibilité de gérer plusieurs bases de données, ce qui nous permet d’atteindre cet objectif. Plutôt que de diriger les configurations de base de données pour la lecture et l’écriture vers des bases de données séparées, nous les orientons vers une seule base de données tout en créant deux pools de connexions isolés avec des configurations distinctes.

Le pool de connexions pour la lecture sera exclusivement composé de connexions en lecture seule, tandis que le pool pour l’écriture ne contiendra qu’une seule connexion.

Configuration des Modèles Active Record

Nous pouvons configurer nos modèles Active Record pour qu’ils se connectent au pool de connexions approprié en fonction de leur rôle. Conceptuellement, nous souhaitons que nos requêtes fonctionnent comme des transactions différées dans SQLite. Chaque requête devrait par défaut utiliser le pool de connexions de lecture, mais lorsqu’il est nécessaire d’écrire dans la base de données, nous basculons vers le pool d’écriture uniquement pour cette opération. Pour cela, nous utiliserons la fonctionnalité de changement de rôle automatique de Rails.

Initialisation et Configuration des Connexions

En intégrant ce code dans un initialiseur, nous forçons Rails à définir la connexion par défaut pour toutes les requêtes web sur le pool de lecture. Nous ajustons également la configuration de délai, car nous n’utilisons pas de bases de données distinctes, mais seulement des connexions séparées. Ainsi, il n’est pas nécessaire de garantir que les requêtes « lisent leurs propres écritures » avec un délai.

Nous pouvons ensuite modifier la méthode transaction de l’adaptateur ActiveRecord pour qu’elle se connecte à la base de données d’écriture.

Amélioration des Performances

Ces ajustements permettent à nos « requêtes différées » d’utiliser des pools de connexions isolés. Lors des tests sur le point de terminaison de création de commentaires, nous observons une amélioration des performances en termes de requêtes simples par seconde.

Voici cinq niveaux d’amélioration des performances que vous devriez envisager pour votre application SQLite sur Rails.

Simplification de l’Intégration des Améliorations

Cependant, il n’est pas nécessaire de passer par toutes ces améliorations dans votre application Rails. Comme mentionné précédemment, vous pouvez simplement installer le gem d’adaptateur amélioré. Si vous souhaitez utiliser les pools de connexions isolés, il vous suffit d’ajouter cette configuration à votre application. Il s’agit d’une fonctionnalité expérimentale plus récente, c’est pourquoi vous devez choisir de l’activer.

Conclusion sur l’Optimisation de SQLite avec Rails

j’espère que cette exploration des outils, techniques et configurations par défaut pour les applications SQLite sur Rails vous a démontré la puissance, la performance et la flexibilité de cette approche. Rails est véritablement le meilleur framework d’application web pour travailler avec SQLite aujourd’hui. L’écosystème croissant de la communauté, avec ses outils et gems, est sans égal. C’est le moment idéal pour commencer une application SQLite sur Rails et explorer ces possibilités par vous-même.

J’espère que vous vous sentez désormais confiant quant aux méthodes et raisons d’une performance optimale lors de l’exécution de SQLite en production avec Rails.

Général

Anker SOLIX dévoile la Solarbank 2 AC : la nouvelle ère du stockage d’énergie ultra-compatible !

Découvrez le Solarbank 2 AC, une véritable révolution dans le domaine de l’énergie solaire ! Grâce à ses batteries au phosphate de fer lithium, ce système s’adapte parfaitement à vos besoins. Avec une puissance impressionnante de 2400 watts et la possibilité d’ajouter jusqu’à cinq batteries supplémentaires, il assure un stockage optimal. Sa compatibilité avec le compteur Anker SOLIX Smart favorise une gestion intelligente de votre consommation énergétique. Ne ratez pas l’offre spéciale « early bird », disponible dès maintenant pour seulement 999 euros ! Saisissez cette chance unique !

Published

on

Anker SOLIX dévoile la Solarbank 2 AC : la nouvelle ère du stockage d’énergie ultra-compatible !

Le Solarbank 2 AC : Une Révolution dans le Stockage Énergétique

Batteries au Lithium Fer Phosphate

Le Solarbank 2 AC se démarque par l’utilisation de batteries au lithium fer phosphate (LFP), reconnues pour leur sécurité et leur efficacité. Ce modèle est particulièrement innovant grâce à son système de couplage alternatif, qui lui permet de s’adapter facilement à divers systèmes solaires déjà en place.Que ce soit pour des installations sur toiture, des systèmes solaires compacts pour balcons ou d’autres configurations réduites, il peut fonctionner avec un micro-onduleur de 800 Watts.

Capacité et flexibilité Énergétique

Avec une capacité maximale d’injection dans le réseau domestique atteignant 1200 watts,le Solarbank 2 AC peut être associé à deux régulateurs solaires MPPT. Cela ouvre la possibilité d’ajouter jusqu’à 1200 watts supplémentaires via des panneaux solaires additionnels, portant ainsi la puissance totale à un impressionnant 2400 watts. Pour les utilisateurs nécessitant davantage de stockage énergétique, il est possible d’intégrer jusqu’à cinq batteries supplémentaires de 1,6 kilowattheure chacune, augmentant la capacité totale à 9,6 kilowattheures.

Intégration dans un Écosystème Intelligent

Le Solarbank 2 AC s’intègre parfaitement dans un écosystème énergétique intelligent grâce à sa compatibilité avec le compteur Anker SOLIX Smart et les prises intelligentes proposées par Anker. cette fonctionnalité permet une gestion optimisée de la consommation électrique tout en réduisant les pertes énergétiques inutiles. De plus, Anker SOLIX prévoit d’étendre cette compatibilité aux dispositifs Shelly.

Durabilité et Résistance aux Intempéries

Anker SOLIX met également l’accent sur la longévité du Solarbank 2 AC. Conçu pour supporter au moins 6000 cycles de charge, cet appareil a une durée de vie estimée dépassant quinze ans. Il est accompagné d’une garantie fabricant décennale et possède une certification IP65 qui assure sa résistance face aux intempéries tout en étant capable de fonctionner dans des températures variant entre -20 °C et +55 °C.

Disponibilité et Offres Promotionnelles

Le solarbank 2 AC est disponible sur le site officiel d’Anker SOLIX ainsi que sur Amazon au prix standard de 1299 euros. Cependant, une offre promotionnelle « early bird » sera active du 20 janvier au 23 février 2025, permettant aux acheteurs intéressés d’acquérir cet appareil dès 999 euros ! Cette promotion inclut également un compteur Anker SOLIX Smart offert pour chaque commande passée durant cette période spéciale.

le Solarbank 2 AC représente une avancée significative dans le domaine du stockage énergétique domestique grâce à ses caractéristiques techniques avancées et son engagement envers la durabilité environnementale.

Continue Reading

Technologie

Ne manquez pas cette offre incroyable : le Air Fryer Moulinex Easy Fry Max à -42% sur Amazon !

Les soldes d’hiver sont là ! Ne ratez pas l’incroyable offre d’Amazon sur le Moulinex Easy Fry Max, à seulement 69 euros au lieu de 119 euros, soit une réduction sensationnelle de -42% ! Avec sa capacité généreuse de 5 L, cette friteuse sans huile est idéale pour régaler jusqu’à 6 convives. Grâce à ses 10 programmes de cuisson et son interface tactile intuitive, préparez des plats sains et savoureux en un clin d’œil. Dépêchez-vous, les stocks s’épuisent vite et cette offre est limitée dans le temps !

Published

on

Ne manquez pas cette offre incroyable : le Air Fryer Moulinex Easy Fry Max à -42% sur Amazon !

Technologie

Les soldes d’hiver sont en cours, et Amazon en profite pour offrir des promotions intéressantes, notamment sur les friteuses à air. Actuellement, le Moulinex Easy Fry Max est proposé à un prix attractif de 69 euros au lieu de 119 euros, ce qui représente une réduction immédiate de 42 %. C’est une occasion parfaite pour acquérir une friteuse sans huile XL d’une capacité généreuse de 5 L, idéale pour préparer des repas pour jusqu’à six personnes à un tarif très compétitif.

Étant donné que cette offre est limitée dans le temps,il est conseillé d’agir rapidement si vous souhaitez en bénéficier. De plus, avec un tel prix, les stocks pourraient s’épuiser rapidement. Ce modèle se classe parmi les meilleures ventes sur Amazon avec plus de 1000 unités écoulées le mois dernier.

Profitez des offres sur Amazon

Amazon propose également la livraison gratuite et rapide pour cet article qui bénéficie d’une garantie de deux ans. En outre, il existe une option de paiement échelonné en quatre fois sans frais sur ce modèle. Enfin, sachez que vous avez la possibilité de changer d’avis et retourner le produit gratuitement dans un délai de 30 jours afin d’obtenir un remboursement intégral.

Moulinex Easy Fry Max : cuisinez sainement pour toute la famille

Le moulinex Easy Fry Max fonctionne comme un four à air chaud permettant la préparation de plats savoureux tout en utilisant peu ou pas du tout d’huile. En plus des frites croustillantes qu’il réalise parfaitement, cet appareil se révèle très polyvalent et peut cuisiner une multitude d’autres recettes.

avec ses dix programmes prédéfinis adaptés à divers ingrédients tels que poulet,steak,poisson ou légumes ainsi que des options pour bacon et desserts comme les pizzas ,cet appareil répond aux besoins variés des familles modernes. De plus, Moulinex met à disposition un livre numérique rempli de recettes accessible via QR Code afin que vous puissiez facilement trouver l’inspiration culinaire lorsque nécessaire.

Sa capacité généreuse permet non seulement la préparation rapide mais aussi économique : jusqu’à 70 % moins énergivore et presque deux fois plus rapide qu’un four traditionnel ! Son interface intuitive avec écran tactile facilite son utilisation quotidienne.

en outre, le panier antiadhésif compatible lave-vaisselle simplifie grandement l’entretien après chaque utilisation. N’oubliez pas qu’il s’agit là encore d’une offre temporaire ; ne tardez donc pas si vous souhaitez profiter du meilleur prix possible sur cette friteuse innovante !

Pour accéder à cette remise exceptionnelle :

Continue Reading

Technologie

TikTok revient en force aux États-Unis, mais pas sur l’App Store !

Le suspense autour de TikTok est à son comble ! En avril 2024, le Congrès américain a voté une loi obligeant l’application à changer de propriétaire avant le 19 janvier. Les utilisateurs ont anxieusement attendu la décision finale. Bien que TikTok ait brièvement cessé ses activités, elle est revenue en ligne, mais absente de l’App Store. Apple justifie cette décision par des obligations légales. Cependant, les utilisateurs peuvent toujours accéder à leur compte… sans mises à jour. L’avenir de TikTok pourrait prendre un tournant décisif avec les promesses du nouveau président.

Published

on

TikTok revient en force aux États-Unis, mais pas sur l’App Store !

Technologie

En avril 2024, le Congrès américain a adopté une législation obligeant TikTok à trouver un nouvel acquéreur, ByteDance étant accusé d’activités d’espionnage. Les utilisateurs de l’submission aux États-Unis ont donc attendu avec impatience le week-end précédent la date limite du 19 janvier pour savoir si TikTok serait interdit dans le pays.

Bien que TikTok n’ait pas réussi à dénicher un repreneur avant cette échéance, l’application a temporairement suspendu ses activités… mais seulement pour quelques heures. le réseau social est désormais de retour en ligne, mais il n’est plus accessible sur l’App Store.

Retour de TikTok : Une Absence Persistante sur l’App Store

Apple a expliqué sa décision de retirer TikTok de son App store par un communiqué officiel. « Apple doit respecter les lois en vigueur dans les régions où elle opère. Selon la loi Protecting Americans from Foreign Adversary Controlled Applications act, les applications développées par ByteDance ltd., y compris TikTok et ses filiales comme CapCut et Lemon8, ne pourront plus être téléchargées ou mises à jour sur l’App Store pour les utilisateurs américains après le 19 janvier 2025 », précise la société.

Il est crucial de souligner que les utilisateurs américains ayant déjà installé TikTok peuvent toujours accéder au service. Cependant, ils ne recevront plus aucune mise à jour future de l’application. L’avenir du réseau social pourrait dépendre des décisions du nouveau président des États-Unis.

DÉCLARATION DE TIKTOK :

>

En collaboration avec nos partenaires techniques, nous travaillons activement à rétablir notre service. Nous remercions le président Trump pour avoir clarifié la situation et rassuré nos partenaires qu’ils ne subiront aucune sanction en continuant d’offrir TikTok aux plus de 170 millions d’utilisateurs…

Le successeur de Joe Biden sera investi comme président ce lundi 20 janvier et prévoit d’émettre un décret afin d’accorder un délai supplémentaire à TikTok pour trouver un acquéreur potentiel.Donald Trump propose même que les États-Unis détiennent une participation significative dans cette application.

« Je souhaite que les États-Unis possèdent une part importante dans une coentreprise avec cet outil numérique afin que nous puissions préserver son intégrité tout en lui permettant d’évoluer […]. Ainsi,notre pays détiendrait la moitié des parts dans une coentreprise établie entre nous et tout acheteur sélectionné »,a déclaré Donald Trump.

L’avenir immédiat de TikTok pourrait donc connaître des évolutions majeures très prochainement. Il convient également de noter qu’une rumeur circulait selon laquelle Elon Musk envisagerait d’acquérir des parts dans la plateforme,mais celle-ci a été rapidement démentie par un porte-parole officiel.

Continue Reading

Trending

Copyright © 2024 Tecknews.