ZDK™
Life is short. Play more.
Live on OSX+Ubuntu seamlessly with VirtualBox
มันดีเยี่ยงนี้ 

การเขียน apache module เพื่อรันเว็บเฟรมเวิร์ก  -» apache mod

ก่อนจะพูดถึงอะไรอย่างละเอียดเกี่ยวกับ apache modนั้น สิ่งสำคัญที่จะต้องเข้าใจคือเว็บแอปพลิเคชั่นทั่วๆไปนั้นทำงานอย่างไร ในมุมมองของผู้ที่ต้องการจะติดต่อไปยังแอปพลิเคชั่นจนถึงเว็บเซิร์ฟเวอร์ เมื่อพูดทั่วๆไปแล้ว เว็บแอปพลิเคชั่นจะรับ HTTP request ผ่านทาง I/O channel เมื่อรับมาแล้วก็ทำกระบวนการอะไรต่างๆจนได้เอาท์พุตและส่งออกเป็น HTTP Response ให้ HTTP Client โดยแอปพลิเคชั่นจะทำงานแบบนี้เรื่อยไปจนกว่าจะมีคำสั่งให้สิ้นสุด ซึ่งจากกระบวนการดังกล่าวนั้นไม่ได้หมายความว่าเว็บแอปพลิเคชั่นจะคุยโดยใช้โปรโตคอล HTTP โดยตรง แต่เว็บแอปพลิเคชั่นนั้นมอง HTTP Request เป็นเพียงแค่ presentation layer ที่อยู่ในรูปแบบที่ตัวเองเข้าใจเท่านั้น

#เว็บแอปพลิเคชั่นที่คุยกับ HTTP clients ที่เราเห็นๆกันอยู่นั้น แบ่งวิธีการเซ็ตอัพได้ประมาณ วิธี

1. เว็บแอปพลิเคชั่นที่อยู่ใน แอปพลิเคชั่นเซิร์ฟเวอร์ เช่น J2EE - Apache Tomcat เป็นต้น

   กรณีนี้ เว็บเซิร์ฟเวอร์ จะส่ง request ต่อให้ แอปพลิเคชั่นเซิร์ฟเวอร์ แล้ว แอปพลิเคชั่นเซิร์ฟเวอร์ จะเป็นตัวจัดการคุย/ส่งต่อในรูปแบบที่เว็บแอปพลิเคชั่นเข้าใจ หลังจากนั้นเมื่อเว็บแอปพลิเคชั่นทำงานเสร็จเรียบร้อยก็จะส่งเอาท์พุตกลับให้ แอปพลิเคชั่นเซิร์ฟเวอร์เว็บเซิร์ฟเวอร์ -» HTTP client ต่อไปตามลำดับ

2. เว็บแอปพลิเคชั่นที่อยู่ใน เว็บเซิร์ฟเวอร์ เช่น mod_php เป็นต้น

   กรณีนี้ เว็บเซิร์ฟเวอร์ จะทำตัวเหมือน แอปพลิเคชั่นเซิร์ฟเวอร์ เป็นลักษณะการทำงานของ PHP เว็บแอปพลิเคชั่นที่เห็นๆกัน โดย เว็บเซิร์ฟเวอร์ จะเป็นตัวจัดการแอปพลิเคชั่น

3. เว็บแอปพลิเคชั่นที่เป็น เว็บเซิร์ฟเวอร์ คุย HTTP โดยตรง หรืออาจจะมี reverse proxy มาช่วย เช่น ระบบ Trac bug tracking เป็นต้น

4. เว็บแอปพลิเคชั่นที่คุยกับ เว็บเซิร์ฟเวอร์ ผ่านเกตเวย์หรือ adapter เช่น CGI, FastCGI และ SCGI เป็นต้น

จากทั้งแบบที่กล่าวมานั้นมีจุดประสงค์เดียวกันก็คือต้องการให้รันเว็บแอปพลิเคชั่นให้ทำงานได้ รับ request และ reponse เอาต์พุตได้  ให้ทำงานได้เหมือนๆกันได้ ไม่ว่าจะเซ็ตอัพมาแบบใดก็ตาม

และน่าจะครอบคลุมวิธีการเซ็ตอัพของเว็บแอปพลิเคชั่นที่มีอยู่ในตลาดทุกวันนี้ได้ ไม่ว่าจะเป็น PHP, Django, J2EE, ASP.NET, เว็บเฟรมเวิร์ก หรืออะไรก็ตามก็ไม่น่าจะพ้น แบบนี้

ถ้าหากเรามองชุด เว็บเซิร์ฟเวอร์, แอปพลิเคชั่นเซิร์ฟเวอร์ และ เว็บแอปพลิเคชั่น เป็นหน่วยประมวลผลหน่วยนึง ก็จะเห็นว่าทั้ง แบบก็จะเหมือนกันหมด

ไม่ว่าจะเซ็ตอัพแบบใดๆ ก็ไม่จำเป็นต้องทำระบบการประมวลผล I/O แบบพิเศษขึ้นมา โดย เว็บเซิร์ฟเวอร์, แอปพลิเคชั่นเซิร์ฟเวอร์ และเว็บแอปพลิเคชั่น สามารถที่จะโปรเซส I/O ไปตามลำดับ(Serial) ต่อหนึ่ง Request, สามารถ multiplex I/O แบบ synchronous (select, poll) เป็น single thread หรือจะโปรเซส I/O แบบ muti-thread/multi-โปรเซส ก็ได้โดยมี load balancer คอยช่วย สรุปก็คือแล้วแต่จะเซ็ตอัพทำได้หมด

# เว็บเฟรมเวิร์ก

เว็บเฟรมเวิร์กแอปพลิเคชั่นเกือบทุกตัวนั้นจะมีส่วนที่เรียกว่า "dispatcher" อยู่ dispatcher นั้นจะทำหน้าที่ประมวลผล HTTP Request ที่รับเข้ามา (แต่ไม่ได้คุยด้วย HTTP โดยตรง)

แต่จะรับโครงสร้างข้อมูล (ที่ประกอบไปด้วยข้อมูลเกี่ยวกับ HTTP request) ดังนั้น dispatcher เปรียบเสมือนเป็นตัวกลางที่คอยติดต่อระหว่าง เว็บเฟรมเวิร์ก และ เว็บเซิร์ฟเวอร์

เมื่อพูดถึงเว็บเฟรมเวิร์กตัวที่ไม่ได้เป็น thread-safe  ตัว dispatcher ของเว็บเฟรมเวิร์กนั้นสามารถประมวลผล request ตามลำดับได้ ครั้งละหนึ่ง request ถ้าจะให้ประมวลผลหลายๆ request พร้อมๆกันโดยแตก threads ไม่สามารถทำได้  (แต่เราสามารถจัดการ concurrrent request ด้วยวิธีอื่นได้) บางเว็บเฟรมเวิร์กอาจจะใช้เวลาในการ start-up นาน เนื่องจากเสียเวลาพอสมควรไปในส่วนของ bootstrap

# Apache 

สถาปัตยกรรมของ Apache เว็บเซิร์ฟเวอร์ นั้นออกแบบมาให้รองรับระบบ I/O มัลติโปรเซสซิ่งสามารถที่จะรับ request จาก HTTP client ได้พร้อมๆกันหลายๆตัว

โดยระบบโมดูลของ Apache นั้นมีเฉพาะที่เรียกว่า MPM (Multi-Processing Module) โดยค่าปริยายจะเซ็ตให้ใช้ MPM ที่เรียกว่า prefork MPM ซึ่งเป็นตัวที่นิยมที่สุดโดย MPM จะแตโปรเซสลูกเป็นโปรเซส ย่อยๆไว้ทำงาน เรียกว่า worker โปรเซส ลักษณะการทำงานก็จะเป็นการรับ HTTP request มาโดย control โปรเซส แล้วก็จะส่งต่อไปยัง worker โปรเซส

#การออกแบบ apache mod

- การ spawning และ caching ของโค้ดและแอปพลิเคชั่น

ทำการเขียน apache modไปต่อขยาย apache และให้ apache ทำตัวเหมือนแอปพลิเคชั่นเซิร์ฟเวอร์ โดยจะจัดให้โมดูลนี้ให้ทำงานอยู่ใน apache control โปรเซส และทำงานอยู่ใน worker โปรเซส ทั้งหมดเมื่อมี HTTP request เข้ามา ตัวโมดูล apache modก็จะทำการเช็คว่ามี request ไหนที่ควรจะถูกจัดการด้วยเว็บเฟรมเวิร์ก  ซึ่งถ้ามี ตัว apache modก็จะ "spawn" ตัวเฟรมเวิร์กแอปพลิเคชั่น (เท่าที่จำเป็น) แล้วก็จะส่งต่อ http request มายังแอปพลิเคชั่น

เว็บเฟรมเวิร์กแอปพลิเคชั่นนั้นมีข้อแตกต่างกับวิธีเซ็ตอัพแบบที่สองของ mod_php (รวมทั้ง mod_perl, mod_ruby ) คือ เว็บเฟรมเวิร์กแอพพลิเคชั่นจะรันอยู่นอกส่วน address ของ Apache ที่ใช้รัน

ด้วยเหตุนี้ถ้า เว็บเฟรมเวิร์กแอปพลิเคชั่น เกิด crash หรือมีปัญหาก็จะไม่มีผลกระทบต่อโปรเซสของ apache ทำให้มีความเสถียรสูง

วิธีที่ง่ายที่สุดในการ implement คือการ spawn เว็บเฟรมเวิร์กแอปพลิเคชั่น ทุกๆ request ที่เข้ามา เหมือนอย่างที่ CGI ทำ แต่วิธีนี้ย่อมส่งผลเสียแน่นอนสำหรับ เว็บเฟรมเวิร์กแอปพลิเคชั่นที่มีขนาดใหญ่ มีโอกาสที่จะได้เวลา 1-2 วินาทีบนเครื่องที่แรงๆ และเป็นไปได้ว่าจะนานกว่านี้ถ้าเป็นเครื่องที่มีโหลดเยอะๆ ซึ่งเป็นสิ่งที่รับไม่ได้แน่นอนสำหรับการทำ shared host

ส่วนอีกวิธีหนึงที่ดีขึ้นมาหน่อยก็คือการทำให้ เว็บเฟรมเวิร์กแอปพลิเคชั่น instance ทีถูก spawn นั้นคงอยู่ไปเรื่อยๆ ซึ่งคล้ายๆกับหลักการทำงานของ FastCGI ของ Lighttpd แต่วิธีนี้ก็ยังมีปัญหาตามมาอีก

1. Request แรกที่เข้ามาในแต่ละเว็บเฟรมเวิร์กแอปพลิเคชั่น ก็จะยังช้าอยู่ แต่ request ต่อๆไปจะเร็วขึ้น (เช่น เว็บpassenger)

2. อย่างที่กล่าวไว้ข้างต้นนั้น เว็บเฟรมเวิร์กแอปพลิเคชั่นนั้นใช้พื้นที่ในหน่วยความจำส่วนนึงในการเก็บโค้ดของเฟรมเวิร์กและแอปพลิเคชั่นขณะรัน ดังนั้นการที่จะรันบนเครื่องที่มีข้อจำกัดเรื่องของหน่วยความจำนั้นย่อมจะมีปัญหาตามมา

ซึ่งสองปัญหานี้จริงๆแล้วก็พอมีทางแก้ได้ไม่ยากนัก

โดยปัญหาแรกคือเราอาจจะทำการโหลดเว็บเฟรมเวิร์กแอปพลิเคชั่นไว้ก่อนที่จะมี request เข้ามา ปัญหา request แรกช้าก็จะหมดไป

ส่วนอย่างที่สองนั้น

ทำโดยสร้างระบบจะมี spawn เซิร์ฟเวอร์ คอย spawn เว็บเฟรมเวิร์กแอปพลิเคชั่น ซึ่ง spawn เซิร์ฟเวอร์ นั้นจะ cache ตัว เว็บเฟรมเวิร์กโค้ด และ แอปพลิเคชั่นโค้ด ไว้ในหน่วยความจำ ขั้นตอนในการ spawn นี้จะช้าเฉพาะในครั้งแรก หลังจากนั้นก็จะเร็วเป็นปกติ โดย เฟรมเวิร์กโค้ด นั้นจะ cache เก็บไว้แยกต่างหากจาก แอปพลิเคชั่นโค้ด ดังนั้นระบบที่มีหลาย แอปพลิเคชั่น ก็จะ spawn ได้เร็วขึ้น (หากใช้เว็บเฟรมเวิร์กเวอร์ชั่นเดียวกัน ที่ cache ไว้แล้ววิธีการใช้ spawn เซิร์ฟเวอร์ แบบนี้นั้นเป็นการแก้ปัญหาในการเก็บโค้ดในหน่วยความจำ โดยมีการใช้ร่วมกันระหว่างหลายๆ แอปพลิเคชั่น

แต่ถึงแม้ว่าจะมีการ cache ตัว เฟรมเวิร์กโค้ด, แอปพลิเคชั่นโค้ด แล้วการ spawn ก็ยังใช้เวลามากเมื่อเทียบกับ HTTP request ที่เข้ามา 

 ดังนั้นเราจึงต้อง spawn ต่อเมื่อจำเป็นเท่านั้น โดยทำการสร้าง แอปพลิเคชั่น pool ขึ้นมา แอปพลิเคชั่น instance ที่่ถูก spawn นั้นจะถูก keep alive ไว้ โดยจะทำการเก็บสิ่งที่เคยจัดการมาแล้วใส่ไว้ใน แอปพลิเคชั่น pool เพื่อให้ แอปพลิเคชั่น instance แต่ละตัวสามารถทำไปใช้ใหม่ได้ต่อไป 

แอปพลิเคชั่น pool นั้นถูกแชร์ระหว่าง worker โปรเซส เนื่องจากหน่วยความจำของแต่ละ worker โปรเซส นั้นไม่สามารถ share ร่วมกันได้ แต่จะต้องสร้างเป็น share memory หรือเป็นลักษณะของ client/เซิร์ฟเวอร์  

 ซึ่งการ implement client/เซิร์ฟเวอร์ นั้นดูจะง่ายกว่า โดยให้ แอปพลิเคชั่น apache control โปรเซส ทำตัวเสมือน เซิร์ฟเวอร์ ให้กับ แอปพลิเคชั่น pool อย่างไรก็ตามไม่ได้หมายความว่าทุกๆ http request/response นั้นต้องผ่าน control โปรเซส

 Worker โปรเซส จะคอยถาม แอปพลิเคชั่น pool เพื่อขอ session สำหรับการติดต่อกับ เว็บเฟรมเวิร์กแอปพลิเคชั่น เมื่อได้ session แล้วครั้งต่อๆไปก็จะติดต่อกับ เว็บเฟรมเวิร์กแอปพลิเคชั่น โดยตรง  แอปพลิเคชั่น pool นั้นถูก implement ใน apache modแอปพลิเคชั่น pool มีหน้าที่ดูแลการ spawn แอปพลิเคชั่น, caching handle ของ spawned แอปพลิเคชั่น, clean idle แอปพลิเคชั่น

# Spawn เซิร์ฟเวอร์

ประกอบด้วยสามส่วนคือ

-ส่วน spawn เมเนเจอร์ ทำหน้าที่คล้ายๆพรอกซี่ เป็นหน้าด่านรับการติดต่อเข้ามาของ client   spawn เมเนเจอร์ จะ spawn เฟรมเวิร์ก spawner เซิร์ฟเวอร์ (เฟรมเวิร์กแต่ละเวอร์ชั่น)

spawn request สำหรับแอปพลิเคชั่นจะถูกส่งต่อไปยัง เฟรมเวิร์ก spawner เซิร์ฟเวอร์ ที่มีเฟรมเวิร์กเวอร์ชั่นที่ถูกต้องสำหรับแอปพลิเคชั่นนั้นๆ

-ส่วนแอปพลิเคชั่น spawner เซิร์ฟเวอร์ นั้นจะคุยกับ frawework spawner เซิร์ฟเวอร์ (ในลักษณะคล้ายๆกับ เฟรมเวิร์ก spawner เซิร์ฟเวอร์ คุยกับ spawner เมเนเจอร์)

-ส่วนเฟรมเวิร์ก spawner  เซิร์ฟเวอร์ จะ spawn แอปพลิเคชั่น spawner เซิร์ฟเวอร์ นั่นคือจะทำการ cache code ของแต่ละ แอปพลิเคชั่น

นั่นคือเราจะมีสองเลเยอร์ของการ caching code เมื่อ spawn เซิร์ฟเวอร์ ได้รับ request เพื่อจะ spawn แแอปพลิเคชั่น instance ใหม่นั้น

spawn เซิร์ฟเวอร์ จะส่งต่อ request ไปยัง เฟรมเวิร์ก spawner เซิร์ฟเวอร์ ที่ถูกต้อง (ถ้า เฟรมเวิร์ก spawner เซิร์ฟเวอร์ จะไม่ได้ spawn ก็ทำการ spawn ก่อน

เช่นเดียวกันก็จะทำการส่งต่อ request ไปยัง แอปพลิเคชั่น spawner เซิร์ฟเวอร์ ที่ถูกต้อง (ถ้า แอปพลิเคชั่น spawner เซิร์ฟเวอร์ จะไม่ได้ spawn ก็ทำการ spawn) ซึ่งแต่ละเลเยอร์นั้นจะรู้จักกันเฉพาะเลเยอร์ที่ติดกันเท่านั้น

อย่างไรก็ตาม แอปพลิเคชั่นเซิร์ฟเวอร์ ไม่ได้เป็นตัวจัดการ spawned แแอปพลิเคชั่น instance ถ้า แแอปพลิเคชั่น instance นั้นถูก spawn จาก mod_apache modแล้ว ข้อมูลต่างๆของ instance จะถูกส่งกลับไปให้ mod_apache modซึ่ง apache modจะจัดการ แแอปพลิเคชั่น instance (life-time) เอง ผ่าน แอปพลิเคชั่น pool

ทั้งนี้แต่ละเลเยอร์นั้นจะแยกโปรเซสกัน เนื่องจาก Ruby โปรเซสสามารถโหลด เว็บเฟรมเวิร์ก ได้ชุดเดียว แอปพลิเคชั่นlication ได้ชุดเดียว

# การแชร์หน่วยความจำ

Unix ตัวใหม่ๆ นั้น เมื่อมีการสร้าง child โปรเซสขึ้นมา จะมีการ share หน่วยความจำส่วนใหญ่ร่วมกับ parent โปรเซสด้วย

ความจริงแล้วแต่ละโปรเซสนั้นไม่ควรที่จะไปยุ่งกับหน่วยความจำของโปรเซสอื่นๆ ดังนั้น OS จึงมีกระบวนการที่เรียกว่า copy-on-write (COW) เป็นการทำสำเนาส่วนของหน่วยความจำเมื่อมีการถูกเขียนด้วย parent หรือ child โปรเซส ถ้าหากใช้เทคนิคนี้ซึ่งจะทำให้ลดการใช้หน่วยความจำไปได้อีกมาก

#การจัดการกับ concurrent requests

ตามที่ได้อธิบายได้ข้างต้นนั้น เว็บเฟรมเวิร์กแอปพลิเคชั่น instance แต่ละตัวนั้นรับได้แค่หนึ่ง request ต่อครั้ง ซึ่งไม่ใช่สิ่งที่ต้องการนัก ซึ่งถ้าเป็น PHP ซึ่ง สคริปต์ แต่ละตัวก็สามารถรับ HTTP request ได้หนึ่ง request ต่อครั้งเช่นเดียวกัน แล้วจะมีวิธีแก้ไขอย่างไรบ้าง

- mod_php แก้ปัญหานี้โดยการใช้ MPM ของ Apache สรุปก็คือ mod_php ไม่ได้อะไร แต่ได้ใช้ฟีเจอร์ของ Apache ในการ spawn worker โปรเซส/thread เมื่อมี request หลายๆตัวมาพร้อมๆกัน เป็นการ spawn php สคริปต์ โปรเซส

- PHP-FastCGI แก้ปัญหาโดยการ spawn persistent PHP เซิร์ฟเวอร์ หลายๆตัวโดย PHP เซิร์ฟเวอร์ ที่รันอยู่นั้นไม่ได้เกียวข้องกับ Apache worker โปรเซส/threads คล้ายๆกับ reverse proxy มายัง mongrel cluster

ถ้า apache modใช้วิธีเดียวกับ mod_php โดย spawn ทุกๆ request ที่เข้ามา อย่างที่กล่าวไป คงจะทำให้ช้าจนรับไม่ได้แต่ถ้าใช้เทคนิคเดียวกับ PHP-FastCGI โดยมี pool ของ แแอปพลิเคชั่น instance และเมื่อมี request เข้ามา ก็จะส่งต่อ request ไปยัง instance ใดตัวหนึ่งใน pool โดยสามารถ config ขนาดของ pool ให้เข้ากับหน่วยความจำของ เซิร์ฟเวอร์ ที่มีอยู่ได้

 

"If you pay a prostitute, you’re financing human trading."



ไม่สนับสนุนบริการทางเพศ

Pretty cake ..

top-10-reasons-why-employees-leave-in-it
Just another idea. Though it seems telling you good points.

Cool sound in the ads!


The very nature of working to some level of anxiety, nervousness or tension, just as we feel for any important event that occurs in our lives. Yes, a little bit of anxiety or stress can be a good thing. It helps us with motivation, and makes achievement just that much sweeter. (Some people often exploit it)
However, too much stress can be a problem; especially if it hinders our ability to function and perform.
Be certain to get a good amount of sleep because when you’re overtired you are not able to perform to the best of your best ability.

If you do manage something, managing time poorly, and not scheduling enough of your time or other people to work, and therefore cramming the night. So it will create the sensation that there is not enough time to do everything.

Basically, there are three primary elements to make difficulty or inability to organize thoughts to a coherent form.
1. Physical components, which involve the same typical bodily reactions as those to acute anxiety.
2. Emotional factors have to do with fear or panic.
3. Mental or cognitive issues concerning attention spans and memory abilities.

Some kinds of wall



Probably, fine answer means project is going well for someone, but for real worker it might mean something else.