Beste JPoint 2018 Papers: Java / JVM und seine Leistung, Kotlin, Spring, Docker

Wir haben bereits Videos von JPoint 2018-Berichten auf YouTube veröffentlicht und speziell für den Java-Hub auf Habré haben wir den Konferenzbesuchern eine traditionelle Auswahl der besten getroffen.


Wie üblich gibt es oben „Junior“ -Berichte mit der höchsten Bewertung am Ende. Dies bedeutet natürlich nicht, dass ein Bericht viel schlechter ist als ein anderer: Wenn Sie die Berechnungsmethode ändern, können sich die Orte leicht ändern. In Wirklichkeit haben wir es geändert, jetzt wird die „Soft Quorum“ -Version des Ratings verwendet, wobei die Anzahl der im Bericht anwesenden Teilnehmer berücksichtigt wird. Dieser Ansatz hat seine Nachteile (zum Beispiel kommen mehr Menschen zur Keynote als zu einem regulären Bericht, einfach weil das Publikum keine Wahl hat), gibt aber insgesamt ein besseres Bild davon, was passiert ist.


Unter dem Schnitt - und Videos der besten Berichte und Links zu ihren Präsentationen und Kurzbeschreibungen sowie einem Link zur vollständigen Wiedergabeliste.



Vollständige Wiedergabeliste


Die vollständige Wiedergabeliste mit allen unten diskutierten Videos finden Sie hier .


10. Linux-Container-Leistungstools für JVM-Anwendungen


Folien herunterladen



Die Containerrevolution hat alle erfasst - die Java-Welt war nicht ohne sie. Trotzdem hatte und hat Java immer bestimmte Probleme und Funktionen, die im Bericht von Sasha Goldstein erörtert werden.


Sasha ist der Serienschöpfer des Performance-Hardcore. Letztes Jahr hielt er bei JPoint ein großartiges Gespräch über die Verwendung des Berkeley-Paketfilters für die JVM (ich empfehle dringend, einen YouTube-Beitrag anzusehen), und es war nur eine Frage der Zeit, bis er sich eingehend mit der Containerisierung befasste. Die Welt geht in die Wolken und Hafenarbeiter, was uns wiederum viele neue Probleme bringt. Wie Sie vielleicht bemerkt haben, sind die meisten Debugging- und Profiling-Systeme auf niedriger Ebene, nachdem sie auf Container angewendet wurden, von verschiedenen Funktionen und Pfosten umgeben. Sasha ging die wichtigsten Szenarien (CPU-Auslastung, E / A-Reaktionsfähigkeit, Zugriff auf gemeinsam genutzte Datenbanken usw.) durch, indem er moderne Tools auf der GNU / Linux-Plattform verwendete, einschließlich BCC und perf.


Nicht jeder braucht diese Spezifität. Dies ist einer der Gründe, warum der Bericht nur auf dem zehnten Platz lag - er wurde von ungefähr zweihundert Personen besucht (verglichen mit mehr als tausend aus Tolkachev und Borisov), und unser Bewertungsberechnungsalgorithmus reagiert sehr empfindlich auf die Größe des Publikums.


Für diejenigen, die irgendwie mit Containern verbunden sind, muss dieser Bericht angezeigt werden. Eine unabhängige Suche nach unzähligen Dienstprogrammen und deren Verwendung spart viel Zeit bei der unabhängigen Suche nach allen Details.


Ich möchte auch darauf hinweisen, dass Sashas Bericht aus den Top 10 in Bezug auf die Menge an praktischen Informationen pro Zeiteinheit fast am dichtesten ist. Von fast jeder Folie können Sie sich einige nützliche Dinge kopieren. Um mich nicht auf eine detaillierte Nacherzählung einzulassen, werde ich nur die Oberflächenstruktur der Präsentation zeigen:


Berichtsübersicht
  • Wie sind die Container angeordnet?
    • Kontrollgruppen: CPU, Speicher, Block-E / A;
    • Namespaces: PID-Namespace, Mount-Namespace, Netzwerk-Namespace;
  • Der Unterschied zwischen den auftretenden Problemen:
    • Auf dem Host;
    • Im Container;
    • Beispiele für Probleme mit Lösungen:
      • Verbindung zu JVM?
      • JVM-Leistungsdaten?
    • Demo-JVM-Tools auf dem Host;
  • Ressourceninformationstools:
    • Beiwagen zur Überwachung;
    • Docker-Statistiken;
    • systemd-cgtop;
    • htop + cgroup ID;
    • nsenter oder docker exec;
    • Demo-Überwachung von Containerressourcen;
  • Profilerstellung von CPU-Containern:
    • Perf auf dem Host: -G, Symbol-Mapping, PID-Mapping, Sharing-Perf-Map (Perf-Map-Agent);
    • Demo mit Flamegrammen; oos;
    • Perf im Container im nicht privilegierten Modus;
    • Ehrlicher-Profiler, Async-Profiler, Perf vs Async-Profiler;
    • Demo-Async-Profiler;
    • BCC ist ein Profiling-Tool (es löst eine Reihe von Problemen selbst, funktioniert jedoch nur unter Linux 4.9+).
    • Drosselung;
  • Andere Überwachungsmethoden:
    • cAdvisor, SysDig, New Relic, DataDog ...

9. Einmal im Jahr blühen Gärten: Analysieren Sie die Semantik von „genau einmal“ Apache Kafka


Folien herunterladen



Victor Gamov hat einen völlig unfairen Vorteil gegenüber anderen Rednern. Dies ist der Mann, der fast zweihundert Ausgaben des Debriefing-Podcasts veröffentlicht hat, der Autor einer Reihe von Berichten, Texten, Beiträgen und sogar des Buches „Enterprise Web Development“ von O'Reilly. Die Anwesenheit von Gamow macht alles besser. Ich bin sicher, er könnte mit der gleichen Intonation nicht über Kafka erzählen, sondern über das Wachstum von Geranien auf der Fensterbank, und das wäre immer noch faszinierend.


Hier haben wir einen Sonderfall: das anfangs ganzheitliche Thema über die Semantik von „genau einmal“. Kafka beeilte sich, alles in einem außergewöhnlichen Umfang zu nutzen, was die Verarbeitung der traditionellen Semantik der Nachrichtenübermittlung erforderte. Nehmen Sie keinen Finger in den Mund - sie haben unterwegs ihre Schuhe unter dem richtigen Protokoll- und Nachrichtenformat gewechselt und alles getan, was sie brauchten. Während des gesamten Berichts spricht Victor darüber, wie es im Inneren angeordnet ist und was es beeinflusst.


Zwei Neuigkeiten, gut und schlecht. Gut: Alles ist in Kafka eingerichtet. Schlecht: Alles ist in Kafka eingerichtet. Um damit zu leben, müssen Sie verstehen, wie es funktioniert und wo Sie mit Ihren schmutzigen Händen klettern können.


Man könnte von Victor eine Art Smoothie erwarten, aber dann bekam er einen verzweifelten Hardcore, und der Plan ist ungefähr so:


Berichtsübersicht
  • Einführung in Kafka:
    • Themen
    • Partitionen
    • Protokolle und Offsets
    • Hinweise und Führer
    • Kunden: Hersteller und Verbraucher
  • Produzent
    • Wie es an Beispielen funktioniert
    • Herstellerprotokoll
  • Verbraucher
    • Wie es an Beispielen funktioniert
    • Verbraucherprotokoll
  • Verarbeitungsmodell
    • Lesen, zählen, aufzeichnen
    • Arten von Pannen (alles brach, Zombies)
  • Verarbeitungssemantik
    • Mindestens einmal, höchstens einmal, genau einmal
  • Semantik "genau einmal"
    • Mit Beispielen
    • Schwächen
      • unsichere Wiederholungsversuche
      • nichtatomare Offsetaufzeichnung
      • Zombies
  • Behebung der ersten Schwäche: ein idempotenter Produzent
  • Beheben Sie die zweite Schwäche:
    • Chandy Lamport Schnappschüsse
      • Prinzip
      • Wie kann man mit Fehlern leben?
        • Schwer: Absturz während der Verarbeitung
        • Soft: Absturz vor oder während der Entfernung des Schnappschusses
    • Transaktionen in Kafka
      • Zwei Arten von Markern (COMMIT, ABORT)
      • Atomaufnahme auf vielen Partitionen (einschließlich! _Consumer_offsets)
  • Beheben Sie die dritte Schwäche: Zombie-Fechten
  • Consumer Reading Isolation
  • End-to-End-EOS
    • Kafka Verbindungsquelle
    • Kafka strömt
    • Kafka Connect Waschbecken

8. Kampf gegen russische Hacker mit Kafka Streams und Firehose API


Folien herunterladen



Wieder Kafka! Wieder Gamow! Ja, und jetzt mit Baruch Sadogursky ( jbaruch ). Trotzdem ist dieser Bericht kein Smoothie, sondern ein sehr spezifisches praktisches Stück darüber, wie auf der Bintray-Plattform (von der Baruch der Gott ist) mit Apache Kafka (für den Victor verantwortlich ist) und Firehose Verhaltensmuster analysiert und große Datenmengen verarbeitet werden.


Wenn der vorherige Bericht über die Innenseiten von Kafka 245 Folien hatte, dann hat diese nur 17. Dies liegt daran, dass Sie es sehen müssen! Dies ist in erster Linie ein lebhafter Dialog zwischen führenden und Live-Demos. Verweilen Sie nicht, öffnen Sie den Vidosik und schauen Sie.


7. Hardware-Transaktionsspeicher in Java


Folien herunterladen



Nikita Koval ( ndkoval ) ist Forscher bei JetBrains im Kotlin-Team und Doktorand bei IST Austria (er war zum Zeitpunkt des Vortrags bei Devexperts). Sein Bericht steht in krassem Gegensatz zu den "russischen Hackern", da es sich nicht um eine leichte, unterhaltsame Lektüre handelt, sondern um eine Geschichte über die komplizierten Interna von VM. Wenn Sie sich die Folien ansehen, finden Sie 150 Blätter, von denen die meisten Code sind.


Wenn Sie Anfang 2018 bei JBreak waren, haben Sie vielleicht Nikitas Geschichte über ganz andere Dinge gefunden - über das Schreiben einer schnellen Multithread-Hash-Tabelle mit der Kraft moderner Multi-Core-Architekturen und spezieller Algorithmen. Stimmen Sie zu, Nikita hat einen Stil . Ich erinnere mich sofort an Shipilev.


Dieses Mal werden wir über das Transaktionsgedächtnis sprechen, das in modernen Prozessoren allmählich auftritt, dessen Verwendung jedoch für einen normalen Menschen aus der JVM-Welt noch unklar ist. Außerhalb der JVM ist natürlich alles einfacher. Aber stellen Sie sich vor, was Sie einem normalen Spring-Webentwickler sagen: "Ja, bearbeiten Sie einfach vmstructs, stapeln Sie Ihre Eigenheiten, erstellen Sie OpenJDK neu und fertig!" Und er ist so: "Natürlich mache ich das jeden Tag!". Nikita spricht nur sehr deutlich über Verwendungsmöglichkeiten, welche Optimierungen bereits in OpenJDK vorhanden sind und wie Transaktionen direkt aus Java-Code ausgeführt werden.


Berichtsübersicht
  • Einführung: Warum brauchen wir Multithreading?
  • Algorithmen zur Erstellung von Algorithmen
    • Grobe Sperre
    • Dünnes Schloss
    • Nicht blockierende Synchronisation
    • Alle drei Typen sind in der Beispielaufgabe über eine Spielzeugbank dargestellt.
  • Multithreading ist kompliziert. Was zu tun ist?
    • Transaktionen in einer perfekten Welt. Schreiben Sie einfach atomar!
    • Woher bekommt man Atom:
      • Software Transactional Memory (STM). Scala STM, NOrec, Coroutines.
      • Hardware Transactional Memory (HTM). Haswell, Macht 8.
      • Hybrid-Transaktionsspeicher
    • Intel RTM anhand von Beispielen
      • XBEGIN, XEND, XABORT, XTEST
      • Intel RTM + Java
        • Elision sperren
        • java.util.concurrent.RTMSupport
      • Intrinsics: Dolmetscher, C1, C2
      • Grobkörnig / Lock-frei + RTMS-Unterstützung in Diagrammen

6. Wir profilieren mit Genauigkeit auf Mikrosekunden und Prozessoranweisungen


Folien herunterladen



Sergey Melnikov ( RainM ) von der Raiffeisenbank brachte uns den zweiten Profilierungsbericht. Interessanterweise arbeitete er vor seiner Arbeit an Java-Code mit geringer Latenz bei Intel als Compiler-Performance-Ingenieur für C / C ++ / FORTRAN-Sprachen. Dieser Bericht hat auch perf! :-) Es gibt auch Informationen zu den Hardwarefunktionen von Prozessoren und der Intel Processor Trace-Technologie, mit denen Sie den nächsten Schritt zur Profilerstellung und zur Rekonstruktion der Ausführung eines Programmabschnitts ausführen können. Es gibt nur wenige solcher Berichte (zum Beispiel finden Sie den Andi Kleen-Bericht auf dem Tracing Summit 2015), die normalerweise ein Meer von Fragen hinterlassen und in Bezug auf Java nicht praktisch sind. Hier haben wir nicht nur eine Person, die beide Welten besucht hat (Intel und Java in der Bank), sondern auch weiß, wie man komplexe Themen klar erklärt.


Berichtsübersicht
  • Was ist das und warum ist es notwendig?
    • Themenbereich - Anwendungen mit geringer Latenz
    • Moskauer Austausch Beispiel
  • Wählen Sie einen Profiler
    • Wie profilieren? Sampling- und Instrumentierungsprofiler
    • Async-Profiler
  • Wir bringen dem Profiler bei, ein detailliertes Profil zu erstellen
    • Wie man perf läuft
    • So schauen Sie im Profil, im Aufrufstapel
    • perf-map-agent, sysctl, dmesg ...
  • Verwenden von PMU / PEBS-Ereignissen in perf
  • Intel Processor Trace - Was ist das und wie wird Java profiliert?
    • Anforderungen: Pakete, Hardware, Betriebssystem
    • Wie läuft man auf Skylake-X (Xeon und i9)

5. VMStructs: Warum muss die Anwendung über JVM-Interna Bescheid wissen?


Folien herunterladen



Andrey ( Apangin ) ist eine Person, die immer wieder die tiefgreifendsten und mächtigsten Berichte sammelt. In der Vergangenheit hat Joker etwas weniger als tausend Menschen versammelt - dies ist ein Rekord in Bezug auf die Publikumsgröße in einem regelmäßigen Bericht, der keine Keynote ist. Dabei hilft ihm ein Jahrzehnt Erfahrung in der Arbeit an virtuellen Maschinen und die Fähigkeit, technischen Hardcore zu erklären, damit er in der Praxis wiederholt werden kann.


Viele verstehen nicht ganz, warum Sie sich mit einer virtuellen Maschine befassen sollten, wenn Sie eine reguläre Anwendung auf einem Tomcat mit einer Datenbank haben und alles so ist, wie es sein sollte. Dieser Bericht enthält ein gutes Argument auf der Ebene "Wie kann man verstehen, welche Abfrage viele Daten abruft?". Wenn Sie versuchen, den Code mit JMX zu instruieren, passiert etwas Seltsames mit der Leistung. Erstens können Sie verstehen, warum dies geschieht, und zweitens, was dagegen getan werden kann. Meiner Meinung nach ist dieser Bericht nicht so sehr wertvoll für eine Reihe von Tools (obwohl es dort ein bisschen um Hilfe geht), sondern für eine Demonstration der richtigen Denkweise des OpenJDK-Entwicklers und des Verhaltens in schwierigen Situationen. Spricht die Präsenz aus und erklärt die Bedeutung bestimmter Dinge wie TLAB, Code Cache, Constant Pool usw.


4. Coroutinen in Kotlin


Folien herunterladen



Nur die Faulen wissen jetzt nichts über Kotlin, und Sie, der Leser, haben einmal bis zum vierten Absatz gelesen - offensichtlich nicht von den Faulen. Roman ( elizarov ) ist ein ehemaliger Entwickler von Hochleistungs-Handelssoftware und jetzt führend in Kotlin-Bibliotheken. Wir haben bereits ein Interview mit Roma über Koroutinen geführt , und es kann sich lohnen, es vor oder nach dem Lesen des Berichts erneut zu lesen . Coroutinen sind ein sehr altes Konzept, da die Zeit von Simula, aber nicht alle gängigen Sprachen sie unterstützen, werden sie nicht bald in Java erscheinen. Aber in Kotlin sind sie bereits in der stabilen Version.


Dieser Bericht beantwortet alle relevanten Fragen zu Coroutinen, dh alle relevanten Fragen unserer Zeit im Allgemeinen :-)


Berichtsübersicht
  • Gesamtbild der Sprachentwicklung
  • Asynchrone Rückrufprogrammierung
  • Futures / Versprechen / Rx
  • Coroutinen in Kotlin
    • Regelmäßige Schleifen, Ausnahmebehandlung, Funktionen höherer Ordnung
    • benutzerdefinierte Funktionen höherer Ordnung
    • Alles sieht aus wie beim Blockieren von Code!
  • Wie funktioniert es
    • Suspendierungsfunktionen, Code mit Suspendierungspunkten
  • Integration
    • Async nachrüsten
    • Rückrufe und Fortsetzungen (call / cc from Scheme!)
    • Contlinx-Coroutinen-Kern
      • jdk, guave, nio, reaktor, rx1, rx2
  • Wie laufen Coroutinen?
  • async / warten
    • Warum gibt es in Kotlin kein Schlüsselwort zum Warten?
    • Parallelität ist schwer. Sie müssen dies explizit tun.
    • Kotlins Herangehensweise an Async
  • Corutin-Konzept: sehr leichte Fäden
  • Interop mit Java
  • Synchrone Coroutinen - erzeugen / ergeben
    • Beispiel für Fibonacci-Zahlen
  • Sequentielle Prozesse kommunizieren (CSP)
  • Bibliothek gegen Sprache
    • Der Kern der Zunge sollte klein sein!
    • Schlüsselwörter: asynchron / warten, generieren / ergeben
    • Modifikatoren: aussetzen
    • kotlinx-coroutines: Start, Async, RunBlocking, Zukunft, Verzögerung, Job, Zurückgestellt, ...

3. Auf den Schultern der Riesen: die Sprachen, die Kotlin studierte


Folien herunterladen



Bericht über Kotlin von einem der Schöpfer der Sprache - was wird sonst noch für das Glück benötigt? Das Wesentliche und die Struktur der Präsentation unterscheiden sich grundlegend von der des vorherigen Berichts von Elizarov. Der Roman erzählte über bestimmte Dinge - was, wie und warum beim Design von Coroutine und wie man sie verwendet, und ich brauche dies, um die Programmierkenntnisse auf Kotlin zu verbessern. Hier spricht Andrei ( abreslav ) über Dinge, die die Gelehrsamkeit im Allgemeinen im Leben verbessern und ein Verständnis für den eigenen Platz in der Welt vermitteln. Wenn Sie all diese Sprachen mit Ihren eigenen Augen gesehen haben - Java, C #, Scala, Groovy, Python, Gosu -, ist dies noch interessanter, da es Grund zur Diskussion gibt (Konferenzbesucher könnten wahrscheinlich die Gelegenheit nutzen und ihr Verständnis der Dinge live im Diskussionsbereich diskutieren ) Dies ist "sieben Sprachen in sieben Wochen", aber nur in einer Stunde.


Übrigens haben wir kürzlich ein separates Interview mit Andrey geführt, aber es geht nicht nur um Kotlin, sondern um viele verschiedene Dinge.


2. Die Abenteuer von Senior Holmes und Junior Watson in der Welt der Softwareentwicklung


Folien herunterladen



Präsentationen mit mehr als einem Redner sind äußerst schwierig. Oft sieht es so aus: Die Hälfte der Zeit steht einer von ihnen auf der Bühne und langweilt sich, und es sieht sehr langweilig aus. Was können Sie über die gemeinsame Aufführung von Baruch Sadogursky und Evgeny Borisov ( EvgenyBorisov ) sagen - im Gegenteil, es wurde großartig gemacht, es ist ein Kunstwerk. Die Stars kamen in der richtigen Reihenfolge zusammen, und zwei Top-Redner mit großer Erfahrung und der Praxis, gepaarte Berichte zu erstellen, erschienen auf der Bühne, um ein Thema zu diskutieren, das für beide interessant war. Warum betone ich das so? Normalerweise haben die Zuschauer keine Ahnung, wie eine solche Präsentation erstellt wird, und sie halten alles für selbstverständlich.


Das Ergebnis rechtfertigte jedoch die Investition. Überzeugen Sie sich selbst, dies ist die abendliche Keynote, der jüngste Konferenzbericht, in der die Leute bereits mit zwei Tagen Zinn erschöpft sind, schlafen wollen, jemand muss sofort nach Hause fliegen und so weiter. Und doch blieben mit Sicherheit mehr als 600 Menschen in der Halle zurück.


Dies ist kein Referenzbericht, sondern ein Bericht, der angezeigt werden muss. Darin enthüllen Holmes und Watson mehrere Rätsel, denen Sie in der täglichen Entwicklung begegnet sind, denen Sie begegnen oder denen Sie begegnen werden. Es wird keinen Müll von Müllsammlern und Bytecode geben, aber es wird Tools, Bibliotheken und Frameworks geben, die gewöhnliche Entwickler in ihrer täglichen Routine verwirren, zu Ausfallzeiten, Profilerstellung von Fristen und langwierigen Depressionen führen. In der Praxis schützen Sherlock und Watson in diesem Bericht Ihre Stirn vor Gesichtspalmen und Rechen, auf die bereits jemand getreten ist.


Daher wird es hier keine kurze Zusammenfassung geben - starten Sie einfach das Video und schauen Sie es sich an.


1. Booten Sie sich, der Frühling kommt


Folien herunterladen




Baruch + Gamow, Baruch + Borisov, wer fehlt bei den Autoren populärer Paarberichte? Das stimmt, Borisov + Tolkachev ( tolkkv ). Ein weiterer cooler Bericht, der keine Keynote war und eine Rekordzahl von Teilnehmern verzeichnete - mehr als tausend. Es gab so viel Material und es ist so interessant, dass im Konferenzprogramm zwei Slots dafür zugewiesen wurden - und Sie müssen sich entsprechend zwei Videos auf YouTube ansehen.


Vor vielen Jahren verwendeten Java-Programmierer "neu", um Dienste zu erstellen. Sie haben viele manuelle Aktionen durchgeführt und die Konfiguration mit der Geschäftslogik gemischt. Sie verwendeten sogar Copy-Paste-Techniken. Es wurden viele Zeilen elenden Codes geschrieben, was manchmal sogar funktionierte.


Dann kam der Frühling. Mit ihm hat sich viel geändert ... Wir haben viel „Magie“ aus dem Spring-Zauberzylinder, und unser Code ist sauberer, einfacher und wartbarer geworden.


Und so erschien Spring Boot. Einerseits werden Tausende bereits bestehender Probleme gelöst: Versionskonflikte, Konfigurationsaufgaben, Arbeiten mit Infrastruktur-Bins, das Problem der Einrichtung der Umgebung und natürlich das Starten oder Bereitstellen einer Anwendung, einschließlich des Erstellens von JAR- / Kriegsarchiven. Auf der anderen Seite hat Spring Boot unserem magischen Zylinder noch mehr Magie verliehen. Infolgedessen gibt es zwei Szenarien:


  • Alles funktioniert super, obwohl niemand weiß wie.
  • Nichts funktioniert und niemand weiß warum.

Dieser Bericht enthüllt die grundlegenden Geheimnisse der Spring Boot-Magie. Sie werden die Grundprinzipien und Konventionen für typische Spring Boot-Anwendungen verstehen. Die Aufgabe von Cyril und Eugene, damit die ganze Magie aus dem Zylinder für Sie zu einem viel transparenteren Prozess wird und Sie nicht nur genießen können, wenn alles funktioniert, sondern auch die Essenz der Probleme verstehen und sie lösen können, ohne Krankenwagen und andere verfügbare Dienste einzubeziehen dringende Anrufe.


Fazit


Ich habe mehrere Tage gebraucht, um alle Videos von der Liste anzusehen. Es war nicht einfach, aber es ist deutlich zu sehen, dass es sich gelohnt hat. In Wirklichkeit gab es auf der Konferenz viel mehr Berichte, und die Top Ten davon zu sehen, ist ein guter Anfang für einen viel größeren Weg. Wenn Sie diese Berichte auch sehen werden - seien Sie nicht zu faul, um Ihre Bewertungen in den Kommentaren zu Habré zu schreiben!


In der Zwischenzeit ist es bereits möglich, Tickets für den nächsten JPoint zu kaufen. Sie findet vom 5. bis 6. April 2019 im WTC Congress Center statt. Bis zum 1. Januar besteht noch die Möglichkeit, Tickets zu günstigen Preisen zu kaufen!

Source: https://habr.com/ru/post/de433858/


All Articles