NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves

NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves
Rube Goldberg kohvimasin

SĂŒndmuspĂ”hine arhitektuur suurendab kasutatavate ressursside hinnatĂ”husust, kuna neid kaasatakse vaid siis, kui need on vajalikud. On palju vĂ”imalusi, kuidas seda teostada ja mitte luua lisapilveseesid worker-rakenduste vormis. TĂ€na rÀÀgin ma mitte FaaS-ist, vaid veebihook'idest. NĂ€itan Ă”ppepraktikat sĂŒndmuste töötlemiseks objekthoidla veebihook'ide abil.

Paari sĂ”na objekthoidla ja veebihook'ide kohta. Objekthoidlad vĂ”imaldavad salvestada igasuguseid andmeid pilves objektide kujul, mis on kergesti ligipÀÀsetavad S3 vĂ”i muu API kaudu (sĂ”ltuvalt rakendamisest) HTTP/HTTPS kaudu. Veebihook'id (webhooks) on ĂŒldises mĂ”ttes kohandatud tagasikutsed HTTP kaudu. Need kĂ€ivitatakse tavaliselt mingi sĂŒndmuse, nĂ€iteks koodi saatmisega repositooriumisse vĂ”i blogisse postitatud kommentaariga. Kui sĂŒndmus toimub, saadab algne sait HTTP-pĂ€ringu veebihook'ile mÀÀratud URL-ile. Selle tulemuseks on see, et ĂŒhe saidi sĂŒndmused vĂ”ivad esile kutsuda tegevusi teises seotud saidis. Kui algne sait on objekthoidla, esinevad sĂŒndmustena muudatused selle sisus.wiki). Kui algne sait on objektide salvestus, toimuvad ĂŒritused selle sisu muutustes.

Lihtsate juhtumite nÀited, kus automatiseerimist kasutada:

  1. KÔikide objektide kopeerimine teise pilveteenusesse. Koopiad peavad olema loodud "reaalajas" igal failide lisamisel vÔi muutmisel.
  2. Graafikafailide miniatĂŒĂŒride automaatne loomine, vesimĂ€rkide lisamine fotodele ja muud pildimuudatused.
  3. Teadete saatmine uute dokumentide saabumise kohta (nĂ€iteks jaotatud raamatupidamisteenus ĂŒles laadib pilve aruanded ning finantsjĂ€relevalve saab teateid uutest aruannetest, kontrollib ja analĂŒĂŒsib neid).
  4. Veidi keerukamad juhtumid hĂ”lmavad nĂ€iteks pĂ€ringu koostamist Kubernetes'es, mis loob soovitud konteineritega pod'i, edastab sellele ĂŒlesande parameetrid ja sulgeb konteiner pĂ€rast töötlemist.

NĂ€iteks kĂ€sitleme ĂŒlesande varianti 1, kus Mail.ru Cloud Solutions (MCS) objektihoidla muudatused sĂŒnkroniseeritakse AWS objektihoidlas veebihookide abil. Tegelikult koormatud juhul tuleks ette nĂ€ha asĂŒnkroonne töö, registreerides veebihookid jĂ€rjekorda, kuid Ă”ppeĂŒlesande jaoks teeme teostuse ilma selleta.

Töö skeem

Koostööprotokoll on detailselt kirjeldatud MCS S3 veebihookide juhendis. Töö skeemis on jÀrgmised elemendid:

  • Avaldamisteenus, mis asub S3 ladustamise poolel ja saadab HTTP-pĂ€ringuid, kui webnhook aktiveerub.
  • Veebihookide vastuvĂ”tuserver, mis kuulab avaldamisteenuse HTTP pöördumisi ja tĂ€idab vastavaid toiminguid. Serveri vĂ”ib kirjutada mistahes keeles, meie nĂ€ites kirjutame serveri Go keeles.

Veebihookide rakendamise eripÀra S3 API-s on veebihookide vastuvÔtuserveri registreerimine avaldamisteenuses. EelkÔige peab veebihookide vastuvÔtuserver kinnitama tellimuse avaldamisteenuse sÔnumitele (muudes veebihookide rakendustes ei ole tellimuse kinnitamine tavaliselt vajalik).

Seega peab veebihookide vastuvÔtuserver toetama kahte pÔhitoimingut:

  • vastama avaldamisteenuse registreerimise kinnitamise pĂ€ringule,
  • töötlema saabunud sĂŒndmusi.

Veebihookide vastuvÔtuserveri seadistamine

Veebihookide vastuvÔtuserveri kÀivitamiseks on vajalik Linuxi server. KÀesolevas artiklis kasutame nÀitena virtuaalset instantsi, mille seadistame MCS-il.

Paigaldame vajalikud tarkvarad ja kÀivitame veebhookside vastuvÔtu serveri.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install git
Pakettide loendamine... Valmis
SÔltuvuste puu loomine
Oleku teabe lugemine... Valmis
JĂ€rgmised paketid installiti automaatselt ja ei ole enam vajalikud:
 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
Kasutage 'sudo apt autoremove', et need eemaldada.
Soovitavad paketid:
 git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui 
gitk gitweb git-cvs git-mediawiki git-svn
JĂ€rgmised UUS paketid installitakse:
 git
0 uuendatud, 1 uus installitud, 0 eemaldatud ja 46 ei ole uuendatud.
Peab hankima 3915 kB arhiive.
PĂ€rast seda toimingut kasutatakse 32.3 MB lisaruumi.
Hankimine:1 http://MS1.clouds.archive.ubuntu.com/ubuntu bionic-updates/main 
amd64 git amd64 1:2.17.1-1ubuntu0.7 [3915 kB]
Hankimine 3915 kB 1s jooksul (5639 kB/s)
Valitakse varem valimata pakett git.
(Lugeb andmebaasi ... 53932 faili ja katalooge on hetkel installitud.)
Valmistub unpackimiseks .../git_12.17.1-1ubuntu0.7_amd64.deb ...
Unpacking git (1:2.17.1-1ubuntu0.7) ...
Seadistamine git (1:2.17.1-1ubuntu0.7) ...

Kloonime veebhookside vastuvÔtu serveri kausta:

ubuntu@ubuntu-basic-1-2-10gb:~$ git clone
https://github.com/RomanenkoDenys/s3-webhook.git
Kloonimine 's3-webhook' kausta...
remote: Objekti loendamine: 48, valmis.
remote: Objektide lugemine: 100% (48/48), valmis.
remote: Objektide tihendamine: 100% (27/27), valmis.
remote: Kokku 114 (delta 20), uuesti kasutatud 45 (delta 18), pakke uuesti kasutatud 66
Objektide vastuvÔtt: 100% (114/114), 23.77 MiB | 20.25 MiB/s, valmis.
Delta lahendamine: 100% (49/49), valmis.

KĂ€ivitame serveri:

ubuntu@ubuntu-basic-1-2-10gb:~$ cd s3-webhook/
ubunt@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80

Tellimus veebihookide teenusele

Veebihookide vastuvÔtva serveri registreerimist saab teostada API vÔi veebiliidese kaudu. Lihtsuse huvides registreerime lÀbi veebiliidese:

  1. Liigume konteinerite jaotisse haldusliideses.
  2. Siseneme konteinerisse, mille jaoks seadistame veebihookid, ja vajutame hammasratta ikoonile:

NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves

KĂ€ime vahekaart Webhooks ja vajutame Lisa:

NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves
TÀidame vÀljad:

NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves

ID — veebihooki nimi.

SĂŒndmus — milliseid sĂŒndmusi edastada. Oleme valinud edastada kĂ”ik sĂŒndmused, mis toimuvad failidega töötamisel (lisamine ja kustutamine).

URL — veebihookide vastuvĂ”tva serveri aadress.

Filtri eesliide/jesliide — filter, mis vĂ”imaldab genereerida veebihooke ainult objektidele, mille nimed vastavad kindlatele reeglitele. NĂ€iteks, et veebihook aktiveeruks ainult .png laiendiga failide puhul, tuleb Filtri jĂ€relliide sisestada «png».

Praegusel hetkel toetatakse veebihookide vastuvĂ”tva serveriga ĂŒhenduse loomisel ainult porte 80 ja 443.

Vajutame Lisa hook ja nÀeme jÀrgmist:

NĂ€ide sĂŒndmustel pĂ”hinevast rakendusest, mis kasutab webhook'e Mail.ru Cloud Solutions objektide S3-salves
Hook on lisatud.

Veebihookide vastuvÔtva serveri logides kuvatakse hooki registreerimise protsessi toimumine:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80
2020/06/15 12:01:14 [POST] sissetulek HTTP pÀring 
95.163.216.92:42530
2020/06/15 12:01:14 Saadi ajatempli: 2020-06-15T15:01:13+03:00 TeemaArn: 
mcs5259999770|myfiles-ash|s3:ObjectCreated:*,s3:ObjectRemoved:* Token: 
E2itMqAMUVVZc51pUhFWSp13DoxezvRxkUh5P7LEuk1dEe9y URL: 
http://89.208.199.220/webhook
2020/06/15 12:01:14 Loo vastuse allkiri: 
3754ce36636f80dfd606c5254d64ecb2fd8d555c27962b70b4f759f32c76b66d

Registreerimine on lÔpetatud. JÀrgmises jaotises vaatame pÔhjalikumalt veebihookide vastuvÔtuserveri töö pÔhimÔtteid.

Veebihookide vastuvÔtuserveri kirjeldus

Meie nÀites on server kirjutatud Go keeles. Vaatleme selle töö pÔhialuseid.

package main

// Generate hmac_sha256_hex
func HmacSha256hex(message string, secret string) string {
}

// Generate hmac_sha256
func HmacSha256(message string, secret string) string {
}

// Send subscription confirmation
func SubscriptionConfirmation(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Send subscription confirmation
func GotRecords(w http.ResponseWriter, req *http.Request, body []byte) {
}

// Liveness probe
func Ping(w http.ResponseWriter, req *http.Request) {
    // log request
    log.Printf("[%s] incoming HTTP Ping request from %sn", req.Method, req.RemoteAddr)
    fmt.Fprintf(w, "Pongn")
}

//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {
}

func main() {

    // get command line args
    bindPort := flag.Int("port", 80, "number between 1-65535")
    bindAddr := flag.String("address", "", "ip address in dot format")
    flag.StringVar(&actionScript, "script", "", "external script to execute")
    flag.Parse()

    http.HandleFunc("/ping", Ping)
    http.HandleFunc("/webhook", Webhook)

log.Fatal(http.ListenAndServe(*bindAddr+":"+strconv.Itoa(*bindPort), nil))
}

Vaatame peamiseid funktsioone:

  • Ping() — marsruut, mis vastab URL/ping, lihtsaim liveness probe'i teostus.
  • Webhook() — peamine marsruut, URL/veebikuulutuse töötleja:
    • kinnitab registreerimist e-posti teenusesse (ĂŒleminek funktsiooni SubscriptionConfirmation),
    • töötleb saabunud veebikuulutusi (funktsioon GotRecords).
  • Funktsioonid HmacSha256 ja HmacSha256hex on HMAC-SHA256 ja HMAC-SHA256 algoritmide rakendused, mis vĂ€ljastavad 16-kohaliste arvude stringid allkirja arvutamiseks.
  • peamine — pĂ”hifunktsioon, mis töötleb kĂ€surea parameetreid ja registreerib URL-i töötlejad.

KĂ€surea parameetrid, mille server aktsepteerib:

  • -port — port, millel server kuulab.
  • -address — IP-aadress, millega server kuulab.
  • -script — vĂ€line programm, mis kĂ€ivitatakse iga saabunud hargnemise puhul.

Vaadake mÔningaid funktsioone lÀhemalt:

//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)
    }

}

See funktsioon mÀÀrab, mis on saabunud — registreerimise kinnitamise vĂ”i veebiharu. Nagu selgub dokumentatsioonis, registreerimise kinnitamise korral tuleb jĂ€rgmine Json-i struktuur Post-pĂ€ringus:

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":"Olete valinud tellida teema $topic. Tellimuse kinnitamiseks peate vastama arvutatud allkirjaga",
    "TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
    "SignatureVersion":1,
    "Token":«RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA»
}

Sellele pÀringule tuleb vastata:

content-type: application/json

{"signature":«ea3fce4bb15c6de4fec365d36bcebbc34ccddf54616d5ca12e1972f82b6d37af»}

Kus allkiri arvutatakse jÀrgmiselt:

allkiri = hmac_sha256(url, hmac_sha256(TopicArn, 
hmac_sha256(Timestamp, Token)))

Kui saabub veebiharu, siis Post-pÀringu struktuur nÀeb vÀlja selline:

POST  HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation

{ "Records":
    [
        {
            "s3": {
                "object": {
                    "eTag":"aed563ecafb4bcc5654c597a421547b2",
                    "sequencer":1577453615,
                    "key":"some-file-to-bucket",
                    "size":100
                },
            "configurationId":"1",
            "bucket": {
                "name": "bucketA",
                "ownerIdentity": {
                    "principalId":"mcs2883541269"}
                },
                "s3SchemaVersion":"1.0"
            },
            "eventVersion":"1.0",
            "requestParameters":{
                "sourceIPAddress":"185.6.245.156"
            },
            "userIdentity": {
                "principalId":"2407013e-cbc1-415f-9102-16fb9bd6946b"
            },
            "eventName":"s3:ObjectCreated:Put",
            "awsRegion":"ru-msk",
            "eventSource":"aws:s3",
            "responseElements": {
                "x-amz-request-id":"VGJR5rtJ"
            }
        }
    ]
}

SeetÔttu, olenevalt pÀringust tuleb mÔista, kuidas andmeid töödelda. Olen valinud indikaatoriks kirje "Type":"SubscriptionConfirmation", kuna see esineb tellimuse kinnitamise pÀringus ja ei esine veebihookis. LÀhtuvalt selle kirje olemasolust / puudumisest POST-pÀringus, suunatakse tÀiendav programmitöö kas funktsiooni SubscriptionConfirmation, vÔi funktsiooni GotRecords.

Funktsiooni SubscriptionConfirmation ei hakka me pÔhjalikult uurima, see on realiseeritud pÔhimÔtete jÀrgi, mis on vÀlja toodud dokumentatsioonis. Selle funktsiooni lÀhtekoodi saab vaadata projekti git-repositooriumist.

Funktsioon GotRecords töötleb saabuvat pÀringut ja kutsub iga Record objekti jaoks vÀlja vÀlise skripti (mille nimi edastati parameetris -script) jÀrgmiste parameetritega:

  • Ă€mber nimi
  • objekti vĂ”ti
  • toiming:
    • copy — kui algses pĂ€ringus on EventName = ObjectCreated | PutObject | PutObjectCopy
    • delete — kui algses pĂ€ringus on EventName = ObjectRemoved | DeleteObject

Seega, kui tuleb webhook koos Post-pĂ€ringuga, nagu kirjeldatud ĂŒle, ja parameeter -script=script.sh, kutsub skript vĂ€lja jĂ€rgmiselt:

script.sh  bucketA some-file-to-bucket copy

Tuleb mÔista, et see webhookide vastuvÔtuserver ei ole tÀielik tootmislahendus, vaid lihtsustatud nÀide vÔimalikust rakendusest.

Töö nÀide

Teeme pĂ”hialuste failide sĂŒnkroonimise MCS-i varundusĂ€mbritesse AWS-is. PĂ”hiline Ă€mber on nimega myfiles-ash, varu- on myfiles-backup (AWS-i Ă€mbrite konfiguratsioon jÀÀb artikli ulatusest vĂ€lja). vastavalt, kui fail pannakse pĂ”hialusesse, peab selle koopia ilmuma varu, kui see kustutatakse pĂ”hialusest — kustutatakse varu.

Töötame bucket'itega awscli tööriista abil, mis on ĂŒhilduv nii MCS pilvehoidla kui ka AWS pilvehoidlaga.

ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install awscli
Pakettide loendite lugemine... Valmis
SÔltuvuste puu koostamine
Oleku teabe lugemine... Valmis
PÀrast seda toimingut kasutatakse 34.4 MB tÀiendavat kettaruumi.
awscli paketist lahtipakkimine (1.14.44-1ubuntu1) ...
awscli seadistamine (1.14.44-1ubuntu1) ...

Seame sisselogimise S3 MCS API-ks:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile mcs
AWS Access Key ID [None]: hdywEPtuuJTExxxxxxxxxxxxxx
AWS Secret Access Key [None]: hDz3SgxKwXoxxxxxxxxxxxxxxxxxx
Vaikimisi piirkonna nimi [None]:
Vaikimisi vÀljundi formaat [None]:

Seame sisselogimise S3 AWS API-ks:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile aws
AWS Access Key ID [None]: AKIAJXXXXXXXXXXXX
AWS Secret Access Key [None]: dfuerphOLQwu0CreP5Z8l5fuXXXXXXXXXXXXXXXX
Vaikimisi piirkonna nimi [None]:
Vaikimisi vÀljundi formaat [None]:

Kontrollime ligipÀÀse:

AWS-lt:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup

MCS puhul tuleb kĂ€su juurde lisada —endpoint-url:

ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile mcs --endpoint-url 
https://hb.bizmrg.com
2020-02-04 06:38:05 databasebackups-0cdaaa6402d4424e9676c75a720afa85
2020-05-27 10:08:33 myfiles-ash

LigipÀÀs on saadud.

NĂŒĂŒd kirjutame sissetuleva hook'i töötlemise skripti, nimetame selleks s3_backup_mcs_aws.sh

#!/bin/bash
# Require aws cli
# if file added — copy it to backup bucket
# if file removed — remove it from backup bucket
# Variables
ENDPOINT_MCS="https://hb.bizmrg.com"
AWSCLI_MCS=`which aws`" --endpoint-url ${ENDPOINT_MCS} --profile mcs s3"
AWSCLI_AWS=`which aws`" --profile aws s3"
BACKUP_BUCKET="myfiles-backup"

SOURCE_BUCKET="${1}"
SOURCE_FILE="${2}"
ACTION="${3}"

SOURCE="s3://${SOURCE_BUCKET}/${SOURCE_FILE}"
TARGET="s3://${BACKUP_BUCKET}/${SOURCE_FILE}"
TEMP="/tmp/${SOURCE_BUCKET}/${SOURCE_FILE}"

case ${ACTION} in
    "copy")
    ${AWSCLI_MCS} cp "${SOURCE}" "${TEMP}"
    ${AWSCLI_AWS} cp "${TEMP}" "${TARGET}"
    rm ${TEMP}
    ;;

    "delete")
    ${AWSCLI_AWS} rm ${TARGET}
    ;;

    *)
    echo "Usage: ${0} sourcebucket sourcefile copy/delete"
    exit 1
    ;;
esac

KĂ€ivitame serveri:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ sudo ./s3-webhook -port 80 -
skript scripts/s3_backup_mcs_aws.sh

Kontrollime, kuidas see töötab. Aja jooksul MCS veebiliidese kaudu. lisame faili test.txt kotti myfiles-ash. Logides on nÀha, et tehtud oli pÀring veebihooki serverisse:

2020/07/06 09:43:08 [POST] sisenev HTTP pÀring aadressilt 
95.163.216.92:56612
downlaad: s3://myfiles-ash/test.txt ../../../tmp/myfiles-ash/test.txt
ĂŒleslaadimine: ../../../tmp/myfiles-ash/test.txt s3://myfiles-backup/test.txt

Kontrollime AWS-is myfiles-backup kotti sisu:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
2020-07-06 09:43:10       1104 test.txt

NĂŒĂŒd kustutame veebiliidese kaudu faili myfiles-ash kotist.

Serveri logid:

2020/07/06 09:44:46 [POST] sisenev HTTP pÀring aadressilt 
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt

Koti sisu:

ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls 
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$

Fail on kustutatud, probleem lahendatud.

KokkuvÔte ja ToDo

Kogu artiklis kasutatud kood on saadaval minu repositooriumis. Seal on ka skripti nÀidendid ja kÀskluste nÀidised veebihookide registreerimise jaoks.

See kood on vaid nĂ€ide sellest, kuidas kasutada S3 veebihĂ€kke oma tegevuses. Nagu ma alguses mainisin, tuleb sellise serveri tootmises kasutamise korral vĂ€hemalt server kirja panna asĂŒnkroonse töö jaoks: saabuvad veebihĂ€kked registreerida jĂ€rjekorda (RabbitMQ vĂ”i NATS) ja sealt neid töötlusrakendustes töödelda. Vastasel juhul vĂ”ib massiliselt saabuvate veebihĂ€kkide korral tekkida serveri ressursside nappus ĂŒlesannete tĂ€itmiseks. JĂ€rjekordade olemasolu vĂ”imaldab jagada serverit ja töötlusrakendusi, samuti lahendada ĂŒlesannete kordamise kĂŒsimusi tĂ”rgete korral. Samuti on soovitatav muuta logimine detailsemaks ja standardiseeritumaks.

Edu!

Veel lugemist teema kohta:

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster