Olay odaklı mimari, kullanılan kaynakların yalnızca ihtiyaç duyulduğu anda kullanılması nedeniyle maliyet verimliliğini artırır. Bunun nasıl uygulanacağına ve çalışan uygulamalar olarak ek bulut varlıkları oluşturulmamasına ilişkin birçok seçenek vardır. Ve bugün FaaS'tan değil web kancalarından bahsedeceğim. Nesne depolama web kancalarını kullanarak olayların işlenmesine ilişkin öğretici bir örnek göstereceğim.
Nesne depolama ve web kancaları hakkında birkaç söz. Nesne depolama, S3 veya başka bir API (uygulamaya bağlı olarak) aracılığıyla HTTP/HTTPS yoluyla erişilebilen nesneler biçiminde bulutta herhangi bir veriyi saklamanıza olanak tanır. Web kancaları genellikle özel HTTP geri aramalarıdır. Bunlar genellikle kodun bir depoya gönderilmesi veya bir blogda yayınlanan yorum gibi bir olay tarafından tetiklenir. Bir olay meydana geldiğinde, kaynak site, web kancası için belirtilen URL'ye bir HTTP isteği gönderir. Sonuç olarak, bir sitedeki olayların diğer sitedeki eylemleri tetiklemesini sağlayabilirsiniz (wiki). Kaynak sitenin bir nesne deposu olması durumunda olaylar, içeriğinde değişiklik görevi görür.
Bu tür otomasyonun kullanılabileceği basit durumlara örnekler:
Başka bir bulut depolama alanındaki tüm nesnelerin kopyalarını oluşturmak. Dosyalar eklendiğinde veya değiştirildiğinde kopyalar anında oluşturulmalıdır.
Bir dizi grafik dosyasının küçük resmini otomatik olarak oluşturma, fotoğraflara filigran ekleme ve diğer görüntü değişiklikleri.
Yeni belgelerin gelişiyle ilgili bildirim (örneğin, dağıtılmış bir muhasebe hizmeti raporları buluta yükler ve finansal izleme, yeni raporlar hakkında bildirimler alır, bunları kontrol eder ve analiz eder).
Biraz daha karmaşık durumlar, örneğin gerekli kapsayıcıları içeren bir bölme oluşturan Kubernetes'e bir istek oluşturulmasını, görev parametrelerinin ona iletilmesini ve işlendikten sonra kapsayıcının daraltılmasını içerir.
Örnek olarak, Mail.ru Bulut Çözümleri (MCS) nesne depolama grubundaki değişiklikler web kancaları kullanılarak AWS nesne depolamasında senkronize edildiğinde görev 1'in bir çeşidini yapacağız. Gerçek yüklü bir durumda webhook'ların kuyruğa kaydedilmesiyle asenkron çalışma sağlanmalıdır ancak eğitim görevi için uygulamayı bu olmadan yapacağız.
Web kancası alıcı sunucusuHTTP yayınlama hizmetinden gelen istekleri dinleyen ve uygun eylemleri gerçekleştiren. Sunucu herhangi bir dilde yazılabilir; örneğimizde sunucuyu Go'ya yazacağız.
Web kancalarının S3 API'de uygulanmasının özel bir özelliği, web kancası alıcı sunucusunun yayınlama hizmetine kaydedilmesidir. Özellikle, web kancası alıcı sunucusunun, yayınlama hizmetinden gelen mesajlara aboneliği onaylaması gerekir (diğer web kancası uygulamalarında, aboneliğin onayı genellikle gerekli değildir).
Buna göre webhook alıcı sunucusunun iki ana işlemi desteklemesi gerekir:
Webhook alıcı sunucusunu çalıştırmak için bir Linux sunucusuna ihtiyacınız vardır. Bu yazımızda örnek olarak MCS üzerinde konuşlandırdığımız sanal bir örneği kullanıyoruz.
Gerekli yazılımı yükleyelim ve webhook alıcı sunucusunu başlatalım.
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) ...
Web kancalarını yapılandıracağımız pakete gidin ve donanıma tıklayın:
Web Kancaları sekmesine gidin ve Ekle'ye tıklayın:
Alanları doldurun:
Kimlik — web kancasının adı.
Olay - hangi olayların iletileceği. Dosyalarla çalışırken (ekleme ve silme) meydana gelen tüm olayların aktarımını ayarladık.
URL — webhook alıcı sunucu adresi.
Filtre öneki/son eki, yalnızca adları belirli kurallarla eşleşen nesneler için web kancaları oluşturmanıza olanak tanıyan bir filtredir. Örneğin, webhook'un yalnızca .png uzantılı dosyaları tetiklemesi için Filtre son eki “png” yazmanız gerekiyor.
Şu anda webhook alıcı sunucusuna erişim için yalnızca 80 ve 443 numaralı bağlantı noktaları desteklenmektedir.
Haydi tıklayalım Kanca ekle ve şunları göreceğiz:
Kanca eklendi.
Webhook alıcı sunucusu, günlüklerinde kanca kayıt işleminin ilerlemesini gösterir:
HmacSha256 ve HmacSha256hex işlevleri, imzayı hesaplamak için onaltılık sayılardan oluşan bir dize olarak çıktı veren HMAC-SHA256 ve HMAC-SHA256 şifreleme algoritmalarının uygulamalarıdır.
main ana işlevdir, komut satırı parametrelerini işler ve URL işleyicilerini kaydeder.
Sunucu tarafından kabul edilen komut satırı parametreleri:
-port, sunucunun dinleyeceği bağlantı noktasıdır.
-adres - Sunucunun dinleyeceği IP adresi.
-script, gelen her kanca için çağrılan harici bir programdır.
Bazı işlevlere daha yakından bakalım:
//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)
}
}
Bu işlev, kaydı onaylamaya yönelik bir isteğin veya bir web kancasının gelip gelmediğini belirler. Aşağıdaki gibi belgeleme, kayıt onaylanırsa Post isteğinde aşağıdaki Json yapısı alınır:
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»
}
Buna göre talebe bağlı olarak verilerin nasıl işleneceğini anlamanız gerekir. Girişi gösterge olarak seçtim "Type":"SubscriptionConfirmation"çünkü abonelik onay isteğinde mevcut olup webhook'ta mevcut değildir. POST isteğinde bu girişin varlığına/yokluğuna bağlı olarak programın daha fazla yürütülmesi ya işleve gider SubscriptionConfirmation, veya işleve GotRecords.
AbonelikOnay fonksiyonunu detaylı olarak ele almayacağız; aşağıda belirtilen ilkelere göre uygulanmaktadır. belgeleme. Bu işlevin kaynak kodunu şu adreste görüntüleyebilirsiniz: proje git depoları.
GotRecords işlevi, gelen bir isteği ayrıştırır ve her Record nesnesi için, aşağıdaki parametrelerle birlikte harici bir komut dosyasını (adı -script parametresinde aktarılan) çağırır:
sil - orijinal istekte ise EventName = ObjectRemoved | Nesneyi Sil
Bu nedenle, açıklandığı gibi bir Post isteğiyle birlikte bir kanca gelirse yukarıdave -script=script.sh parametresi kullanıldığında komut dosyası şu şekilde çağrılacaktır:
script.sh bucketA some-file-to-bucket copy
Bu web kancası alıcı sunucusunun eksiksiz bir üretim çözümü olmadığı, ancak olası bir uygulamanın basitleştirilmiş bir örneği olduğu anlaşılmalıdır.
İş örneği
Dosyaları MCS'deki ana klasörden AWS'deki yedekleme paketine senkronize edelim. Ana kovanın adı myfiles-ash, yedek olanın adı ise myfiles-backup'tır (AWS'deki kova yapılandırması bu makalenin kapsamı dışındadır). Buna göre, bir dosya ana kovaya yerleştirildiğinde kopyası yedekte görünmeli, ana kovadan silindiğinde yedekte de silinmelidir.
Hem MCS bulut depolama hem de AWS bulut depolama ile uyumlu olan awscli yardımcı programını kullanarak paketlerle çalışacağız.
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) ...
S3 MCS API'sine erişimi yapılandıralım:
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]:
AWS S3 API'sine erişimi yapılandıralım:
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]:
Erişimleri kontrol edelim:
AWS'ye:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup
MCS için, komutu çalıştırırken —endpoint-url'yi eklemeniz gerekir:
Nasıl çalıştığını görelim. Başından sonuna kadar MCS web arayüzü test.txt dosyasını myfiles-ash klasörüne ekleyin. Konsol günlükleri webhook sunucusuna bir istek yapıldığını gösteriyor:
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
AWS'deki dosyalarım yedekleme paketinin içeriğini kontrol edelim:
Şimdi web arayüzü aracılığıyla dosyayı myfiles-ash kovasından sileceğiz.
Sunucu günlükleri:
2020/07/06 09:44:46 [POST] incoming HTTP request from
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt
Kova içeriği:
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$
Dosya silinir, sorun çözülür.
Sonuç ve Yapılacaklar
Bu makalede kullanılan tüm kodlar benim depomda. Ayrıca web kancalarını kaydetmek için komut dosyası örnekleri ve imza sayma örnekleri de vardır.
Bu kod, etkinliklerinizde S3 web kancalarını nasıl kullanabileceğinizi gösteren bir örnekten başka bir şey değildir. Başlangıçta söylediğim gibi, böyle bir sunucuyu üretimde kullanmayı planlıyorsanız, en azından sunucuyu eşzamansız çalışma için yeniden yazmanız gerekir: gelen web kancalarını bir kuyruğa kaydedin (RabbitMQ veya NATS) ve oradan bunları ayrıştırıp işleyin. İşçi uygulamalarıyla. Aksi takdirde, web kancaları çok sayıda geldiğinde, görevleri tamamlamak için sunucu kaynaklarının yetersizliğiyle karşılaşabilirsiniz. Kuyrukların varlığı, sunucuyu ve çalışanları dağıtmanıza ve arıza durumunda tekrarlanan görevlerle ilgili sorunları çözmenize olanak tanır. Ayrıca günlüğe kaydetmenin daha ayrıntılı ve daha standart hale getirilmiş bir şekilde değiştirilmesi de tavsiye edilir.