ProHoster > Blog > Uprava > Primer aplikacije, ki temelji na dogodkih in temelji na webhookih v objektnem shranjevanju S3 rešitve Mail.ru Cloud Solutions
Primer aplikacije, ki temelji na dogodkih in temelji na webhookih v objektnem shranjevanju S3 rešitve Mail.ru Cloud Solutions
Dogodkovno vodena arhitektura povečuje stroškovno učinkovitost uporabljenih virov, saj se le-ti uporabljajo le v trenutku, ko so potrebni. Obstaja veliko možnosti, kako to implementirati in ne ustvariti dodatnih entitet v oblaku kot delovnih aplikacij. In danes ne bom govoril o FaaS, ampak o webhookih. Pokazal bom primer vadnice za obravnavo dogodkov z uporabo spletnih kavljev za shranjevanje objektov.
Nekaj besed o shranjevanju objektov in webhookih. Shramba objektov vam omogoča shranjevanje poljubnih podatkov v oblaku v obliki objektov, dostopnih prek S3 ali drugega API-ja (odvisno od izvedbe) prek HTTP/HTTPS. Webhooki so na splošno prilagojeni povratni klici HTTP. Običajno jih sproži dogodek, na primer potisna koda v repozitorij ali objava komentarja na blogu. Ko pride do dogodka, izvorno mesto pošlje zahtevo HTTP na URL, naveden za webhook. Posledično lahko povzročite, da dogodki na enem mestu sprožijo dejanja na drugem (wiki). V primeru, da je izvorno mesto shramba objektov, dogodki delujejo kot spremembe njegove vsebine.
Primeri preprostih primerov, ko je mogoče uporabiti takšno avtomatizacijo:
Ustvarjanje kopij vseh predmetov v drugi shrambi v oblaku. Kopije je treba ustvariti sproti, ko so datoteke dodane ali spremenjene.
Samodejno ustvarjanje serije sličic grafičnih datotek, dodajanje vodnih žigov fotografijam in druge spremembe slik.
Obveščanje o prispetju novih dokumentov (npr. porazdeljeni računovodski servis nalaga poročila v oblak, finančni nadzor pa prejema obvestila o novih poročilih, jih preverja in analizira).
Nekoliko bolj zapleteni primeri vključujejo na primer generiranje zahteve do Kubernetesa, ki ustvari pod s potrebnimi vsebniki, mu posreduje parametre opravila in po obdelavi vsebnik zruši.
Kot primer bomo naredili različico naloge 1, ko se spremembe v vedru za shranjevanje objektov Mail.ru Cloud Solutions (MCS) sinhronizirajo v shrambi objektov AWS z uporabo spletnih kavljev. V realno naloženem primeru bi moralo biti asinhrono delo zagotovljeno z registracijo webhookov v čakalni vrsti, vendar bomo za nalogo usposabljanja implementacijo izvedli brez tega.
Založniška storitev, ki je na strani shrambe S3 in objavlja zahteve HTTP, ko se sproži webnhook.
Prejemni strežnik Webhook, ki posluša zahteve storitve objavljanja HTTP in izvaja ustrezna dejanja. Strežnik je lahko napisan v katerem koli jeziku; v našem primeru bomo strežnik napisali v Go.
Posebnost implementacije webhookov v S3 API je registracija sprejemnega strežnika webhookov na storitvi objavljanja. Strežnik za sprejem webhooka mora zlasti potrditi naročnino na sporočila storitve objavljanja (pri drugih izvedbah webhooka potrditev naročnine običajno ni potrebna).
V skladu s tem mora sprejemni strežnik webhook podpirati dve glavni operaciji:
odgovorite na zahtevo založniške službe za potrditev registracije,
obdelati dohodne dogodke.
Namestitev sprejemnega strežnika webhook
Če želite zagnati sprejemni strežnik webhook, potrebujete strežnik Linux. V tem članku kot primer uporabljamo virtualni primerek, ki ga namestimo na MCS.
Namestimo potrebno programsko opremo in zaženimo sprejemni strežnik webhook.
ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
bc dns-root-data dnsmasq-base ebtables landscape-common liblxc-common
liblxc1 libuv1 lxcfs lxd lxd-client python3-attr python3-automat
python3-click python3-constantly python3-hyperlink
python3-incremental python3-pam python3-pyasn1-modules
python3-service-identity python3-twisted python3-twisted-bin
python3-zope.interface uidmap xdelta3
Use 'sudo apt autoremove' to remove them.
Suggested packages:
git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui
gitk gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
git
0 upgraded, 1 newly installed, 0 to remove and 46 not upgraded.
Need to get 3915 kB of archives.
After this operation, 32.3 MB of additional disk space will be used.
Get:1 http://MS1.clouds.archive.ubuntu.com/ubuntu bionic-updates/main
amd64 git amd64 1:2.17.1-1ubuntu0.7 [3915 kB]
Fetched 3915 kB in 1s (5639 kB/s)
Selecting previously unselected package git.
(Reading database ... 53932 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.17.1-1ubuntu0.7_amd64.deb ...
Unpacking git (1:2.17.1-1ubuntu0.7) ...
Setting up git (1:2.17.1-1ubuntu0.7) ...
Pojdite do vedra, za katerega bomo konfigurirali webhooke, in kliknite na zobnik:
Pojdite na zavihek Webhooks in kliknite Dodaj:
Izpolnite polja:
ID — ime webhooka.
Dogodek - katere dogodke posredovati. Nastavili smo prenos vseh dogodkov, ki se zgodijo pri delu z datotekami (dodajanje in brisanje).
URL — naslov strežnika za sprejem webhooka.
Predpona/pripona filtra je filter, ki vam omogoča ustvarjanje webhookov samo za predmete, katerih imena ustrezajo določenim pravilom. Na primer, da bi webhook sprožil samo datoteke s pripono .png, v Pripona filtra morate napisati "png".
Trenutno so za dostop do sprejemnega strežnika webhook podprta le vrata 80 in 443.
Kliknimo Dodajte kavelj in videli bomo naslednje:
Kavelj dodan.
Prejemni strežnik webhook v svojih dnevnikih prikazuje napredek postopka registracije kljuka:
Ping() - pot, ki se odziva prek URL-ja/pinga, najpreprostejša izvedba sonde živahnosti.
Webhook() - glavna pot, URL/upravljalnik webhooka:
potrdi registracijo na založniškem servisu (pojdite na funkcijo SubscriptionConfirmation),
obdeluje dohodne webhooke (funkcija Gorecords).
Funkciji HmacSha256 in HmacSha256hex sta implementaciji šifrirnih algoritmov HMAC-SHA256 in HMAC-SHA256 z izhodom kot nizom šestnajstiških števil za izračun podpisa.
main je glavna funkcija, obdeluje parametre ukazne vrstice in registrira obdelovalce URL-jev.
Parametri ukazne vrstice, ki jih sprejme strežnik:
-port so vrata, na katerih bo strežnik poslušal.
-address - IP naslov, ki ga bo strežnik poslušal.
-script je zunanji program, ki se kliče za vsako dohodno kljuko.
Oglejmo si podrobneje nekatere funkcije:
//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {
// Read body
body, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// log request
log.Printf("[%s] incoming HTTP request from %sn", req.Method, req.RemoteAddr)
// check if we got subscription confirmation request
if strings.Contains(string(body),
""Type":"SubscriptionConfirmation"") {
SubscriptionConfirmation(w, req, body)
} else {
GotRecords(w, req, body)
}
}
Ta funkcija določa, ali je prispela zahteva za potrditev registracije ali webhook. Kot sledi iz dokumentacijo, če je registracija potrjena, je v zahtevi za objavo prejeta naslednja struktura Json:
POST http://test.com HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation
content-type: application/json
{
"Timestamp":"2019-12-26T19:29:12+03:00",
"Type":"SubscriptionConfirmation",
"Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
"TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
"SignatureVersion":1,
"Token":«RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA»
}
V skladu s tem morate glede na zahtevo razumeti, kako obdelati podatke. Za indikator sem izbral vnos "Type":"SubscriptionConfirmation", ker je prisoten v zahtevi za potrditev naročnine in ni prisoten v webhooku. Glede na prisotnost/odsotnost tega vnosa v zahtevi POST gre nadaljnje izvajanje programa bodisi na funkcijo SubscriptionConfirmation, ali v funkcijo GotRecords.
Funkcije SubscriptionConfirmation ne bomo podrobno obravnavali; implementirana je v skladu z načeli, določenimi v dokumentacijo. Izvorno kodo za to funkcijo si lahko ogledate na repozitoriji projekta git.
Funkcija GotRecords razčleni dohodno zahtevo in za vsak objekt Record pokliče zunanji skript (katerega ime je bilo posredovano v parametru -script) s parametri:
ime vedra
predmetni ključ
dejanje:
kopija - če je v izvirni zahtevi ImeDogodka = ObjectCreated | PutObject | PutObjectCopy
izbriši - če je v prvotni zahtevi ImeDogodka = Odstranjen Objekt | DeleteObject
Torej, če kljuka prispe z zahtevo za objavo, kot je opisano zgorajin parameter -script=script.sh, potem bo skript poklican na naslednji način:
script.sh bucketA some-file-to-bucket copy
Razumeti je treba, da ta sprejemni strežnik webhook ni popolna proizvodna rešitev, ampak poenostavljen primer možne izvedbe.
Primer dela
Sinhronizirajmo datoteke iz glavnega vedra v MCS v rezervno vedro v AWS. Glavno vedro se imenuje myfiles-ash, rezervno pa se imenuje myfiles-backup (konfiguracija vedra v AWS je izven obsega tega članka). V skladu s tem, ko je datoteka postavljena v glavno vedro, mora biti njena kopija prikazana v rezervnem, in ko je izbrisana iz glavnega, mora biti izbrisana v varnostnem.
Z vedri bomo delali s pomočjo pripomočka awscli, ki je združljiv s shrambo v oblaku MCS in shrambo v oblaku AWS.
ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install awscli
Reading package lists... Done
Building dependency tree
Reading state information... Done
After this operation, 34.4 MB of additional disk space will be used.
Unpacking awscli (1.14.44-1ubuntu1) ...
Setting up awscli (1.14.44-1ubuntu1) ...
Konfigurirajmo dostop do S3 MCS API:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile mcs
AWS Access Key ID [None]: hdywEPtuuJTExxxxxxxxxxxxxx
AWS Secret Access Key [None]: hDz3SgxKwXoxxxxxxxxxxxxxxxxxx
Default region name [None]:
Default output format [None]:
Konfigurirajmo dostop do API-ja AWS S3:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile aws
AWS Access Key ID [None]: AKIAJXXXXXXXXXXXX
AWS Secret Access Key [None]: dfuerphOLQwu0CreP5Z8l5fuXXXXXXXXXXXXXXXX
Default region name [None]:
Default output format [None]:
Preverimo dostope:
Za AWS:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup
Za MCS morate pri zagonu ukaza dodati —endpoint-url:
Poglejmo, kako deluje. Skozi MCS spletni vmesnik dodajte datoteko test.txt v vedro myfiles-ash. Dnevniki konzole kažejo, da je bila zahteva poslana strežniku webhook:
2020/07/06 09:43:08 [POST] incoming HTTP request from
95.163.216.92:56612
download: s3://myfiles-ash/test.txt to ../../../tmp/myfiles-ash/test.txt
upload: ../../../tmp/myfiles-ash/test.txt to
s3://myfiles-backup/test.txt
Zdaj bomo prek spletnega vmesnika izbrisali datoteko iz vedra myfiles-ash.
Dnevniki strežnika:
2020/07/06 09:44:46 [POST] incoming HTTP request from
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt
Vsebina vedra:
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$
Datoteka je izbrisana, težava je rešena.
Zaključek in ToDo
Vsa koda, uporabljena v tem članku, je v mojem skladišču. Obstajajo tudi primeri skript in primeri štetja podpisov za registracijo webhookov.
Ta koda ni nič drugega kot primer, kako lahko uporabite S3 webhooks v svojih dejavnostih. Kot sem rekel na začetku, če nameravate tak strežnik uporabljati v produkciji, morate strežnik vsaj prepisati za asinhrono delo: registrirati dohodne webhooke v čakalno vrsto (RabbitMQ ali NATS) in jih od tam razčleniti in obdelati z delavskimi prijavami. V nasprotnem primeru, ko webhooki prihajajo množično, lahko naletite na pomanjkanje strežniških virov za dokončanje nalog. Prisotnost čakalnih vrst vam omogoča porazdelitev strežnika in delavcev ter reševanje težav s ponavljajočimi se nalogami v primeru napak. Priporočljivo je tudi spremeniti beleženje v podrobnejše in bolj standardizirano.