معماری رویداد محور کارایی هزینه منابع مورد استفاده را افزایش می دهد زیرا آنها فقط در لحظه ای که به آنها نیاز است استفاده می شوند. گزینه های زیادی در مورد نحوه پیاده سازی این و عدم ایجاد موجودیت های ابری اضافی به عنوان برنامه های کاربردی وجود دارد. و امروز نه در مورد FaaS، بلکه در مورد وب هوک ها صحبت خواهم کرد. من یک مثال آموزشی از مدیریت رویدادها با استفاده از وب هوک های ذخیره سازی اشیاء را نشان خواهم داد.
چند کلمه در مورد ذخیره سازی اشیاء و وب هوک ها. ذخیره سازی اشیاء به شما امکان می دهد هر داده ای را در فضای ابری به شکل اشیا ذخیره کنید که از طریق S3 یا API دیگری (بسته به اجرا) از طریق HTTP/HTTPS قابل دسترسی است. وب هوک ها معمولاً تماس های سفارشی HTTP هستند. آنها معمولاً توسط یک رویداد فعال می شوند، مانند ارسال کد به یک مخزن یا ارسال نظر در وبلاگ. هنگامی که رویدادی رخ می دهد، سایت مبدا درخواست HTTP را به URL مشخص شده برای وب هوک ارسال می کند. در نتیجه، میتوانید رویدادهای یک سایت را در سایت دیگر فعال کنید (ویکی). در مواردی که سایت منبع یک ذخیره سازی شی باشد، رویدادها به عنوان تغییراتی در محتوای آن عمل می کنند.
نمونه هایی از موارد ساده ای که می توان از چنین اتوماسیونی استفاده کرد:
ایجاد کپی از تمام اشیاء در فضای ذخیره سازی ابری دیگر. هر زمان که فایلها اضافه میشوند یا تغییر میکنند، باید کپیها به سرعت ایجاد شوند.
ایجاد خودکار مجموعه ای از ریز عکسها از فایل های گرافیکی، افزودن واترمارک به عکس ها و سایر تغییرات تصویر.
اطلاع رسانی در مورد ورود اسناد جدید (به عنوان مثال، یک سرویس حسابداری توزیع شده گزارش ها را در فضای ابری آپلود می کند، و نظارت مالی اعلان هایی در مورد گزارش های جدید دریافت می کند، آنها را بررسی و تجزیه و تحلیل می کند).
موارد کمی پیچیده تر شامل ایجاد یک درخواست برای Kubernetes است که یک pod با کانتینرهای لازم ایجاد می کند، پارامترهای وظیفه را به آن ارسال می کند و پس از پردازش، ظرف را جمع می کند.
به عنوان مثال، زمانی که تغییرات در سطل ذخیرهسازی اشیاء Mail.ru Cloud Solutions (MCS) در ذخیرهسازی شی AWS با استفاده از وبکهوکها همگامسازی میشوند، یک نوع کار 1 ایجاد میکنیم. در یک مورد بارگذاری شده واقعی، کار ناهمزمان باید با ثبت وب هوک ها در یک صف ارائه شود، اما برای کار آموزشی، ما پیاده سازی را بدون این کار انجام خواهیم داد.
خدمات انتشارات، که در سمت ذخیره سازی S3 قرار دارد و درخواست های HTTP را هنگام راه اندازی webnhook منتشر می کند.
سرور دریافت وب هوک، که به درخواست های سرویس انتشار HTTP گوش می دهد و اقدامات مناسب را انجام می دهد. سرور را می توان به هر زبانی نوشت؛ در مثال ما سرور را در Go می نویسیم.
یکی از ویژگی های خاص پیاده سازی وب هوک در S3 API ثبت سرور دریافت کننده وب هوک در سرویس انتشار است. به ویژه، سرور دریافت کننده وب هوک باید اشتراک پیام های سرویس انتشار را تأیید کند (در سایر پیاده سازی های وب هوک، معمولاً تأیید اشتراک لازم نیست).
بر این اساس، سرور دریافت وب هوک باید از دو عملیات اصلی پشتیبانی کند:
به درخواست سرویس انتشار برای تایید ثبت پاسخ دهید،
پردازش رویدادهای دریافتی
نصب سرور دریافت وب هوک
برای اجرای سرور دریافت وب هوک، به سرور لینوکس نیاز دارید. در این مقاله، به عنوان مثال، از یک نمونه مجازی استفاده می کنیم که در MCS مستقر می کنیم.
بیایید نرم افزار لازم را نصب کنیم و سرور دریافت وب هوک را راه اندازی کنیم.
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) ...
به سطلی بروید که برای آن webhook ها را پیکربندی می کنیم و روی چرخ دنده کلیک کنید:
به تب Webhooks بروید و روی Add کلیک کنید:
فیلدها را پر کنید:
ID - نام وب هوک.
رویداد - کدام رویدادها باید منتقل شوند. ما انتقال تمام رویدادهایی را که هنگام کار با فایل ها (افزودن و حذف) رخ می دهد تنظیم کرده ایم.
URL - آدرس سرور دریافت کننده وب هوک.
پیشوند/پسوند فیلتر فیلتری است که به شما امکان می دهد فقط برای اشیایی که نام آنها با قوانین خاصی مطابقت دارد وب هوک ایجاد کنید. به عنوان مثال، برای اینکه وب هوک فقط فایل هایی با پسوند png. را فعال کند، در پسوند فیلتر شما باید "png" بنویسید.
در حال حاضر تنها پورت های 80 و 443 برای دسترسی به سرور دریافت کننده وب هوک پشتیبانی می شوند.
بیایید کلیک کنیم قلاب اضافه کنید و موارد زیر را خواهیم دید:
هوک اضافه شد.
سرور دریافت وب هوک در گزارش های خود پیشرفت فرآیند ثبت هوک را نشان می دهد:
Ping() - مسیری که از طریق URL/ping پاسخ می دهد، ساده ترین پیاده سازی یک کاوشگر زنده.
Webhook() - مسیر اصلی، URL/webhook handler:
ثبت نام در سرویس انتشار را تأیید می کند (به تابع SubscriptionConfirmation بروید)
وب هوک های دریافتی را پردازش می کند (عملکرد Gorecords).
توابع HmacSha256 و HmacSha256hex پیاده سازی الگوریتم های رمزگذاری HMAC-SHA256 و HMAC-SHA256 با خروجی به عنوان رشته ای از اعداد هگزا دسیمال برای محاسبه امضا هستند.
main تابع اصلی است، پارامترهای خط فرمان را پردازش می کند و کنترل کننده های URL را ثبت می کند.
پارامترهای خط فرمان پذیرفته شده توسط سرور:
-port پورتی است که سرور به آن گوش می دهد.
-address - آدرس IP که سرور به آن گوش خواهد داد.
-script یک برنامه خارجی است که برای هر هوک ورودی فراخوانی می شود.
بیایید نگاهی دقیق تر به برخی از عملکردها بیندازیم:
//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)
}
}
این تابع تعیین می کند که آیا درخواستی برای تأیید ثبت نام رسیده است یا یک وب هوک. به شرح زیر از مستندات، در صورت تایید ثبت نام، ساختار Json زیر در درخواست Post دریافت می شود:
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»
}
بر این اساس، بسته به درخواست، باید نحوه پردازش داده ها را بدانید. من ورودی را به عنوان شاخص انتخاب کردم "Type":"SubscriptionConfirmation"، زیرا در درخواست تأیید اشتراک وجود دارد و در وب هوک وجود ندارد. بر اساس وجود یا عدم وجود این ورودی در درخواست POST، اجرای بیشتر برنامه یا به تابع می رود SubscriptionConfirmation، یا به تابع GotRecords.
ما تابع SubscriptionConfirmation را با جزئیات در نظر نخواهیم گرفت؛ این تابع طبق اصولی که در مستندات. شما می توانید کد منبع این تابع را در اینجا مشاهده کنید مخازن پروژه git.
تابع GotRecords یک درخواست ورودی را تجزیه می کند و برای هر شی Record یک اسکریپت خارجی (که نام آن در پارامتر -script ارسال شده است) با پارامترهای زیر فراخوانی می کند:
نام سطل
کلید شی
عمل:
کپی - اگر در درخواست اصلی EventName = ObjectCreated | PutObject | PutObjectCopy
حذف - اگر در درخواست اصلی EventName = ObjectRemoved | DeleteObject
بنابراین، اگر یک هوک با یک درخواست ارسال، همانطور که توضیح داده شد، وارد شود بالاتر، و پارامتر -script=script.sh سپس اسکریپت به صورت زیر فراخوانی می شود:
script.sh bucketA some-file-to-bucket copy
باید درک کرد که این سرور دریافت وب هوک یک راه حل کامل تولید نیست، بلکه یک نمونه ساده از یک پیاده سازی ممکن است.
نمونه کار
بیایید فایل ها را از سطل اصلی در MCS به سطل پشتیبان در AWS همگام کنیم. سطل اصلی myfiles-ash نام دارد و سطل پشتیبان myfiles-backup نام دارد (پیکربندی سطل در AWS خارج از محدوده این مقاله است). بر این اساس، زمانی که فایلی در سطل اصلی قرار میگیرد، کپی آن در سطل پشتیبان و زمانی که از فایل اصلی حذف میشود، باید در سطل پشتیبان حذف شود.
ما با استفاده از ابزار awscli که با فضای ذخیره سازی ابری MCS و فضای ذخیره سازی ابری 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) ...
اجازه دهید دسترسی به 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]:
اجازه دهید دسترسی به API 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]:
بیایید دسترسی ها را بررسی کنیم:
به AWS:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup
برای MCS، هنگام اجرای دستور باید —endpoint-url را اضافه کنید:
بیایید ببینیم چگونه کار می کند. از طریق رابط وب MCS فایل test.txt را به سطل myfiles-ash اضافه کنید. گزارشهای کنسول نشان میدهند که درخواستی به سرور وب هوک ارسال شده است:
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
بیایید محتویات سطل پشتیبان myfiles را در AWS بررسی کنیم:
اکنون از طریق رابط وب، فایل را از سطل myfiles-ash حذف می کنیم.
گزارش های سرور:
2020/07/06 09:44:46 [POST] incoming HTTP request from
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt
محتویات سطل:
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$
فایل پاک شد مشکل حل شد
نتیجه گیری و انجام کار
تمام کدهای استفاده شده در این مقاله می باشد در مخزن من. همچنین نمونه هایی از اسکریپت ها و نمونه هایی از شمارش امضا برای ثبت وب هوک ها وجود دارد.
این کد چیزی نیست جز مثالی از اینکه چگونه می توانید از وب هوک های S3 در فعالیت های خود استفاده کنید. همانطور که در ابتدا گفتم، اگر قصد دارید از چنین سروری در تولید استفاده کنید، حداقل باید سرور را برای کارهای ناهمزمان بازنویسی کنید: وب هوک های ورودی را در یک صف ثبت کنید (RabbitMQ یا NATS)، و از آنجا آنها را تجزیه و پردازش کنید. با برنامه های کارگری در غیر این صورت، هنگامی که وب هوک ها به طور انبوه وارد می شوند، ممکن است با کمبود منابع سرور برای تکمیل وظایف مواجه شوید. وجود صف به شما امکان می دهد سرور و کارگران را توزیع کنید و همچنین در صورت خرابی مشکلات مربوط به تکرار وظایف را حل کنید. همچنین توصیه می شود که ورود به سیستم را به یک جزئیات بیشتر و استانداردتر تغییر دهید.