PHP tanpa server di AWS Lambda

Halo semuanya. Pada hari Senin, pelajaran pertama akan diadakan di grup baru kursus "Backend PHP Developer" . Dalam hal ini, kami terus menerbitkan materi yang bermanfaat tentang topik ini. Mari kita mulai.



Seperti Simon Wordley , saya percaya bahwa komputasi tanpa server adalah bidang yang sangat menarik, terutama karena sistem pembayaran granular (hanya membayar ketika kode Anda dieksekusi), dan Anda tidak perlu khawatir tentang servis dan persiapan server serta wadah. Sedemikian rupa sehingga saya bekerja dengan PHP Runtime terbuka untuk Apache OpenWhisk , versi komersial yang tersedia sebagai salah satu fitur dari IBM Cloud .

Ada penyedia serverless lainnya, dan AWS Lambda adalah pemimpin pasar, tetapi sampai saat ini, dukungan PHP sangat rumit dan bersahaja. Ini berubah pada akhir 2018 dengan API runtime Lambda baru dan dukungan lapisan .

Mari kita lihat aspek praktis dari PHP tanpa server di Lambda dengan Kerangka Tanpa Server .

TL; DR


Kode sumber untuk Hello World yang sederhana ada di repositori lambda-php saya di Github. Buka bagian Catatan dan kami dapat melanjutkan.

Runtime php


API runtime memungkinkan Anda untuk menggunakan runtime apa pun dengan Lambda. Di satu sisi, ini mirip dengan OpenWhisk, karena ada HTTP API antara platform tanpa server dan runtime. Ada satu perbedaan besar dengan Lambda, runtime mengirimkan permintaan ke platform untuk menerima data panggilan, sementara OpenWhisk memanggil titik akhir yang harus disediakan oleh runtime. Untuk informasi lebih lanjut, lihat posting blog AWS Michael Moussa yang menginspirasi saya untuk melakukan pekerjaan itu.

Untuk memulai, kita membutuhkan runtime PHP untuk Lambda. Ini akan terdiri dari executable PHP, kode PHP untuk memanggil fungsi tanpa server, dan file bootstrap , sebagaimana diminta oleh platform. Dari tiga hal ini kami mengumpulkan lapisan. Lapisan dapat digunakan kembali di akun yang berbeda, jadi saya terkejut bahwa AWS tidak memberi kami akun PHP. Luar biasa, tetapi benar, mereka tidak menggunakan PHP 7.3, jadi kita harus membangunnya sendiri.
Semua file yang kami tempatkan di direktori layer/php di proyek kami.

Membangun sebuah executable PHP


Kami membutuhkan executable PHP yang akan berjalan di dalam wadah Lambda. Cara termudah untuk melakukannya adalah mengompilasinya di platform yang sama dengan Lambda, jadi kami akan menggunakan EC2. Artikel Michael menjelaskan cara melakukan ini, dan saya membungkus perintah-perintah ini dalam skrip compile_php.sh , lalu untuk menyalinnya ke instance EC2, jalankan dan salin file yang dapat dieksekusi kembali ke komputer saya:

 $ export AWS_IP=ec2-user@{ipaddress} $ export SSH_KEY_FILE=~/.ssh/aws-key.rsa $ scp -i $SSH_KEY_FILE compile_php.sh $AWS_IP:doc/compile_php.sh $ ssh -i $SSH_KEY_FILE -t $AWS_IP "chmod a+x compile_php.sh && ./compile_php.sh 7.3.0" $ scp -i $SSH_KEY_FILE $AWS_IP:php-7-bin/bin/php layer/php/php 


Pendekatan ini akan membuatnya dapat direproduksi dengan baik, dan mudah-mudahan hanya akan ditingkatkan ke versi PHP yang baru.

Bootstrap


Karena kami menggunakan runtime API, kami memerlukan file bootstrap . Lambda sendiri membutuhkan nama seperti itu untuk menentukan file, itu menanggapi panggilan fungsi yang cocok dengan gambar dengan memanggil API dalam satu lingkaran.

Intinya, kita harus berada dalam satu lingkaran dan memanggil titik akhir /next untuk memahami apa yang harus dipanggil selanjutnya, memanggilnya, dan kemudian mengirim jawaban ke titik akhir /response .
AWS memberikan contoh dalam BASH menggunakan curl :

 while true do HEADERS="$(mktemp)" # Get an event EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Execute the handler function from the script RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA") # Send the response curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done 


Kami ingin melakukan hal yang sama di PHP, dan walaupun saya bisa menulisnya sendiri, Pariksit Agnihotri sudah ada di depan saya di PHP-Lambda-Runtime / runtime.php , jadi kami salin ini ke layer/php/runtime.php . Dalam versi saya, saya membuat beberapa perubahan, menambahkan json_encoding dan meningkatkan penangan kesalahan.
layer/php/bootstrap file layer/php/bootstrap sangat sederhana, dan yang diperlukan hanyalah menjalankan PHP yang dapat dieksekusi dengan file ini:

 #!/bin/sh cd $LAMBDA_TASK_ROOT /opt/php /opt/runtime.php 


Itu saja. Sekarang kami memiliki tiga file di layer / php:

  • php - file yang dapat dieksekusi php ;
  • runtime.php - file kerja API runtime;
  • bootstrap adalah file Lambda yang diperlukan.


Akibatnya, semua ini akan menjadi PHP Layer (layer) di aplikasi Lambda kami.

Konfigurasikan Kerangka Tanpa Server


Serverless Framework menyediakan konfigurasi berulang dan penyebaran aplikasi tanpa server. Saya penggemar konsep ini dan saya ingin menggunakan lebih banyak alat seperti itu. Kami akan menggunakan Kerangka Tanpa Server untuk PHP Hello World kami.
Karena tidak ada templat yang mudah untuk aplikasi dalam PHP di Serverless Framework, kami cukup membuat file serverless.yml di direktori dengan proyek kami.
Sebagai permulaan, yang paling mendasar:

 service: php-hello-world provider: name: aws runtime: provided region: eu-west-2 memorySize: 128 


Kami akan memanggil aplikasi kami php-hello-world dan menggunakan AWS sebagai penyedia. Sejak saya di Inggris, saya telah mendirikan kawasan London . Kami tidak membutuhkan banyak memori, jadi 128 MB sudah cukup.
Runtime biasanya merupakan bahasa tempat Anda ingin fungsi Anda dieksekusi. Untuk menggunakan runtime API yang akan dijalankan oleh file bootstrap kami, Anda mengatur bidang ini untuk disediakan .
Dan Anda memerlukan file .gitignore mengandung:

 .serverless 


Karena di git kita tidak perlu direktori ini.
Selanjutnya, mari kita tambahkan layer kita ke serverless.yml dengan menambahkan:

 layers: php: path: layer/php 


Ini akan membuat layer AWS dan memberinya nama PhpLambdaLayer , yang dapat kita rujuk dalam fungsi kita.

Mari kita menulis fungsi Hello World
Sekarang kita dapat menulis fungsi PHP tanpa server. Ini harus dimasukkan dalam file handler.php :

 <?php function hello($eventData) : array { return ["msg" => "hello from PHP " . PHP_VERSION]; } 


Fungsi mengambil informasi tentang acara dan mengembalikan array asosiatif.
Untuk memberi tahu Kerangka Tanpa Server tentang penyebaran fungsi kami, Anda perlu menambahkan yang berikut ke file serverless.yml :

 functions: hello: handler: handler.hello layers: - {Ref: PhpLambdaLayer} 


Kerangka Tanpa Server mendukung beberapa fungsi untuk satu aplikasi. Masing-masing dari mereka memiliki nama, dalam hal ini hello , dan, dalam kasus kami, penangan, yang merupakan nama file tanpa ekstensi, diikuti oleh titik, dan kemudian nama fungsi dalam file ini. Dengan demikian, handler.hello handler berarti kita akan menjalankan fungsi hello() di handler.php .
Akhirnya, kami juga melaporkan fungsi ke lapisan PHP kami sehingga dapat menjalankan kode PHP.

Penempatan di Lambda


Untuk memperluas fungsi kami dengan lapisannya, kami menjalankan perintah berikut:

 $ sls deploy 


Jika perintah dieksekusi selama mungkin, output yang mirip dengan ini akan diperoleh:



Pemenuhan fungsi kita


Setelah penyebaran, kita dapat memanggil fungsi menggunakan perintah:

 $ sls invoke -f hello -l 




Dan kamu selesai!

Untuk meringkas


Dengan API lapisan dan runtime baru, sekarang Anda dapat dengan mudah menjalankan fungsi serverless PHP di Lambda. Ini adalah kabar baik bagi pengembang PHP yang terikat dengan AWS.

Menunggu komentar Anda, teman-teman!

Source: https://habr.com/ru/post/id453116/


All Articles