Ni akceptas 10 000 eventojn en Yandex.Cloud. Parto 1

Saluton al ĉiuj, amikoj!

* Ĉi tiu artikolo baziĝas sur la malferma laborrenkontiĝo REBRAIN & Yandex.Cloud, se vi preferas spekti la videon, vi povas trovi ĝin ĉe ĉi tiu ligilo - https://youtu.be/cZLezUm0ekE

Ni lastatempe havis la ŝancon provi Yandex.Cloud vive. Ĉar ni volis sondi longe kaj malfacile, ni tuj forlasis la ideon lanĉi simplan Wordpress-blogon kun nuba bazo - ĝi estis tro enuiga. Post iom da pripensado, ni decidis disfaldi ion similan al arkitekturo de produktada servo por ricevi kaj analizi eventojn en preskaŭ realtempa reĝimo.

Mi estas absolute certa, ke la granda plimulto de interretaj (kaj ne nur) entreprenoj iel kolektas monton da informoj pri siaj uzantoj kaj iliaj agoj. Minimume, tio estas necesa por fari iujn decidojn - ekzemple, se vi administras interretan ludon, vi povas rigardi la statistikojn, je kiu nivelo uzantoj plej ofte blokiĝas kaj forigi vian ludilon. Aŭ kial uzantoj forlasas vian retejon sen aĉeti ion ajn (saluton, Yandex.Metrica).

Do, nia rakonto: kiel ni skribis aplikaĵon en golang, testis kafka vs rabbitmq vs yqs, skribis datumojn fluantajn en Clickhouse-areo kaj bildigis la datumojn uzante yandex-datenojn. Nature, ĉio ĉi estis spicita per infrastrukturaj ĝojoj en la formo de docker, terraform, gitlab ci kaj, kompreneble, prometheus. Ni iru!

Mi ŝatus tuj fari rezervon, ke ni ne povos agordi ĉion en unu kunsido - por tio ni bezonos plurajn artikolojn en la serio. Iom pri la strukturo:

Parto 1 (vi legas ĝin). Ni decidos pri la specifoj kaj arkitekturo de la solvo, kaj ankaŭ skribos aplikaĵon en golang.
Parto 2. Ni liberigas nian aplikaĵon en produktadon, igas ĝin skalebla kaj testas la ŝarĝon.
Parto 3. Ni provu eltrovi kial ni devas konservi mesaĝojn en bufro kaj ne en dosieroj, kaj ankaŭ komparu kafka, rabbitmq kaj yandex queuoservo.
Parto 4 Ni deplojos Clickhouse-grupon, skribos streaming-servon por translokigi datumojn de la bufro tie, kaj starigos bildigon en datumlenso.
Parto 5 Ni alportu la tutan infrastrukturon en ĝustan formon - agordu ci/cd per gitlab ci, konektu monitoradon kaj servan malkovron per prometeo kaj konsulo.

TK

Unue, ni formulu la referencojn - kion ĝuste ni volas ricevi kiel rezulto.

  1. Ni volas havi finpunkton kiel events.kis.im (kis.im estas la testa domajno, kiun ni uzos tra ĉiuj artikoloj), kiu devus ricevi eventojn uzante HTTPS.
  2. Eventoj estas simpla json kiel: {“event”: “view”, “os”: “linux”, “browser”: “chrome”}. En la fina etapo ni aldonos iom pli da kampoj, sed ĉi tio ne ludos grandan rolon. Se vi deziras, vi povas ŝanĝi al protobuf.
  3. La servo devas povi prilabori 10 eventojn je sekundo.
  4. Devus ebli skali horizontale per simple aldonado de novaj okazoj al nia solvo. Kaj estos bone, se ni povas movi la antaŭan parton al malsamaj geolokigoj por redukti latencian por klientpetoj.
  5. Kulpo toleremo. La solvo devas esti sufiĉe stabila kaj povi travivi la falon de iuj partoj (ĝis certa nombro, kompreneble).

arkitekturo

Ĝenerale, por ĉi tiu tipo de tasko, klasikaj arkitekturoj estas delonge inventitaj, kiuj permesas efikan skalon. La figuro montras ekzemplon de nia solvo.

Ni akceptas 10 000 eventojn en Yandex.Cloud. Parto 1

Do kion ni havas:

1. Maldekstre estas niaj aparatoj, kiuj generas diversajn eventojn, ĉu ludantoj kompletigantaj nivelon en ludilo sur inteligenta telefono aŭ kreantaj mendon en reta vendejo per regula retumilo. Okazaĵo, kiel specifita en la specifo, estas simpla json kiu estas sendita al nia finpunkto - events.kis.im.

2. La unuaj du serviloj estas simplaj ekvilibristoj, iliaj ĉefaj taskoj estas:

  • Estu konstante disponebla. Por fari tion, vi povas uzi, ekzemple, keepalived, kiu ŝanĝos la virtualan IP inter nodoj en kazo de problemoj.
  • Terminu TLS. Jes, ni ĉesigos TLS sur ili. Unue, por ke nia solvo konformas al la teknikaj specifoj, kaj due, por malpezigi la ŝarĝon establi ĉifritan konekton de niaj backend-serviloj.
  • Ekvilibro alvenantaj petoj al disponeblaj backend serviloj. La ŝlosilvorto ĉi tie estas alirebla. Surbaze de ĉi tio, ni ekkomprenas, ke ŝarĝbalanciloj devas povi monitori niajn servilojn per aplikaĵoj kaj ĉesi ekvilibrigi trafikon al malsukcesaj nodoj.

3. Post la ekvilibristoj, ni havas aplikaĵoservilojn kurantajn sufiĉe simplan aplikaĵon. Ĝi devus povi akcepti envenantajn petojn per HTTP, validigi la senditan json kaj meti la datumojn en bufron.

4. La diagramo montras kafkan kiel bufron, kvankam, kompreneble, aliaj similaj servoj povas esti uzataj sur ĉi tiu nivelo. Ni komparos Kafka, rabbitmq kaj yqs en la tria artikolo.

5. La antaŭlasta punkto de nia arkitekturo estas Clickhouse - kolumna datumbazo, kiu permesas vin stoki kaj prilabori grandegan kvanton da datumoj. Je ĉi tiu nivelo, ni devas transdoni datumojn de la bufro al la stokada sistemo mem (pli pri tio en artikolo 4).

Ĉi tiu dezajno permesas al ni grimpi ĉiun tavolon sendepende horizontale. Backend-serviloj ne povas elteni - ni aldonu ankoraŭ unu aferon - finfine ili estas sennaciaj aplikoj, kaj tial tio povas esti farita eĉ aŭtomate. La Kafka-stila bufro ne funkcias—ni aldonu pli da serviloj kaj transdonu kelkajn el la sekcioj de nia temo al ili. Clickhouse ne povas trakti ĝin - estas neeble :) Fakte, ni ankaŭ konektos la servilojn kaj disrompos la datumojn.

Cetere, se vi volas efektivigi la laŭvolan parton de niaj teknikaj specifoj kaj skalo en malsamaj geolokigoj, tiam estas nenio pli simpla:

Ni akceptas 10 000 eventojn en Yandex.Cloud. Parto 1

En ĉiu geolokigo ni deplojas ŝarĝbalancilon kun aplikaĵo kaj kafka. Ĝenerale sufiĉas 2 aplikaĵaj serviloj, 3 kafkaj nodoj kaj nubo-balancilo, ekzemple cloudflare, kiuj kontrolos la haveblecon de aplikaj nodoj kaj ekvilibros petojn per geolokigo bazita sur la fonta IP-adreso de la kliento. Tiel, datumoj senditaj de usona kliento surteriĝos sur usonajn servilojn. Kaj datumoj de Afriko estas en afrika.

Tiam ĉio estas sufiĉe simpla - ni uzas la spegulan ilon de la aro Kafka kaj kopias ĉiujn datumojn de ĉiuj lokoj al nia centra datumcentro situanta en Rusio. Interne, ni analizas la datumojn kaj registras ĝin en Clickhouse por posta bildigo.

Do, ni ordigis la arkitekturon - ni komencu skui Yandex.Cloud!

Skribante aplikaĵon

Antaŭ la Nubo, vi ankoraŭ devas esti iom pacienca kaj skribi sufiĉe simplan servon por prilabori venontajn eventojn. Ni uzos golango ĉar ĝi pruvis sin tre bone kiel lingvo por verki retajn aplikojn.

Post unu horo (eble kelkaj horoj), ni ricevas ion tian: https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/main.go.

Kiuj estas la ĉefaj punktoj, kiujn mi ŝatus noti ĉi tie:

1. Komencante la aplikaĵon, vi povas specifi du flagojn. Unu respondecas pri la haveno, sur kiu ni aŭskultos alvenantajn http-petojn (-addr). La dua estas por la kafka servila adreso, kie ni registros niajn eventojn (-kafka):

addr     = flag.String("addr", ":8080", "TCP address to listen to")
kafka    = flag.String("kafka", "127.0.0.1:9092", "Kafka endpoints”)

2. La aplikaĵo uzas la sarama bibliotekon ([] github.com/Shopify/sarama) por sendi mesaĝojn al la kafka areto. Ni tuj fiksas la agordojn celantajn maksimuman pretigan rapidon:

config := sarama.NewConfig()
config.Producer.RequiredAcks = sarama.WaitForLocal
config.Producer.Compression = sarama.CompressionSnappy
config.Producer.Return.Successes = true

3. Nia aplikaĵo ankaŭ havas enkonstruitan prometheus-klienton, kiu kolektas diversajn metrikojn, kiel:

  • nombro da petoj al nia aplikaĵo;
  • nombro da eraroj dum plenumado de la peto (neeble legi afiŝopeton, rompita json, neebla skribi al Kafka);
  • prilaborado por unu peto de la kliento, inkluzive de la tempo por skribi mesaĝon al Kafka.

4. Tri finpunktoj, kiujn nia aplikaĵo prilaboras:

  • /status - simple revenu bone por montri ke ni vivas. Kvankam vi povas aldoni kelkajn ĉekojn, kiel la havebleco de la Kafka-grupo.
  • /metrics - laŭ ĉi tiu url, la prometheus-kliento resendos la metrikojn, kiujn ĝi kolektis.
  • /post estas la ĉefa finpunkto kie POST-petoj kun json ene estos senditaj. Nia aplikaĵo kontrolas la json por valideco kaj se ĉio estas en ordo, ĝi skribas la datumojn al la Kafka-grupo.

Mi faros rezervon, ke la kodo ne estas perfekta - ĝi povas (kaj devas!) esti kompletigita. Ekzemple, vi povas ĉesi uzi la enkonstruitan reton/http kaj ŝanĝi al la pli rapida rapidahttp. Aŭ vi povas akiri pretigtempon kaj cpu-rimedojn movante la json-valideckontrolon al pli posta etapo - kiam la datumoj estas transdonitaj de la bufro al la klakdomo.

Krom la disvolva flanko de la afero, ni tuj pensis pri nia estonta infrastrukturo kaj decidis deploji nian aplikaĵon per docker. La fina Dockerfile por konstrui la aplikaĵon estas https://github.com/RebrainMe/yandex-cloud-events/blob/master/app/Dockerfile. Ĝenerale, ĝi estas sufiĉe simpla, la sola punkto, pri kiu mi ŝatus atenti, estas la plurŝtupa muntado, kiu ebligas al ni redukti la finan bildon de nia ujo.

Unuaj paŝoj en la nubo

Unue, registriĝu cloud.yandex.ru. Post plenigi ĉiujn necesajn kampojn, ni estos kreitaj konto kaj donita subvencion por certa kvanto de mono, kiu povas esti uzata por testi nubajn servojn. Se vi volas ripeti ĉiujn paŝojn de nia artikolo, ĉi tiu subvencio devus sufiĉi por vi.

Post registriĝo, aparta nubo kaj defaŭlta dosierujo estos kreitaj por vi, en kiuj vi povas komenci krei nubajn rimedojn. Ĝenerale, en Yandex.Cloud, la rilato de rimedoj aspektas jene:

Ni akceptas 10 000 eventojn en Yandex.Cloud. Parto 1

Vi povas krei plurajn nubojn por unu konto. Kaj ene de la nubo, faru malsamajn adresarojn por malsamaj firmaaj projektoj. Vi povas legi pli pri tio en la dokumentado - https://cloud.yandex.ru/docs/resource-manager/concepts/resources-hierarchy. Cetere, mi ofte aludos al ĝi sube en la teksto. Kiam mi starigis la tutan infrastrukturon de nulo, la dokumentaro helpis min pli ol unufoje, do mi konsilas vin studi ĝin.

Por administri la nubon, vi povas uzi kaj la retinterfacon kaj la konzola ilo - yc. Instalado estas farita per unu komando (por Linukso kaj Mac Os):

curl https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash

Se via interna sekureca specialisto furiozas pri rulado de skriptoj de la Interreto, tiam, unue, vi povas malfermi la skripton kaj legi ĝin, kaj due, ni rulas ĝin sub nia uzanto - sen radikrajtoj.

Se vi volas instali klienton por Vindozo, vi povas uzi la instrukciojn tie kaj poste ekzekuti yc initpor plene personecigi ĝin:

vozerov@mba:~ $ yc init
Welcome! This command will take you through the configuration process.
Please go to https://oauth.yandex.ru/authorize?response_type=token&client_id= in order to obtain OAuth token.

Please enter OAuth token:
Please select cloud to use:
 [1] cloud-b1gv67ihgfu3bp (id = b1gv67ihgfu3bpt24o0q)
 [2] fevlake-cloud (id = b1g6bvup3toribomnh30)
Please enter your numeric choice: 2
Your current cloud has been set to 'fevlake-cloud' (id = b1g6bvup3toribomnh30).
Please choose folder to use:
 [1] default (id = b1g5r6h11knotfr8vjp7)
 [2] Create a new folder
Please enter your numeric choice: 1
Your current folder has been set to 'default' (id = b1g5r6h11knotfr8vjp7).
Do you want to configure a default Compute zone? [Y/n]
Which zone do you want to use as a profile default?
 [1] ru-central1-a
 [2] ru-central1-b
 [3] ru-central1-c
 [4] Don't set default zone
Please enter your numeric choice: 1
Your profile default Compute zone has been set to 'ru-central1-a'.
vozerov@mba:~ $

Principe, la procezo estas simpla - unue vi devas akiri aŭth-ĵetonon por administri la nubon, elektu la nubon kaj la dosierujon, kiun vi uzos.

Se vi havas plurajn kontojn aŭ dosierujojn ene de la sama nubo, vi povas krei pliajn profilojn kun apartaj agordoj per yc agorda profilo krei kaj ŝanĝi inter ili.

Krom ĉi-supraj metodoj, la teamo Yandex.Cloud skribis tre bonan kromaĵo por terraform por administri nubajn rimedojn. Miaflanke, mi preparis git-deponejon, kie mi priskribis ĉiujn rimedojn, kiuj estos kreitaj kiel parto de la artikolo - https://github.com/rebrainme/yandex-cloud-events/. Ni interesiĝas pri la majstra branĉo, ni klonu ĝin loke:


vozerov@mba:~ $ git clone https://github.com/rebrainme/yandex-cloud-events/ events
Cloning into 'events'...
remote: Enumerating objects: 100, done.
remote: Counting objects: 100% (100/100), done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 100 (delta 37), reused 89 (delta 26), pack-reused 0
Receiving objects: 100% (100/100), 25.65 KiB | 168.00 KiB/s, done.
Resolving deltas: 100% (37/37), done.
vozerov@mba:~ $ cd events/terraform/

Ĉiuj ĉefaj variabloj uzataj en terraform estas skribitaj en la dosiero main.tf. Por komenci, kreu private.auto.tfvars-dosieron en la terraform-dosierujo kun jena enhavo:

# Yandex Cloud Oauth token
yc_token = ""
# Yandex Cloud ID
yc_cloud_id = ""
# Yandex Cloud folder ID
yc_folder_id = ""
# Default Yandex Cloud Region
yc_region = "ru-central1-a"
# Cloudflare email
cf_email = ""
# Cloudflare token
cf_token = ""
# Cloudflare zone id
cf_zone_id = ""

Ĉiuj variabloj povas esti prenitaj el la yc agorda listo, ĉar ni jam agordis la konzola ilo. Mi konsilas vin tuj aldoni private.auto.tfvars al .gitignore, por ne hazarde publikigi privatajn datumojn.

En private.auto.tfvars ni ankaŭ specifis datumojn de Cloudflare - por krei DNS-rekordojn kaj prokurigi la ĉefan domajnon events.kis.im al niaj serviloj. Se vi ne volas uzi cloudflare, tiam forigu la inicialigon de la cloudflare-provizanto en main.tf kaj la dns.tf dosieron, kiu respondecas pri kreado de la necesaj dns-rekordoj.

En nia laboro ni kombinos ĉiujn tri metodojn - la retinterfaco, la konzola ilo kaj terraform.

Virtualaj retoj

Por esti honesta, vi povus preterlasi ĉi tiun paŝon, ĉar kiam vi kreos novan nubon, vi aŭtomate havos apartan reton kaj 3 subretojn kreitajn - unu por ĉiu havebleca zono. Sed ni tamen ŝatus fari apartan reton por nia projekto kun propra adresado. La ĝenerala diagramo pri kiel la reto funkcias en Yandex.Cloud estas montrita en la suba figuro (honeste prenita de https://cloud.yandex.ru/docs/vpc/concepts/)

Ni akceptas 10 000 eventojn en Yandex.Cloud. Parto 1

Do, vi kreas komunan reton ene de kiu rimedoj povas komuniki unu kun la alia. Por ĉiu havebleczono, subreto estas kreita kun sia propra adresado kaj konektita al la ĝenerala reto. Kiel rezulto, ĉiuj nubaj rimedoj en ĝi povas komuniki, eĉ se ili estas en malsamaj haveblecaj zonoj. Rimedoj ligitaj al malsamaj nubaj retoj povas vidi unu la alian nur per eksteraj adresoj. Cetere, kiel ĉi tiu magio funkcias interne, estis bone priskribita sur Habré.

Retkreado estas priskribita en la dosiero network.tf el la deponejo. Tie ni kreas unu komunan privatan reton internan kaj ligas al ĝi tri subretojn en malsamaj haveblecaj zonoj - interna-a (172.16.1.0/24), interna-b (172.16.2.0/24), interna-c (172.16.3.0/24). ).

Komencu terraform kaj kreu retojn:

vozerov@mba:~/events/terraform (master) $ terraform init
... skipped ..

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_vpc_subnet.internal-a -target yandex_vpc_subnet.internal-b -target yandex_vpc_subnet.internal-c

... skipped ...

Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

yandex_vpc_network.internal: Creating...
yandex_vpc_network.internal: Creation complete after 3s [id=enp2g2rhile7gbqlbrkr]
yandex_vpc_subnet.internal-a: Creating...
yandex_vpc_subnet.internal-b: Creating...
yandex_vpc_subnet.internal-c: Creating...
yandex_vpc_subnet.internal-a: Creation complete after 6s [id=e9b1dad6mgoj2v4funog]
yandex_vpc_subnet.internal-b: Creation complete after 7s [id=e2liv5i4amu52p64ac9p]
yandex_vpc_subnet.internal-c: Still creating... [10s elapsed]
yandex_vpc_subnet.internal-c: Creation complete after 10s [id=b0c2qhsj2vranoc9vhcq]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Bonege! Ni kreis nian reton kaj nun pretas krei niajn internajn servojn.

Krei virtualajn maŝinojn

Por testi la aplikaĵon, ni nur bezonos krei du virtualajn maŝinojn - ni bezonos la unuan por konstrui kaj ruli la aplikaĵon, la duan por ruli kafka, kiun ni uzos por stoki envenantajn mesaĝojn. Kaj ni kreos alian maŝinon, kie ni agordos prometheus por kontroli la aplikaĵon.

La virtualaj maŝinoj estos agorditaj per ansible, do antaŭ ol komenci terraform, certigu, ke vi havas unu el la plej novaj versioj de ansible. Kaj instalu la necesajn rolojn kun ansible galaksio:

vozerov@mba:~/events/terraform (master) $ cd ../ansible/
vozerov@mba:~/events/ansible (master) $ ansible-galaxy install -r requirements.yml
- cloudalchemy-prometheus (master) is already installed, skipping.
- cloudalchemy-grafana (master) is already installed, skipping.
- sansible.kafka (master) is already installed, skipping.
- sansible.zookeeper (master) is already installed, skipping.
- geerlingguy.docker (master) is already installed, skipping.
vozerov@mba:~/events/ansible (master) $

Ene de la ansible dosierujo estas ekzemplo .ansible.cfg agorda dosiero kiun mi uzas. Ĝi povus esti utila.

Antaŭ krei virtualajn maŝinojn, certigu, ke vi havas ssh-agent funkciantan kaj ssh-ŝlosilon aldonita, alie terraform ne povos konektiĝi al la kreitaj maŝinoj. Mi, kompreneble, trovis cimon en os x: https://github.com/ansible/ansible/issues/32499#issuecomment-341578864. Por eviti ke tio okazu denove, aldonu malgrandan variablon al env antaŭ lanĉi Terraform:

vozerov@mba:~/events/terraform (master) $ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

En la dosierujo kun terraform ni kreas la necesajn rimedojn:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_compute_instance.build -target yandex_compute_instance.monitoring -target yandex_compute_instance.kafka
yandex_vpc_network.internal: Refreshing state... [id=enp2g2rhile7gbqlbrkr]
data.yandex_compute_image.ubuntu_image: Refreshing state...
yandex_vpc_subnet.internal-a: Refreshing state... [id=e9b1dad6mgoj2v4funog]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

... skipped ...

Plan: 3 to add, 0 to change, 0 to destroy.

... skipped ...

Se ĉio finiĝis sukcese (kaj devus esti), tiam ni havos tri virtualajn maŝinojn:

  1. build - maŝino por testi kaj konstrui aplikaĵon. Docker estis instalita aŭtomate de Ansible.
  2. monitoring - monitoring machine - prometheus & grafana instalita sur ĝi. Ensalutu / pasvorta normo: admin / admin
  3. kafka estas malgranda maŝino kun kafka instalita, alirebla sur haveno 9092.

Ni certigu, ke ili ĉiuj estas en loko:

vozerov@mba:~/events (master) $ yc compute instance list
+----------------------+------------+---------------+---------+---------------+-------------+
|          ID          |    NAME    |    ZONE ID    | STATUS  |  EXTERNAL IP  | INTERNAL IP |
+----------------------+------------+---------------+---------+---------------+-------------+
| fhm081u8bkbqf1pa5kgj | monitoring | ru-central1-a | RUNNING | 84.201.159.71 | 172.16.1.35 |
| fhmf37k03oobgu9jmd7p | kafka      | ru-central1-a | RUNNING | 84.201.173.41 | 172.16.1.31 |
| fhmt9pl1i8sf7ga6flgp | build      | ru-central1-a | RUNNING | 84.201.132.3  | 172.16.1.26 |
+----------------------+------------+---------------+---------+---------------+-------------+

La rimedoj estas en loko, kaj de ĉi tie ni povas akiri iliajn IP-adresojn. Ĉie en kio sekvas mi uzos IP-adresojn por konekti per ssh kaj testi la aplikaĵon. Se vi havas cloudflare-konton konektita al terraform, bonvolu uzi ĵus kreitajn DNS-nomojn.
Cetere, dum kreado de virtuala maŝino, interna IP kaj interna DNS-nomo estas donitaj, do vi povas aliri servilojn ene de la reto laŭnome:

ubuntu@build:~$ ping kafka.ru-central1.internal
PING kafka.ru-central1.internal (172.16.1.31) 56(84) bytes of data.
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=1 ttl=63 time=1.23 ms
64 bytes from kafka.ru-central1.internal (172.16.1.31): icmp_seq=2 ttl=63 time=0.625 ms
^C
--- kafka.ru-central1.internal ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.625/0.931/1.238/0.308 ms

Ĉi tio estos utila por ni indiki al la aplikaĵo la finpunkton per kafk.

Kunvenado de la aplikaĵo

Bonege, ekzistas serviloj, ekzistas aplikaĵo - restas nur kunmeti ĝin kaj publikigi ĝin. Por la konstruo ni uzos la kutiman docker-konstruaĵon, sed kiel bildstokadon ni uzos servon de Yandex - container registry. Sed unue aferojn.

Ni kopias la aplikaĵon al la konstrumaŝino, ensalutu per ssh kaj kunmetas la bildon:

vozerov@mba:~/events/terraform (master) $ cd ..
vozerov@mba:~/events (master) $ rsync -av app/ [email protected]:app/

... skipped ...

sent 3849 bytes  received 70 bytes  7838.00 bytes/sec
total size is 3644  speedup is 0.93

vozerov@mba:~/events (master) $ ssh 84.201.132.3 -l ubuntu
ubuntu@build:~$ cd app
ubuntu@build:~/app$ sudo docker build -t app .
Sending build context to Docker daemon  6.144kB
Step 1/9 : FROM golang:latest AS build
... skipped ...

Successfully built 9760afd8ef65
Successfully tagged app:latest

Duono de la batalo estas farita - nun ni povas kontroli la funkciojn de nia aplikaĵo lanĉante ĝin kaj sendante ĝin al kafka:

ubuntu@build:~/app$ sudo docker run --name app -d -p 8080:8080 app /app/app -kafka=kafka.ru-central1.internal:9092</code>

С локальной машинки можно отправить тестовый event и посмотреть на ответ:

<code>vozerov@mba:~/events (master) $ curl -D - -s -X POST -d '{"key1":"data1"}' http://84.201.132.3:8080/post
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 13 Apr 2020 13:53:54 GMT
Content-Length: 41

{"status":"ok","partition":0,"Offset":0}
vozerov@mba:~/events (master) $

La aplikaĵo respondis kun sukceso de la registrado kaj indikante la id de la subdisko kaj ofseto en kiu la mesaĝo estis inkluzivita. Restas nur krei registron en Yandex.Cloud kaj alŝuti nian bildon tie (kiel fari tion per tri linioj estas priskribita en la dosiero registry.tf). Krei stokadon:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_container_registry.events

... skipped ...

Plan: 1 to add, 0 to change, 0 to destroy.

... skipped ...

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Estas pluraj manieroj aŭtentikigi en la ujo-registro - uzante aŭuth-ĵetonon, iam-ĵetonon aŭ servokontoŝlosilon. Pliaj detaloj pri ĉi tiuj metodoj troveblas en la dokumentado. https://cloud.yandex.ru/docs/container-registry/operations/authentication. Ni uzos la servokontoŝlosilon, do ni kreas konton:

vozerov@mba:~/events/terraform (master) $ terraform apply -target yandex_iam_service_account.docker -target yandex_resourcemanager_folder_iam_binding.puller -target yandex_resourcemanager_folder_iam_binding.pusher

... skipped ...

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Nun restas nur fari ŝlosilon por ĝi:

vozerov@mba:~/events/terraform (master) $ yc iam key create --service-account-name docker -o key.json
id: ajej8a06kdfbehbrh91p
service_account_id: ajep6d38k895srp9osij
created_at: "2020-04-13T14:00:30Z"
key_algorithm: RSA_2048

Ni ricevas informojn pri la identigilo de nia stokado, transdonas la ŝlosilon kaj ensalutu:

vozerov@mba:~/events/terraform (master) $ scp key.json [email protected]:
key.json                                                                                                                    100% 2392   215.1KB/s   00:00

vozerov@mba:~/events/terraform (master) $ ssh 84.201.132.3 -l ubuntu

ubuntu@build:~$ cat key.json | sudo docker login --username json_key --password-stdin cr.yandex
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ubuntu@build:~$

Por alŝuti la bildon al la registro, ni bezonas la ujan registran ID, ni prenas ĝin de la yc-utilo:

vozerov@mba:~ $ yc container registry get events
id: crpdgj6c9umdhgaqjfmm
folder_id:
name: events
status: ACTIVE
created_at: "2020-04-13T13:56:41.914Z"

Post tio, ni etikedas nian bildon kun nova nomo kaj alŝutas:

ubuntu@build:~$ sudo docker tag app cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
ubuntu@build:~$ sudo docker push cr.yandex/crpdgj6c9umdhgaqjfmm/events:v1
The push refers to repository [cr.yandex/crpdgj6c9umdhgaqjfmm/events]
8c286e154c6e: Pushed
477c318b05cb: Pushed
beee9f30bc1f: Pushed
v1: digest: sha256:1dd5aaa9dbdde2f60d833be0bed1c352724be3ea3158bcac3cdee41d47c5e380 size: 946

Ni povas kontroli, ke la bildo ŝarĝis sukcese:

vozerov@mba:~/events/terraform (master) $ yc container repository list
+----------------------+-----------------------------+
|          ID          |            NAME             |
+----------------------+-----------------------------+
| crpe8mqtrgmuq07accvn | crpdgj6c9umdhgaqjfmm/events |
+----------------------+-----------------------------+

Cetere, se vi instalas la ilon yc sur Linuksa maŝino, vi povas uzi la komandon

yc container registry configure-docker

por agordi docker.

konkludo

Ni faris multe da malfacila laboro kaj kiel rezulto:

  1. Ni elpensis la arkitekturon de nia estonta servo.
  2. Ni skribis aplikaĵon en golang, kiu efektivigas nian komercan logikon.
  3. Ni kolektis ĝin kaj verŝis ĝin en privatan ujan registron.

En la sekva parto, ni daŭrigos la interesajn aferojn - ni liberigos nian aplikaĵon en produktadon kaj fine lanĉos la ŝarĝon sur ĝi. Ne ŝanĝu!

Ĉi tiu materialo estas en la videoregistraĵo de la malferma laborrenkontiĝo REBRAIN & Yandex.Cloud: Ni akceptas 10 petojn por sekundo sur Yandex Cloud - https://youtu.be/cZLezUm0ekE

Se vi interesiĝas ĉeesti tiajn eventojn interrete kaj demandi demandojn en reala tempo, konektu al DevOps per kanalo REBRAIN.

Ni ŝatus diri specialan dankon al Yandex.Cloud pro la ŝanco gastigi tian eventon. Ligu al ili - https://cloud.yandex.ru/prices

Se vi bezonas translokiĝi al la nubo aŭ havas demandojn pri via infrastrukturo, Bonvolu sendi peton.

PS Ni havas 2 senpagajn reviziojn monate, eble via projekto estos unu el ili.

fonto: www.habr.com

Aldoni komenton