Mga Background na Gawain sa Faust, Bahagi I: Panimula

Mga Background na Gawain sa Faust, Bahagi I: Panimula

Paano ako nabuhay ng ganito?

Hindi pa matagal na ang nakalipas kailangan kong magtrabaho sa backend ng isang napaka-load na proyekto, kung saan kinakailangan upang ayusin ang regular na pagpapatupad ng isang malaking bilang ng mga gawain sa background na may kumplikadong mga kalkulasyon at mga kahilingan para sa mga serbisyo ng third-party. Asynchronous ang proyekto at bago ako dumating, mayroon itong simpleng mekanismo para sa mga gawain sa paglulunsad ng cron: isang loop na sinusuri ang kasalukuyang oras at paglulunsad ng mga grupo ng mga coroutine sa pamamagitan ng pagtitipon - naging katanggap-tanggap ang diskarteng ito hanggang sa magkaroon ng dose-dosenang at daan-daang mga naturang coroutine , gayunpaman, nang ang kanilang bilang ay lumampas sa dalawang libo, kinailangan kong mag-isip tungkol sa pag-aayos ng isang normal na pila sa gawain kasama ang isang broker, ilang manggagawa, at iba pa.

Una ay nagpasya akong subukan ang Celery, na ginamit ko noon. Dahil sa asynchronous na katangian ng proyekto, sumisid ako sa tanong at nakita isang artikulopati na rin proyekto, nilikha ng may-akda ng artikulo.

Sasabihin ko ito, ang proyekto ay napaka-interesante at medyo matagumpay na gumagana sa iba pang mga aplikasyon ng aming koponan, at ang may-akda mismo ay nagsabi na nagawa niya itong ilunsad sa produksyon sa pamamagitan ng paggamit ng isang asynchronous na pool. Ngunit, sa kasamaang-palad, hindi talaga ito nababagay sa akin, tulad ng nangyari problema sa paglulunsad ng pangkat ng mga gawain (tingnan. grupo). Sa panahon ng pagsulat problema ay sarado na, gayunpaman, ang trabaho ay nangyayari sa loob ng isang buwan. Sa anumang kaso, good luck sa may-akda at sa lahat ng pinakamahusay, dahil mayroon nang mga bagay na gumagana sa lib ... sa pangkalahatan, ang punto ay nasa akin at ang tool ay naging mamasa-masa para sa akin. Bilang karagdagan, ang ilang mga gawain ay may 2-3 mga kahilingan sa http sa iba't ibang mga serbisyo, kaya kahit na sa pag-optimize ng mga gawain, lumikha kami ng 4 na libong TCP na koneksyon, humigit-kumulang bawat 2 oras - hindi masyadong maganda... Gusto kong lumikha ng isang session para sa isang uri ng gawain kapag nagsisimula ng mga manggagawa. Kaunti pa tungkol sa malaking bilang ng mga kahilingan sa pamamagitan ng aiohttp dito.

Sa bagay na ito, nagsimula akong maghanap mga kahalili at natagpuan ito! Ang mga tagalikha ng kintsay, partikular, sa pagkakaintindi ko Tanong ni Solem, ay nilikha Faust, orihinal na para sa proyekto robinhood. Ang Faust ay inspirasyon ng Kafka Streams at nakikipagtulungan sa Kafka bilang isang broker, ginagamit din ang rocksdb upang mag-imbak ng mga resulta mula sa gawain ng mga ahente, at ang pinakamahalagang bagay ay ang library ay asynchronous.

Gayundin, maaari kang tumingin mabilis na paghahambing celery at faust mula sa mga tagalikha ng huli: ang kanilang mga pagkakaiba, mga pagkakaiba sa pagitan ng mga broker, pagpapatupad ng isang elementarya na gawain. Ang lahat ay medyo simple, gayunpaman, ang isang magandang tampok sa faust ay umaakit ng pansin - nai-type na data para sa paghahatid sa paksa.

Anong gagawin natin?

Kaya, sa isang maikling serye ng mga artikulo, ipapakita ko sa iyo kung paano mangolekta ng data mula sa mga gawain sa background gamit ang Faust. Ang pinagmulan para sa aming halimbawang proyekto ay, gaya ng iminumungkahi ng pangalan, alphavantage.co. Ipapakita ko kung paano magsulat ng mga ahente (sink, topics, partitions), kung paano gawin ang regular (cron) execution, ang pinaka-maginhawang faust cli commands (isang wrapper over click), simpleng clustering, at sa dulo ay mag-attach kami ng datadog ( nagtatrabaho sa labas ng kahon) at subukan ang isang bagay upang makita. Upang iimbak ang mga nakolektang data, gagamitin namin ang mongodb at motor para sa koneksyon.

PS Sa paghusga sa kumpiyansa kung saan isinulat ang punto tungkol sa pagsubaybay, sa palagay ko ang mambabasa sa dulo ng huling artikulo ay magiging ganito pa rin:

Mga Background na Gawain sa Faust, Bahagi I: Panimula

Mga kinakailangan sa proyekto

Dahil sa katotohanang nangako na ako, gumawa tayo ng maliit na listahan ng kung ano ang dapat gawin ng serbisyo:

  1. Mag-upload ng mga securities at isang pangkalahatang-ideya ng mga ito (kabilang ang mga kita at pagkalugi, balanse, cash flow - para sa nakaraang taon) - regular
  2. Mag-upload ng makasaysayang data (para sa bawat taon ng pangangalakal, maghanap ng mga matinding halaga ng pagsasara ng presyo ng kalakalan) - regular
  3. Mag-upload ng pinakabagong data ng kalakalan - regular
  4. Mag-upload ng naka-customize na listahan ng mga indicator para sa bawat seguridad - regular

Gaya ng inaasahan, pumili kami ng pangalan para sa proyekto mula sa simula: Horton

Inihahanda namin ang imprastraktura

Ang pamagat ay tiyak na malakas, gayunpaman, ang kailangan mo lang gawin ay magsulat ng isang maliit na config para sa docker-compose na may kafka (at zookeeper - sa isang lalagyan), kafdrop (kung gusto nating tingnan ang mga mensahe sa mga paksa), mongodb. Nakukuha namin [docker-compose.yml](https://github.com/Egnod/horton/blob/562fa5ec14df952cd74760acf76e141707d2ef58/docker-compose.yml) ng sumusunod na anyo:

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

Wala namang kumplikado dito. Dalawang tagapakinig ang idineklara para sa kafka: isa (panloob) para sa paggamit sa loob ng composite network, at ang pangalawa (panlabas) para sa mga kahilingan mula sa labas, kaya ipinasa nila ito sa labas. 2181 — port ng zookeeper. Ang natitira, sa palagay ko, ay malinaw.

Paghahanda ng balangkas ng proyekto

Sa pangunahing bersyon, ang istraktura ng aming proyekto ay dapat magmukhang ganito:

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 *

*Lahat ng napansin ko Hindi pa namin ito ginagalaw, gumagawa lang kami ng mga walang laman na file.**

Gumawa kami ng isang istraktura. Ngayon idagdag natin ang mga kinakailangang dependencies, isulat ang config at kumonekta sa mongodb. Hindi ko ibibigay ang buong teksto ng mga file sa artikulo, upang hindi ito maantala, ngunit magbibigay ako ng mga link sa mga kinakailangang bersyon.

Magsimula tayo sa mga dependency at meta tungkol sa proyekto - pyproject.toml

Susunod, magsisimula kaming mag-install ng mga dependency at lumikha ng isang virtualenv (o maaari kang lumikha ng venv folder mismo at i-activate ang kapaligiran):

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

Ngayon gumawa tayo config.yml - Mga kredensyal at kung saan kakatok. Maaari mong agad na ilagay ang data para sa alphavantage doon. Well, lumipat tayo sa config.py — kunin ang data para sa application mula sa aming config. Oo, inaamin ko, ginamit ko ang aking lib - sitri.

Kapag kumokonekta sa Mongo, ang lahat ay medyo simple. inihayag klase ng kliyente upang kumonekta at batayang klase para sa cruds, para mas madaling gumawa ng mga query sa mga koleksyon.

Anong sunod na mangyayari?

Ang artikulo ay hindi masyadong mahaba, dahil dito ko lang pinag-uusapan ang tungkol sa pagganyak at paghahanda, kaya huwag mo akong sisihin - ipinapangako ko na ang susunod na bahagi ay magkakaroon ng aksyon at mga graphic.

Kaya, sa mismong susunod na bahagi na ito ay:

  1. Sumulat tayo ng isang maliit na kliyente para sa alphavantage sa aiohttp na may mga kahilingan para sa mga endpoint na kailangan natin.
  2. Gumawa tayo ng ahente na mangongolekta ng data sa mga securities at makasaysayang presyo para sa kanila.

Code ng proyekto

Code para sa bahaging ito

Pinagmulan: www.habr.com

Magdagdag ng komento