nginx

จาก blog ที่ผ่านมา สรุปสถาปัตยกรรมแบบ Realtime ของระบบ Disqus
แล้วพบว่าสิ่งที่นำมาพัฒนาระบบนั้นน่าสนใจมาก
โดยส่วนที่ผมสนใจก็คือ Nginx + push stream module
ใช้สำหรับการพัฒนาระบบ Realtime ในรูปแบบ  publish/subscribe
ดังนั้นมาลองกันหน่อยว่าจะใช้งานมันอย่างไร

เริ่มต้นด้วยโครงสร้างของ Publish/Subscibe ดังรูป

โครงสร้าง Publish Subscribe

นำรูปมาจาก http://msdn.microsoft.com/en-us/library/ff649664.aspx

เรียกอีกชื่อว่า Producer และ Consumer
Publish เป็นผู้ทำการส่งข้อมูลกระจายไปยังผู้ที่ทำการ Subscribe ไว้ทั้งหมด
ตามช่องทางหรือ channel หรือในระบบ messaging คือ Topic นั่นเอง
เป็นการส่งข้อมูลแบบ one-to-many

ต่อมาทำการติดตั้ง Nginx + Push stream module

รายละเอียดของ Software ที่ใช้งาน

  • OS :: Ubuntu 12.04  ใน VirtualBox
  • PCRE Library ( Perl 5 Compatible Regular Expression Library )

ขั้นตอนการติดตั้งเป็นดังนี้
Download Nginx 1.6 มาจาก http://nginx.org/
แล้วทำการ extract ซะ หรือจะใช้ wget ก็ได้ดังนี้

$wget http://nginx.org/download/nginx-1.6.0.tar.gz
$tar -xzvf nginx-1.6.0.tar.gz

แล้วทำการ Download Push stream module มาดังนี้

$git clone http://github.com/wandenberg/nginx-push-stream-module.git

 

และทำการกำหนด environment variable เพื่อกำหนด path ของ module นี้
เพื่อให้ใช้งานง่ายๆ  ดังนี้

$export NGINX_PUSH_STREAM_MODULE_PATH=$PWD/nginx-push-stream-module

เมื่อทุกอย่างเรียบร้อย เข้าสู่ขั้นตอนการติดตั้งดังนี้

$cd nginx-1.6.0
$./configure --add-module=../nginx-push-stream-module
$make
$sudo make install

ถ้าไม่มี error อะไรในการติดตั้ง ให้ทำการตรวจสอบดังนี้

$sudo /usr/local/nginx/sbin/nginx

เป็นคำสั่งเพื่อ start service ของ Nginx
ให้ทำการเปิด browser และเข้าไปที่ url ด้วย IP ของเครื่อง
จากตัวอย่างผมใช้ IP=192.168.1.35 เป็นดังรูป

Screen Shot 2557-05-01 at 10.48.02 PM

หรือสามารถตรวจสอบเวอร์ชันของ nginx ด้วยคำสั่ง

$sudo /usr/local/nginx/sbin/nginx -v

จากนั้นมาถึงสิ่งที่เราต้องการจริงๆ ก็คือ Push stream module

เริ่มด้วยการตรวจสอบด้วย configuration file ที่มากับกับ module อยู่แล้ว
ซึ่งจะไม่แก้ไขใดๆ ทั้งสิ้น ด้วยคำสั่งดังนี้

$sudo /usr/local/nginx/sbin/nginx -c $NGINX_PUSH_STREAM_MODULE_PATH/misc/nginx.conf -t

ผลการทำงานที่ได้ต้องเป็นลักษณะนี้
the configuration file $NGINX_PUSH_STREAM_MODULE_PATH/misc/nginx.conf syntax is ok
configuration file $NGINX_PUSH_STREAM_MODULE_PATH/misc/nginx.conf test is successful

เมื่อทุกอย่างเรียบร้อยให้ Start service nginx ด้วย configuration file ข้างต้น ดังนี้

$sudo /usr/local/nginx/sbin/nginx -c $NGINX_PUSH_STREAM_MODULE_PATH/misc/nginx.conf

ถ้าเข้าไปดูใน configuration file จะพบว่า port ที่เปิดให้ใช้คือ 9080

Screen Shot 2557-05-01 at 10.56.11 PM

ไม่รอช้าลองใช้งาน Pub/Sub กันดีกว่า

ทำการทดลองใช้งานผ่าน curl ก่อน ดังนี้

1. ทำการสร้าง channel หรือ topic
สำหรับให้ผู้ใช้งาน หรือ subscriber มาติดต่อ
เพื่อขอรับข้อมูล
จากตัวอย่างจะสร้าง 3 channel คือ ch1, ch2 และ ch3 ดังนี้

curl -s -v 'http://192.168.1.35:9080/sub/ch1'
curl -s -v 'http://192.168.1.35:9080/sub/ch2'
curl -s -v 'http://192.168.1.35:9080/sub/ch3'

ผลการทำงานของแต่ละ channel จะเป็นดังรูป

Screen Shot 2557-05-01 at 11.02.28 PM

2. ทำการ publish ข้อมูลไปยัง channel ต่างๆ
ผ่าน curl เช่นเดิม ดังนี้

curl -s -v -X POST 'http://192.168.1.35:9080/pub?id=ch1' -d 'message for ch1'
curl -s -v -X POST 'http://192.168.1.35:9080/pub?id=ch2' -d 'message for ch2'
curl -s -v -X POST 'http://192.168.1.35:9080/pub?id=ch3' -d 'message for ch3'

ผลการทำงาน เป็นดังรูป

Screen Shot 2557-05-01 at 11.07.03 PM

ผลการทำงานจะตอบกลับมาเป็นข้อมูลรูปแบบ JSON

  • อธิบายข้อมูลของแต่ละ channel
  • จำนวนข้อมูลที่ถูกส่งออกไป
  • จำนวนข้อมูลที่ถูกบันทึก
  • และจำนวน sunsciber ที่ติดต่ออยู่กับ channel นั้นๆ จากตัวอย่างจะมี 2 connection

3. มาลองดูสถิติต่างๆ ว่ามีอะไรให้ใช้บ้าง
ดูสถิติของการ publish ของแต่ละ channel ด้วยคำสั่ง

$curl -s -v 'http://192.168.1.35:9080/pub?id=ch1'
$curl -s -v 'http://192.168.1.35:9080/pub?id=ch2'
$curl -s -v 'http://192.168.1.35:9080/pub?id=ch3'

สามารถดูเพิ่มติมได้จากที่ Nginx Push Stream Module

มาสร้าง Web application กันดีกว่า

เมื่อทดลองใช้งานผ่าน curl แล้วไม่มีปัญหาอะไร
ต่อไปเราจะสร้าง web application เล็กๆ ไม่เช่นนั้นจะไม่เห็นภาพ
ให้ทำการติดต่อกับ nginx + push stream ที่เราสร้างไว้

ในตัวอย่างใช้ JavaScript เพื่อติดต่อไปยัง Nginx ด้วย class PushStream
เป็น class ที่หุ้มการทำงานกับ WebSocket, EventSource, Stream และ LongPolling
เพื่ออำนวยความสะดวกต่อการใช้งาน

แต่ถ้าไม่อยากใช้ก็ไปหา library อื่นๆ ได้เช่นกัน
หรือใช้งาน WebSocket ที่อยู่ใน browser ก็ได้ครับ

ตัวอย่างการใช้งาน จะเปิด connection ไปยัง channel ชื่อว่า ch1 ดังนี้

จากนั้นให้ทำการเปิดไฟล์ผ่าน browser
เปิด browser มา 3 หน้าต่าง และทำ publish ข้อมูลเข้าไปยัง channel ชื่อ ch1
ผลการทำงานดังนี้

Screen Shot 2557-05-01 at 11.25.27 PM

เพียงเท่านั้น เราก็สามารถสร้างระบบแบบ Realtime ด้วย nginx + push stream module แบบง่ายๆ ได้แล้ว …

สรุปจากการทดลอง

จากการทดลองใช้งานพบว่า สามารถเริ่มต้นติดตั้งได้ง่าย
สร้างระบบแบบ Realtime ได้ง่ายดี
โดยไม่ต้องใช้ความสามารถอะไรมากนัก
แต่ต้องเข้าใจแนวคิดของ module นี้ก่อนนะ

ส่วนอื่นๆ ที่ยังต้องศึกษาต่อไป คือ การ configuration และ tuning ต่างๆ
รวมไปถึงการทดสอบ performance

ส่วนการนำไปใช้งาน น่าจะต้องมีระบบ queue มาช่วย
เพื่อ integrate เข้ากับระบบอื่นๆ ซึ่งมีลักษณะเช่นเดียวกับที่ Disqus ใช้งาน

โดยรวมถือว่า ตอบโจทย์มากพอสมควร สำหรับการพัฒนาระบบแบบ Realtime ครับ

ตัวอย่าง code อยู่ที่ Github