in Technology

ลองทำ PHP Serverless ง่ายๆ ด้วย bref

ไหนๆ ก็เขียน PHP อยู่แล้ว เลยมาลองทำเป็น Serverless ทดสอบบน AWS Lambda สักหน่อย ถ้าวิธีปกติคือทำเป็น Custom Runtime แต่ขั้นตอนอาจจะยุ่งยากนิดนึง เลยมีคนทำเครื่องมือชื่อ bref ขึ้นมา ใช้ง่ายมากครับ ลองมาดูวิธีทำกัน

bref คืออะไร

bref เป็นเครื่องมือ open source หนึ่งที่ไว้ deploy และ run serverless สำหรับภาษา PHP โดยมันไป integrate กับ Serverless Framework อีกที (แน่นอน ต้องติดตั้ง Serverless Framework ก่อน) ซึ่งปัจจุบันใช้ได้เฉพาะ AWS Lambda เท่านั้น

สิ่งที่ต้องมีในเครื่อง

  • PHP 7.2+
  • Composer
  • AWS account (ต้องมี permission อย่างน้อย: CloudFormation, CloudWatch, Lambda, S3, API Gateway)
  • Node.js

จัดแจงเตรียมเครื่องมือทำงาน

ตรียม AWS Credential Key และ Secret Code (ถ้ามีแล้ว ข้ามได้ครับ)

Install serverless (ถ้ามีแล้ว ข้ามได้ครับ)

npm install -g serverless

Config serverless with AWS (ถ้าเคยทำแล้ว ข้ามได้ครับ)

serverless config credentials --provider aws --key <key> --secret <secret>

สร้างโฟลเดอร์ที่จะใช้งาน

mkdir php-bref-function

Install bref

composer require bref/bref

ทำ PHP Function Serverless ตัวแรก

Create PHP Lambda

vendor/bin/bref init

เมื่อ Enter จะแสดงข้อความให้เลือกประเภท Lambda

What kind of lambda do you want to create? (you will be able to add more functions later by editing `serverless.yml`) [PHP function]:
  [0] PHP function
  [1] HTTP application
  [2] Console application

ในที่นี้เราจะสร้าง PHP Function สามารถกด Enter ผ่านไป หรือกดคีย์หมายเลข 0 ก็ได้ จะได้ไฟล์ประมาณนี้

Config PHP Lambda

เมื่อสร้าง Application เสร็จ ให้แก้ไขไฟล์ serverless.yml ดังนี้

โดย

provider > region : คือทวีปที่เราใช้ AWS โดยทั่วไปที่ไทยใช้เป็น ap-southeast-1
functions > php-bref-function : โดย php-bref-function ชื่อ function เราแก้ตามที่ต้องการได้เลย
functions > handler : ช่องทางแรกที่ Lambda จะเรียกทำงาน
functions > layers : เป็น custom runtime แต่ในที่นี้ bref ได้สร้างเป็น layer เพื่อเรียกใช้งาน ไม่เอามาผสมกับ core code ของเรา (ทำความเข้าใจ AWS Lambda Layer คืออะไร)

อธิบายเพิ่มเติมเกี่ยวกับ Layers
สำหรับ PHP functions ให้ระบุเป็น php-74 หรือ php-73
ใช้สำหรับสร้าง PHP function เพื่อประมวลผลเท่านั้น ไม่ใช่ HTTP Application

สำหรับ HTTP applications ให้ระบุเป็น php-74-fpm หรือ php-73-fpm
โดย runtime ตัวนี้จะใช้ PHP-FPM เพื่อทำงานแบบ HTTP applications จะเหมือนกับที่เราเขียน PHP ปกติ คือเขียนเสร็จแล้วต้องเปิดผ่าน PHP hosting หรือพวก Nginx, Apache (สามารถใช้ได้กับ Symfony และ Laravel ได้ด้วยนะ)
(Read more at https://bref.sh/docs/runtimes/#bref-runtimes)

ทดสอบ PHP Function Serverless บน localhost

เมื่อสร้างเสร็จแล้ว ลองทดสอบบนเครื่องตัวเองได้นะครับ ด้วยคำสั่งนี้

serverless invoke local --docker -f <function-name>

เปลี่ยน <function-name> ให้เป็นชื่อ function ของเรา ซึ่งที่นี้คือ php-bref-function โดยผลลัพธ์ “Hello World”

แต่ถ้าอยากส่ง data payload เข้าไป ให้ใช้คำสั่งนี้

serverless invoke local --docker -f <function-name> --data '{"name": "iFew"}'

ผลลัพธ์ที่ได้คือ “Hello iFew”

ทำการ Deploy PHP Function Serverless เพื่อทดสอบบน AWS Lambda

จะลอง Deploy ขึ้นไปทดสอบบน AWS Lambda ด้วยคำสั่ง

serverless deploy

จะได้ผลลัพธ์ประมาณนี้

สังเกตว่ามีจะมีการ pack file และทำการ upload ขึ้นไปไว้บน S3 เพื่อพักไว้ก่อน และ Deploy ไปที่ Lambda อีกที

ทดสอบอีกรอบว่า บน AWS Lambda ใช้งานได้จริงหรือไม่

serverless invoke -f <function-name>

ถ้าใช้งานได้ ก็จะแสดง output ออกมาตามที่โค้ดเราเขียนไว้

ผลการทดสอบความเร็ว ของ PHP Function Serverless ด้วย bref

ทำงานด้วย Memory 1024MB (ค่ามาตรฐาน) ได้ประมาณ​ 14-15ms

ทำงานด้วย Memory 256MB ได้ประมาณ​ 75-80ms

ทำงานด้วย Memory 128MB ได้ประมาณ​ 270-290ms

ลองทำ PHP HTTP Application Serverless ดูบ้าง

วิธีการทำแบบเดิมเลยครับ ต่างกันตอนเลือกประเภท Lambda ให้เลือกประเภท [1] HTTP application แทน พร้อมกับแก้ serverless.yml ในหัวข้อ function > layer ให้เป็น php-74-fpm หรือ php-73-fpm แทน

วิธีการทดสอบบน localhost ให้ใช้คำสั่ง ดังนี้

php -S localhost:8000 index.php

จากนั้นเปิด browser ไปที่ http://localhost:8000 จะเจอหน้าตาแบบนี้

ซึ่งเมื่อเรา Deploy ไปอยู่บน AWS Lambda ขั้นตอนของ bref จะทำการ upload ไป S3 และ deploy ไป Lambda เหมือนกับกรณี PHP Function แต่เพิ่มเติมคือ จะไปทำการสร้าง API Gateway ให้ด้วย เพื่อเป็นช่องทางการ access เข้าไปใช้งาน ไม่ว่าจะเป็น Website หรือ API (ให้ดูที่ endpoints)

ถ้าลองเปิด url ดูแล้วก็จะได้เหมือนกับที่ลองใน localhost

ส่วนผลการทดสอบความเร็ว จะไม่สามารถ invocation ได้นะครับ ต้องเปิดผ่าน API Gateway เท่านั้น

ผมลองดู SPeed Network ด้วย Chrome แต่ความเร็วที่ได้ มันผ่าน stack ชั้น API Gateway ก่อน เลยทำให้ไม่รู้ว่า AWS Lambda จริงๆทำงานเร็วแค่ไหน แต่ผลลัพธ์ที่ได้ อยู่ราวๆ 80-100ms ถือว่าเร็วเลยหละ

วิธีการลบ PHP Serverless Application บน AWS Lambda

ผมแนะนำว่าให้ใช้คำสั่งแทนนะครับ เพราะการไปลบบน AWS Lambda อย่างเดียว อาจจะไม่ครบ อาจจะต้องไปตามหาใน S3, CloudFormation, API Gateway และอาจจะหลายสิ่ง จึงแนะนำให้ใช้คำสั่งของ serverless แทน ดังนี้ครับ

serverless remove

อยากลบตัวไหน ให้เข้าไปที่ folder ของ application นั้น มันจะทำการลบตามที่เรา config ในไฟล์ serverless.yml ครับ

สรุป

ถ้าใครอยากทำ Serverless ด้วย PHP และ AWS Lambda ผมแนะนำให้ใช้ bref เลยครับ ค่อนข้างสะดวก ส่วนเรื่องความเร็วที่ได้ถือว่าประทับใจ เมื่อเทียบกับ .NET Core (ใน Memory เท่ากัน) แต่ก็ยังช้ากว่า Node.js, Go, Python

ข้อสังเกต

  1. Default Memory คือ 1024MB ระวังให้ดีว่าจะเผลอเสียเงินเยอะโดยใช้เหตุครับ
  2. Default Timeout คือ 6 วินาที
  3. ไม่พบ Cold Start จากการ run ครั้งแรก เพราะครั้งต่อๆ ไป ก็ยังทำงานด้วยเวลาพอกัน

ตัวอย่างโค้ด