Fonaj Taskoj pri Faust, Parto I: Enkonduko

Fonaj Taskoj pri Faust, Parto I: Enkonduko

Kiel mi vivis tiel?

Antaŭ nelonge mi devis labori pri la backend de tre ŝarĝita projekto, en kiu estis necese organizi la regulan plenumon de granda nombro da fonaj taskoj kun kompleksaj kalkuloj kaj petoj por triaj servoj. La projekto estas nesinkrona kaj antaŭ ol mi venis, ĝi havis simplan mekanismon por kron-lanĉaj taskoj: buklo kontrolanta la nunan tempon kaj lanĉanta grupojn de korutinoj per gather - ĉi tiu aliro montriĝis akceptebla ĝis ekzistis dekoj kaj centoj da tiaj korutinoj. , tamen, kiam ilia nombro superis du mil, mi devis pensi pri organizado de normala taskovico kun makleristo, pluraj laboristoj, ktp.

Unue mi decidis provi Celery, kiun mi antaŭe uzis. Pro la nesinkrona naturo de la projekto, mi plonĝis en la demandon kaj vidis artikolo, kaj ankaŭ la projekto, kreita de la aŭtoro de la artikolo.

Mi diros ĉi tion, la projekto estas tre interesa kaj funkcias sufiĉe sukcese en aliaj aplikoj de nia teamo, kaj la aŭtoro mem diras, ke li povis efektivigi ĝin en produktadon uzante nesinkronan naĝejon. Sed, bedaŭrinde, ĝi ne vere konvenis al mi, kiel evidentiĝis la problemo kun grupa lanĉo de taskoj (vd. grupo). En la momento de la skribado temo estas jam fermita, tamen la laboro daŭras de monato. Ĉiukaze, bonŝancon al la aŭtoro kaj ĉion bonan, ĉar jam funkcias aferoj sur la lib... ĝenerale, la afero estas en mi kaj la ilo montriĝis por mi malseka. Krome, iuj taskoj havis 2-3 http-petojn al malsamaj servoj, do eĉ dum optimumigo de taskoj, ni kreas 4 mil TCP-konektojn, proksimume ĉiujn 2 horojn - ne tre bone... Mi ŝatus krei sesion por unu speco de tasko kiam oni komencas laboristojn. Iom pli pri la granda nombro da petoj per aiohttp tie.

Tiurilate mi komencis serĉi alternativoj kaj trovis ĝin! La kreintoj de celerio, specife, kiel mi komprenas ĝin Demandu Solemon, estis kreita Faŭsto, origine por la projekto Robin Hood. Faust estas inspirita de Kafka Streams kaj laboras kun Kafka kiel makleristo, rocksdb ankaŭ estas uzata por konservi rezultojn de la laboro de agentoj, kaj la plej grava afero estas, ke la biblioteko estas nesinkrona.

Ankaŭ vi povas rigardi rapida komparo celerio kaj faust de la kreintoj de ĉi-lasta: iliaj diferencoj, diferencoj inter makleristoj, efektivigo de elementa tasko. Ĉio estas sufiĉe simpla, tamen bela trajto en faust altiras atenton - tajpitaj datumoj por transdono al la temo.

Kion ni faru?

Do, en mallonga serio de artikoloj, mi montros al vi kiel kolekti datumojn de fonaj taskoj uzante Faust. La fonto por nia ekzempla projekto estos, kiel la nomo sugestas, alphaavantage.co. Mi montros kiel skribi agentojn (lavujo, temoj, subdiskoj), kiel fari regulan (cron) ekzekuton, la plej oportunajn faust cli-komandojn (envolvaĵo super klako), simplan grupigon, kaj fine ni aldonos datadog ( laborante el la skatolo) kaj provu ion por vidi. Por konservi la kolektitajn datumojn ni uzos mongodb kaj motoro por konekto.

PS Juĝante laŭ la konfido, kun kiu estis skribita la punkto pri monitorado, mi pensas, ke la leganto fine de la lasta artikolo ankoraŭ aspektos tiel:

Fonaj Taskoj pri Faust, Parto I: Enkonduko

Projektaj postuloj

Pro la fakto, ke mi jam promesis, ni faru malgrandan liston de tio, kion la servo devus povi fari:

  1. Alŝutu valorpaperojn kaj superrigardon de ili (inkluzive de profitoj kaj perdoj, bilanco, monfluo - por la lasta jaro) - regule
  2. Alŝutu historiajn datumojn (por ĉiu komerca jaro, trovu ekstremajn valorojn de la ferma prezo de komerco) - regule
  3. Alŝutu plej novajn komercajn datumojn - regule
  4. Alŝutu personecigitan liston de indikiloj por ĉiu sekureco - regule

Kiel atendite, ni elektas nomon por la projekto de nulo: Horton

Ni preparas la infrastrukturon

La titolo certe estas forta, tamen vi bezonas nur skribi malgrandan agordon por docker-compose kun kafka (kaj zookeeper - en unu ujo), kafdrop (se ni volas rigardi mesaĝojn en temoj), mongodb. Ni ricevas [docker-compose.yml](https://github.com/Egnod/horton/blob/562fa5ec14df952cd74760acf76e141707d2ef58/docker-compose.yml) de la sekva formo:

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-service

Ĉi tie estas nenio komplika. Du aŭskultantoj estis deklaritaj por kafka: unu (interna) por uzo ene de la kunmetita reto, kaj la dua (ekstera) por petoj de ekstere, do ili plusendis ĝin eksteren. 2181 - zookeeper haveno. La resto, mi pensas, estas klara.

Preparante la skeleton de la projekto

En la baza versio, la strukturo de nia projekto devus aspekti jene:

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 *

*Ĉion, kion mi notis Ni ankoraŭ ne tuŝas ĝin, ni nur kreas malplenajn dosierojn.**

Ni kreis strukturon. Nun ni aldonu la necesajn dependecojn, skribu la agordon kaj konektu al mongodb. Mi ne provizos la plenan tekston de la dosieroj en la artikolo, por ne prokrasti ĝin, sed mi disponigos ligilojn al la necesaj versioj.

Ni komencu per dependecoj kaj meta pri la projekto - pyproject.toml

Poste, ni komencas instali dependecojn kaj krei virtualenv (aŭ vi povas krei la dosierujon venv mem kaj aktivigi la medion):

pip3 install poetry (если ещё не установлено)
poetry install

Nun ni kreu agordo.yml - Akreditaĵoj kaj kie frapi. Vi povas tuj meti datumojn por alfavantaĝo tie. Nu, ni pluiru al agordo.py — ĉerpi datumojn por la aplikaĵo el nia agordo. Jes, mi konfesas, mi uzis mian lib - sitri.

Kiam vi konektas al Mongo, ĉio estas sufiĉe simpla. anoncita klienta klaso konekti kaj baza klaso por krudaĵoj, por faciligi fari demandojn pri kolektoj.

Kio okazos poste?

La artikolo ne estas tre longa, ĉar ĉi tie mi parolas nur pri instigo kaj preparado, do ne kulpigu min - mi promesas, ke la sekva parto havos agon kaj grafikaĵojn.

Do, en ĉi tiu sama sekva parto ni:

  1. Ni skribu malgrandan klienton por alphaavantage sur aiohttp kun petoj por la finpunktoj, kiujn ni bezonas.
  2. Ni kreu agenton, kiu kolektos datumojn pri valorpaperoj kaj historiaj prezoj por ili.

Projekta kodo

Kodo por ĉi tiu parto

fonto: www.habr.com

Aldoni komenton