
Hvordan kom jeg til dette liv?
For nylig arbejdede jeg pĂ„ backendâen af et hĂžjt belastet projekt, hvor jeg skulle organisere regelmĂŠssig udfĂžrelse af et stort antal baggrundsopgaver med komplekse beregninger og forespĂžrgsler til tredjepartsservices. Projektet er asynkront, og inden jeg kom ind i det, var der en simpel mekanisme til planlĂŠgning af opgaver: en lĂžkke der kontrollerede den nuvĂŠrende tid og startede grupper af korutiner gennem gather â denne tilgang viste sig at vĂŠre acceptabel, indtil antallet af korutiner blev titusinder, men da antallet oversteg to tusinde, var vi nĂždt til at overveje at organisere en normal opgavekĂž med en broker, flere workere og lignende.
FÞrst besluttede jeg at prÞve Celery, som jeg tidligere havde brugt. PÄ grund af projektets asynkronitet dykkede jeg ind i spÞrgsmÄlet og sÄ , samt , skabt af forfatteren af artiklen.
Jeg vil sige, at projektet er meget interessant og fungerer ganske godt i andre applikationer i vores team, og forfatteren selv nĂŠvner, at han har vĂŠret i stand til at implementere det i produktion ved at bruge en asynkron pulje. Men desvĂŠrre var det ikke helt egnet til mig, da der opstod vedrĂžrende gruppering af opgaveudfĂžrelser (se ). PĂ„ tidspunktet for skrivningen af artiklen var allerede afsluttet, men arbejdet blev udfĂžrt i lĂžbet af en mĂ„ned. Uanset hvad, Ăžnsker jeg forfatteren held og lykke, da der allerede er fungerende lĂžsninger i biblioteket... Kort sagt, det er mit problem, og for mig var vĂŠrktĂžjet lidt for ufuldstĂŠndigt. Desuden var der i nogle opgaver 2-3 http-forespĂžrgsler til forskellige tjenester, sĂ„ledes at selv ved optimering af opgaverne skaber vi 4.000 tcp-forbindelser cirka hver 2. time â ikke ideelt... Jeg ville gerne have en session pr. opgavetype ved start af workere. Mere om det store antal forespĂžrgsler gennem aiohttp .
Fordi dette begyndte jeg at sĂžge alternativer og fandt! Skaberne af Celery, mere prĂŠcist, som jeg forstod , havde skabt , oprindeligt til projektet . Faust er inspireret af Kafka Streams og arbejder med Kafka som broker, ligeledes anvendes RocksDB til lagring af resultaterne fra arbejdet med agenter, og det vigtigste er, at biblioteket er asynkront.
Du kan ogsĂ„ se celery og faust fra skaberne af den seneste: deres forskelle, forskelle mellem mĂŠglere, implementeringen af en simpel opgave. Det er alt sammen ret enkelt, men faust tiltrĂŠkker opmĂŠrksomhed med en behagelig egenskab â typesikrede data til overfĂžrsel til emner.
Hvad skal vi gĂžre?
SĂ„ i en lille serie artikler vil jeg vise, hvordan man indsamler data i baggrundsopgaver med hjĂŠlp fra Faust. Kilden til vores eksempelprojekt vil, som titlen antyder, vĂŠre . Jeg vil demonstrere, hvordan man skriver agenter (sinks, emner, partitioner), hvordan man udfĂžrer regelmĂŠssige (cron) kĂžringer, de mest praktiske cli-kommandoer i faust (en wrapper over click), simpel clustering, og til sidst vil vi integrere datadog (som fungerer ud af boksen) og forsĂžge at se noget. Til opbevaring af de indsamlede data vil vi bruge mongodb og motor til at forbinde.
P.S. I betragtning af den selvsikkerhed, der er skrevet i afsnittet om overvÄgning, tror jeg, at lÊseren i slutningen af den sidste artikel vil se sÄdan ud:

Krav til projektet
Da jeg allerede har lovet en del, lad os lave en lille liste over, hvad tjenesten skal kunne:
- Hente vĂŠrdipapirer og en oversigt over dem (herunder indtĂŠgter og udgifter, balance, cash flow â for det seneste Ă„r) â regelmĂŠssigt
- Hente historiske data (for hvert handelsĂ„r finde ekstrempriserne for afslutningskurserne) â regelmĂŠssigt
- Hente de seneste handelsdata â regelmĂŠssigt
- Hente en konfigureret liste over indikatorer for hvert vĂŠrdipapir â regelmĂŠssigt
Som sÊdvanligt vÊlger vi et navn til projektet fra det blÄ: horton
Forberede infrastrukturen
Titlen er bestemt stĂŠrk, men alt hvad der skal gĂžres er at skrive en lille konfiguration for docker-compose med kafka (og zookeeper â i en enkelt container), kafdrop (hvis vi vil se beskeder i emnerne), mongodb. Vi fĂ„r [docker-compose.yml]() af fĂžlgende slags:
version: '3'
services:
db:
container_name: horton-mongodb-local
image: mongo:4.2-bionic
command: mongod --port 20017
restart: always
ports:
- 20017:20017
environment:
- MONGO_INITDB_DATABASE=horton
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin_password
kafka-service:
container_name: horton-kafka-local
image: obsidiandynamics/kafka
restart: always
ports:
- "2181:2181"
- "9092:9092"
environment:
KAFKA_LISTENERS: "INTERNAL://:29092,EXTERNAL://:9092"
KAFKA_ADVERTISED_LISTENERS: "INTERNAL://kafka-service:29092,EXTERNAL://localhost:9092"
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT"
KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
KAFKA_ZOOKEEPER_SESSION_TIMEOUT: "6000"
KAFKA_RESTART_ATTEMPTS: "10"
KAFKA_RESTART_DELAY: "5"
ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: "0"
kafdrop:
container_name: horton-kafdrop-local
image: 'obsidiandynamics/kafdrop:latest'
restart: always
ports:
- '9000:9000'
environment:
KAFKA_BROKERCONNECT: kafka-service:29092
depends_on:
- kafka-serviceDer er faktisk ikke noget kompliceret her. For Kafka har vi erklÊret to lyttere: en (intern) til brug inden for det samlede netvÊrk og den anden (extern) til forespÞrgsler udefra, derfor har vi Äbnet den udadtil. 2181 er zookeeper-porten. Resten, tÊnker jeg, er klart.
Vi forbereder projektets skelet
I den grundlÊggende version skal strukturen af vores projekt se sÄledes ud:
horton
âââ docker-compose.yml
âââ horton
âââ agents.py *
âââ alphavantage.py *
âââ app.py *
âââ config.py
âââ database
â âââ connect.py
â âââ cruds
â â âââ base.py
â â âââ __init__.py
â â âââ security.py *
â âââ __init__.py
âââ __init__.py
âââ records.py *
âââ tasks.py **Alt det, jeg har markeret rĂžrer vi ikke ved endnu, men laver blot tomme filer.
Vi har oprettet strukturen. Nu tilfÞjer vi de nÞdvendige afhÊngigheder, skriver konfigurationen og forbindelsen til MongoDB. Jeg vil ikke medtage hele teksten af filerne i artiklen for ikke at gÞre den for lang, sÄ jeg vil lave links til de nÞdvendige versioner.
Lad os begynde med afhĂŠngighederne og metaoplysningerne om projektet â
Derefter starter vi installationen af afhĂŠngighederne og oprettelsen af et virtualenv (eller, du kan selv oprette en mappe venv og aktivere miljĂžet):
pip3 install poetry (hvis ikke allerede installeret)
poetry installLad os nu oprette â credentialer og hvor vi skal kommunikere. Her kan vi ogsĂ„ placere oplysninger til alphavantage. Og sĂ„ gĂ„r vi videre til â vi henter data til applikationen fra vores konfiguration. Ja, jeg beklager, jeg har brugt mit eget bibliotek â .
Forbindelsen med MongoDB er heller ikke besvÊrlig. Vi har erklÊret til forbindelsen og til CRUD-operationer, for at gÞre det lettere at udfÞre forespÞrgsler pÄ samlingerne.
Hvad vil der ske videre?
Artiklen er ikke sÊrlig lang, da jeg kun taler om motivation og forberedelse her, sÄ bÊr over med mig - jeg lover, at der i nÊste del vil vÊre action og grafik.
SĂ„ i denne nĂŠste del skal vi:
- Skrive en lille klient til alphavantage pÄ aiohttp med forespÞrgsler til de endepunkter, vi har brug for.
- Lave en agent, der indsamler data om vÊrdipapirer og historiske priser pÄ dem.
Kilde: habr.com
