چگونه یک برنامه قابل جابجایی Golang ایجاد کنیم و از AWS Lambda Layers بهره مند شویم.

گلنگ - چرا ارزش توجه شما را دارد؟

Golang یک زبان برنامه نویسی منبع باز است که توسط Google تولید و اجرا شده است. در کاربردهای مدرن خصوصاً در ابر بسیار گسترده استفاده می شود. آنها مشخصه ترین ویژگی ها هستند:

  • Golang بصورت ایستا نوشته شده است - انعطاف پذیری کمتری دارد اما از شما در برابر خطا محافظت می کند ،
  • شی گرا نیست. با این حال ، شما می توانید ساختارها و رابط هایی ایجاد کنید ، و این نتیجه از 3 اصل OOP 3 نتیجه گیری می شود: انتزاع داده ، کپسول سازی و چندشکلی. آنچه از دست رفته است ارث است
  • Goroutines! - بهترین اجرای رشته های سبک که تاکنون استفاده کرده ام. با استفاده از اپراتور go می توانید به راحتی یک موضوع جدید ایجاد کنید و از طریق کانال های بین goroutines مختلف ارتباط برقرار کنید.
  • با تمام وابستگی ها در یک فایل باینری تکمیل می شود - دیگر هیچ درگیری بسته وجود ندارد!

من شخصاً Golang را بزرگترین زبانی می دانم که هر روز استفاده می کنم. با این حال ، این مقاله در مورد ایجاد اولین عملکرد شما یا چاپ "Hello World" نیست. من چیزهای پیشرفته تری به شما نشان می دهم. اگر مبتدی هستید و می خواهید در مورد Golang بیشتر بدانید ، لطفاً به صفحه اصلی مراجعه کنید.

AWS لامبدا و گلنگ

AWS Lambda یکی از محبوب ترین سرویس های رایانش بدون سرور در فضای ابری عمومی است که توسط وب آمازون در نوامبر 2014 منتشر شد. بدون نیاز به تنظیم یا مدیریت سرورها ، می توانید کد خود را در پاسخ به رویدادهایی مانند DynamoDB ، SNS یا HTTP راه اندازی کنید! آیا می دانید چه چیزی واقعاً عالی است؟ از ژانویه 2018 از دوره Golang حمایت می کند. کار با AWS Lambda واقعاً آسان است - فقط یک بسته فشرده با کد و همه وابستگی ها را بارگذاری کنید (اگر از Golang استفاده می کنید ، یک باینری است).

سریع 4 سال بعد ، 2018 دوباره: Invent AWS Lambda Layers را منتشر می کند که به شما امکان می دهد داده هایی را که برای عملکردهای مختلف در یک یا حتی چندین حساب AWS به اشتراک گذاشته شده ذخیره و مدیریت کنید! به عنوان مثال ، اگر از پایتون استفاده می کنید ، می توانید تمام وابستگی ها را در یک لایه اضافی قرار دهید که بعداً توسط سایر lambdas قابل استفاده باشد. دیگر لازم نیست که وابستگی های مختلفی را در هر بسته فشرده قرار دهید! در جهان Golang اوضاع متفاوت است زیرا AWS Lambda نیاز به بارگذاری پرونده های باینری کامپایل شده دارد. چگونه می توانیم از لایه های AWS Lambda بهره مند شویم؟ پاسخ ساده است - با پلاگین های Golang یک برنامه مدولار بسازید!

افزونه های Golang - روشی برای ساخت یک برنامه مدولار

Golang Plugins ویژگی منتشر شده در Go1.8 است که به شما امکان می دهد کتابخانه های مشترک (فایلهای so.) را به صورت پویا بارگیری کنید. شما این امکان را دارید که بخشی از کد خود را به کتابخانه جداگانه صادر کنید یا از افزونه ای که توسط شخص دیگری ایجاد و تدوین شده استفاده کنید. با این وجود محدودیت هایی وجود دارد:

  • پلاگین شما باید یک ماژول اصلی باشد ،
  • فقط می توانید توابع و متغیرهایی را که به عنوان نمادهای ELF صادر می شوند بارگیری کنید.
  • به دلیل تایپ ثابت ، باید هر علامت بارگذاری شده را به نوع صحیح تبدیل کنید. در بدترین حالت ، باید رابط صحیح را در کد خود تعریف کنید ،
  • این فقط در Linux و MacOS کار می کند. من شخصاً این را به عنوان یک ضرر نمی دانم :)

اولین پلاگین خود را ایجاد و آزمایش کنید

حالا بیایید اولین پلاگین خود را ایجاد کنیم. به عنوان نمونه ماژولی ساده برای رمزگذاری رشته ایجاد خواهیم کرد. بیایید به اصول اولیه برگردیم و دو الگوریتم رمزگذاری ساده - Ceasar و Verman را پیاده سازی کنیم.

  • رمز سزار الگوریتمی است که اولین بار توسط Julius Ceases استفاده شد. هر حرف را در متن به تعداد مشخص مکان تغییر می دهد. به عنوان مثال ، اگر بخواهید کلمه golang را با کلید 4 رمزگذاری کنید ، ktpek دریافت خواهید کرد. رمزگشایی به همان روش کار می کند. تمام کاری که شما باید انجام دهید این است که حروف را در جهت مخالف حرکت دهید.
  • رمز Verman مشابه رمز Ceaser است ، بر اساس همان ایده تغییر دهنده. تفاوت در این است که شما هر حرف را به تعداد مختلف موقعیت حرکت می دهید. برای رمزگشایی متن ، شما به یک کلید با موقعیت هایی که متن رمزگذاری شده است نیاز دارید. به عنوان مثال ، اگر بخواهید کلمه golang را با کلید [-1 ، 4 ، 7 ، 20 ، 4 ، -2] رمزگذاری کنید ، آینده خواهید داشت.

اجرای کامل این مثال را می توان در اینجا یافت.

اجرای پلاگین

قطعه زیر شامل پیاده سازی دو الگوریتم ذکر شده در بالا است. برای هر کدام ، ما دو روش رمزگذاری و رمزگشایی متن خود را پیاده سازی می کنیم:

همانطور که مشاهده می کنید ، ما 3 نماد مختلف در اینجا صادر کرده ایم (گلانگ فقط این شناسه هایی را که با حرف بالا شروع می شوند صادر می کند):

  • EncryptCeasar - func (int ، string) رشته ای که متن را با استفاده از الگوریتم Ceasar رمزگذاری می کند.
  • DecryptCeaser - رشته ای (int ، string) رشته ای که متن را با استفاده از الگوریتم Caeser رمزگشایی می کند ،
  • VermanCipher - متغیری از نوع vermanCipher ، که 2 روش را پیاده سازی می کند: رمزگذاری: رشته func (رشته) و رمزگشایی: func () (* رشته ، خطا)

برای کامپایل این افزونه باید دستور زیر را اجرا کنید:

go build -buildmode = plugin -o plugin / cipher.so plugin / cipher.go

در حال حاضر هیچ چیز خاصی وجود ندارد - فقط چند عملکرد ساده ایجاد شده و یک ماژول با اضافه کردن آرگومان -buildmode = plugin به عنوان یک پلاگین وارد شده است.

پلاگین را بارگیری و آزمایش کنید

لذت از زمانی شروع می شود که می خواهیم از افزونه کامپایل شده در برنامه خود استفاده کنیم. بیایید یک مثال ساده ایجاد کنیم:

ابتدا باید بسته پلاگین Golang را وارد کنید. این شامل تنها دو عملکرد است - اولین بارگذاری یک کتابخانه مشترک و دوم یافتن یک نماد صادر شده است. برای بارگذاری کتابخانه خود ، باید از عملکرد Open استفاده کنید که برای آن باید مسیر افزونه مشترک و متغیر بازگشت نوع پلاگین را مشخص کنید. اگر کتابخانه بارگیری نشود (به عنوان مثال مسیر اشتباه یا پرونده آسیب دیده) ، این عملکرد خطایی را که باید مدیریت شود برمی گرداند.

مرحله بعدی بارگیری هر نماد صادر شده با استفاده از روش مراجعه است. یک نقطه ضعف کوچک این است که شما باید هر عملکرد صادر شده را جداگانه بارگیری کنید. با این حال ، می توانید چندین عملکرد را به همان روشی که برای نماد VermanCipher انجام داده اید ، ترکیب کنید. پس از بارگیری همه نمادهایی که می خواهید استفاده کنید ، باید آنها را به نوع صحیح تبدیل کنید. Golang یک زبان تایپی استاتیک است ، بنابراین راهی دیگر برای استفاده از این نمادها بدون ریخته گری وجود ندارد. به یاد داشته باشید ، اگر متغیری را صادر می کنید که برخی از روش ها را پیاده سازی می کند ، باید آن را به نوع رابط صحیح وارد کنید (برای کنترل این مسئله باید رابط encryptionEngine را تعریف می کردم) \ Newline \ newline

برای کامپایل و اجرای برنامه از دستور زیر استفاده کنید:

برو ساخت app.go ./app

در خروجی ، شما باید متن رمزگذاری شده و رمزگشایی شده را به عنوان شواهدی از عملکرد صحیح الگوریتم مشاهده کنید.

از پلاگین در AWS Lambda استفاده کنید

برای استفاده از افزونه خود در AWS Lambda ، باید تغییراتی در برنامه خود ایجاد کنیم:

  • AWS Lambda لایه هایی را در پوشه / opt در ظرف Lambda نصب می کند ، بنابراین ما باید پلاگین خود را از این پوشه بارگیری کنیم.
  • ما باید یک عملکرد کنترل کننده ایجاد کنیم که توسط موتور Lambda برای پردازش رویداد آزمایش ما استفاده شود.

قطعه زیر شامل برنامه ما است که برای استفاده توسط Lambda اقتباس شده است:

همانطور که می بینید ، پیاده سازی بسیار شبیه به قبلی است. ما فقط دایرکتوری را که پلاگین خود را از آن بارگیری کردیم تغییر دادیم و به جای چاپ مقادیر ، پاسخ عملکرد را اضافه کردیم. برای کسب اطلاعات بیشتر در مورد نوشتن لامبدا در Golang ، به اسناد AWS مراجعه کنید.

استقرار AWS لامبدا

دو روش برای استقرار توابع و لایه های AWS Lambda وجود دارد. شما می توانید یک بسته فشرده را به صورت دستی ایجاد و بارگذاری کنید یا از چارچوب پیشرفته ای استفاده کنید که باعث سهولت و سرعت بیشتر آن می شود. در بیشتر پروژه های من از فریم ورک بدون سرور استفاده می کنم. بنابراین من در حال حاضر فایل پیکربندی ساده serverless.yml را با این ابزار آماده کرده ام:

سرویس: cipherService frameworkVersion: "> = 1.28.0 <2.0.0" ارائه دهنده: نام: aws زمان اجرا: go1.x
لایه ها: رمزنگاری لایه: مسیر: bin / plugin زمان اجرا سازگار: - go1.x
توابع: موتور: کنترل کننده: bin / cipherEngine بسته بندی: شامل: - ./** شامل: - ./bin/cipherEngine لایه ها: - {Ref: CipherLayerLambdaLayer}

در ناحیه لایه ، ما یک لایه واحد با مسیر پلاگین ایجاد کرده ایم که قبلاً ایجاد شده است - این همراه با عملکرد Lambda ارائه می شود. شما می توانید حداکثر 5 سطح مختلف تعریف کنید که ترتیب آن واقعاً مهم است. آنها در همان پوشه / opt نصب شده اند ، بنابراین لایه هایی با تعداد بیشتر می توانند پرونده ها را از لایه های نصب شده قبلی بازنویسی کنند. برای هر سطح باید حداقل 2 پارامتر تعیین کنید: مسیر به پوشه با منبع سطح (در مسیر مورد خود به پرونده باینری پلاگین) و لیست زمانهای سازگار.

بخش عملکرد بعدی مکانی است که در آن شما لیستی از توابع برای اجرا را تعریف می کنید. برای هر تابع حداقل باید مسیر برنامه کامپایل شده را مشخص کنید. علاوه بر این ، ما باید پارامتر لایه را با توجه به لایه تعریف شده در بالا تعریف کنیم. این به طور خودکار لایه را به تابع Lambda ما در حین استقرار اضافه می کند. نکته جالب این است که اگر می خواهید به این منبع مراجعه کنید ، باید نام لایه Lambda خود را به TitleCased تبدیل کرده و پسوند LambdaLayer را اضافه کنید. به نظر می رسد تیم بدون سرور این روش را برای حل تعارض در مورد انواع مختلف منابع پیاده سازی کرده است.

به محض آماده شدن فایل پیکربندی serverless.yml ما ، آخرین کاری که باید انجام دهید اینست که برنامه ما را کامپایل ، وصل کنید و استقرار دهید. برای این کار می توانیم از یک پرونده ساده استفاده کنیم:

.PHONY: ساخت BuildPlugin را به راحتی تمیز کنید
build: dep safe -v env GOOS = Linux go build -ldflags = "-s -w" -o bin / cipherEngine cipherEngine / main.go
buildPlugin: env GOOS = Linux go build -ldflags = "- s -w" -buildmode = Plugin -o bin / plugin / cipher.so ../plugin/cipher.go
تمیز: rm -rf ./bin ./vendor Gopkg.lock
استقرار: build buildPlugin build sls استقرار - verbose

با اجرای دستور زیر می توانید عملکرد خود را ایجاد و استقرار دهید:

فراهم کردن

AWS لامبدا را امتحان کنید

همانطور که قبلا ذکر شد ، کد AWS Lambda در پاسخ به این رویداد اجرا می شود. با این حال ، ما هیچ محرک رویدادی را پیکربندی نکرده ایم ، بنابراین بدون کمک ما نمی توان آنها را فراخوانی کرد. ما باید این کار را به صورت دستی با Serverless Framework یا ابزار awscli انجام دهیم:

فراخوانی sls -f function-name aws lambda invoke - فایل تابع name-name خروجی پرونده

در جواب ، باید همان خروجی قبلی را مشاهده کنید ، که ثابت می کند عملکرد lambda ما به درستی کار می کند و پلاگین از لایه اضافی بارگیری می شود. اکنون می توانید توابع دیگری ایجاد کنید که از همان لایه استفاده می کنند یا حتی آن را با حساب های دیگر AWS به اشتراک بگذارید.

خلاصه

با استفاده از ماژول های Golang و آزمایش نحوه یکپارچه سازی آنها با لایه های AWS Lambda بسیار جالب بود. کتابخانه پلاگین واقعاً عالی است ، اما به دلیل محدودیت ها و مشخصات Golang فقط در سناریوهای خاص قابل استفاده است. فکر می کنم برای اکثر توسعه دهندگانی که روی پروژه های استاندارد کار می کنند ، افزونه ها مورد نیاز و حتی امکان پذیر نیستند. من فقط می توانم به دو دلیل فکر کنم:

  • پیاده سازی الگوریتم های پیچیده ای که می توانند توسط برنامه های دیگر استفاده شوند ، به عنوان مثال الگوریتم های کدگذاری یا رمزگذاری ویدئو.
  • بدون انتشار کد ، الگوریتم خود را با دیگران به اشتراک بگذارید.