แสดงบทความที่มีป้ายกำกับ PHP แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ PHP แสดงบทความทั้งหมด

วันจันทร์ที่ 29 สิงหาคม พ.ศ. 2554

การ downgrade php เป็นรุ่น 5.2.x ใน Debian 6.0 (Squeeze)

เมื่อติดตั้ง Debian 6.0 จะได้ php5 เป็นรุ่น 5.3.x ซึ่งมีคุณสมบัติบางประการต่างไปจากรุ่นเดิมคือ 5.2.x (อ่านเพิ่มเติมที่ http://php.net/manual/en/migration53.php) ซึ่งในบางครั้งเรายังจำเป็นต้องใช้รุ่นเดิมอยู่ เช่นยังใช้ drupal 5.x ซึ่งยังใช้ไม่ได้กับ php 5.3 (ต้องเป็น drupal รุ่น 6.x ตัวหลังๆ หรือ drupal 7.x) สามารถเลือกติดตั้ง php5 จาก oldstable หรือ Debian 5.0 (lenny) โดยทำได้ดังนี้

เพิ่ม repository ของ lenny เช่น จากเดิมใน /etc/apt/sources.list มี


deb http://ftp.th.debian.org/debian squeeze main non-free contrib
deb http://ftp.th.debian.org/debian-security squeeze/updates main non-free contrib

ให้เพิ่ม ของ lenny เข้าไปด้วย เป็น

deb http://ftp.th.debian.org/debian squeeze main non-free contrib
deb http://ftp.th.debian.org/debian-security squeeze/updates main non-free contrib
deb http://ftp.th.debian.org/debian lenny main
deb http://ftp.th.debian.org/debian-security lenny/updates main

แก้ไข (หรือสร้างไฟล์ใหม่) /etc/apt/preferences ใส่คอนฟิกดังนี้ลงไป

Package: php-* php5 php5-* libapache2-mod-php5 php-pear
Pin: release a=oldstable
Pin-Priority: 999

จากนั้นสั่ง

# apt-get update
# apt-get -f install

ระบบจะ downgrade แพกเกจ PHP ที่ติดตั้งไปแล้ว ที่อยู่ในรายการที่เรากำหนด ให้เป็นรุ่นที่อยู่ใน oldstable ตามต้องการ ถ้ายังไม่ติดตั้ง ก็ติดตั้งตามปกติ

และเมื่อไหร่ที่พร้อมที่จะอัพเกรด php เป็นรุ่น 5.3 ก็แก้ไฟล์ /etc/apt/preferences เอาคอนฟิกที่เพิ่มเข้าไป 3 บรรทัดนั้นออก แล้วสั่ง upgrade ตามปกติได้เลย

วันพฤหัสบดีที่ 13 กันยายน พ.ศ. 2550

drupal+debian กับปัญหาตาราง sessions โตขึ้นเรื่อยๆ

ที่เว็บไซต์ opentle.org ใช้ drupal กับ community ขนาดใหญ่พอสมควร ส่วน OS เปลี่ยนจากเดิมใช้ FreeBSD 6.2 มาเป็น debian 4.0 (etch) ได้สัก 9 เดือนเศษละ มีข้อสังเกตว่า ตั้งแต่เปลี่ยนเป็น debian ตาราง sessions ใหญ่ขึ้นเรื่อยๆ จนเป็นนับล้านเรคอร์ดในเวลาไม่กี่เดือน ทั้งๆ ที่ session.gc_maxlifetime ก็ตั้งไว้ราวๆ 24 วัน ต้องคอยล้างทิ้งเป็นระยะๆ ทีแรกนึกไม่ออกว่าเกิดจากอะไร ดูที่เว็บไซต์อื่นๆ ก็มีทั้งเป็นบ้าง ไม่เป็นบ้าง แต่ส่วนใหญ่ไม่รู้ว่ามีปัญหานี้ เพราะ session มีน้อย จนไม่รู้สึกอะไร ขณะที่ opentle นั้น แค่เดือนเดียวก็เห็นได้ชัดว่าตารางมันใหญ่ขึ้น

เดิมที่ไล่แกะดูการทำงานของตารางนี้คือ ปกติ php จะจัดการ session ด้วยตัวเอง ซึ่งจะสร้างเป็นแฟ้ม session ไว้ใน /var/lib/php5/ แต่ใน drupal จะจัดการ session ด้วยฐานข้อมูล คือเก็บลงตาราง sessions แล้วเขียน function มา handle ซึ่งดูรายละเอียดฟังก์ชันเหล่านี้ได้จาก includes/session.inc และกำหนดให้ใช้ฟังก์ชันเหล่านี้ในการจัดการ session ใน includes/bootstrap.inc ซึ่งก็ดูปกติดี โดยเฉพาะตรงฟังก์ชัน sess_gc() ซึ่งมีไว้เคลียร์ session ที่อายุเกิน maxlifetime ทิ้ง โดยการลบ record ทิ้งด้วยเงื่อนไข ก็ดูเรียบร้อยดี

วันนี้อยากเคลียร์ปัญหานี้ให้จบเลยแกะดูการทำงานต่อ เริ่มจากตรวจล็อกของ mysql พบว่า ไม่เคยมีคำสั่ง "DELETE FROM sessions ...." ถูกรันเลย แปลว่า sess_gc() ไม่เคยถูกเรียกใช้จาก php เลย คำถามจึงมีอยู่ว่า เมื่อไหร่ที่ php จะเรียกใช้ sess_gc() ทำให้ต้องย้อนไปแกะดูใหม่

เปิดดู php.ini อีกครั้ง (ก่อนนี้ก็เคยแกะดูแล้ว แต่ไม่พบอะไรผิดปกติ) คราวนี้เน้นไปที่เรื่อง gc ก็พบตรงนี้เข้า

; Define the probability that the 'garbage collection' process is started
; on every session initialization.
; The probability is calculated by using gc_probability/gc_divisor,
; e.g. 1/100 means there is a 1% chance that the GC process starts
; on each request.

; This is disabled in the Debian packages, due to the strict permissions
; on /var/lib/php5. Instead of setting this here, see the cronjob at
; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below
;session.gc_probability = 0
session.gc_divisor = 100

นั่นคือ ปกติ session.gc_probability = 1 จะทำให้ทุกครั้งที่ php ทำงาน จะมีโอกาส 1/100 ที่ gc ทำงาน หรือพอจะตีความว่า รัน php 100 ครั้ง gc จะถูกเรียก 1 ครั้งก็พอได้ แต่ใน debian ไม่ใช่อย่างนั้น debian จะ comment ค่านี้ไว้ ทำให้มีค่าเป็น 0 เสมอ gc จะไม่ถูกเรียกใช้งาน แต่จะมี cron สำหรับลบ session ที่หมดอายุแทน เหตุผลก็อธิบายไว้ใน comment แล้ว

ตรงนี้แหละคือปัญหา เพราะนั่นเท่ากับว่า sess_gc() ที่ drupal เตรียมไว้ให้ php เรียกใช้ จะไม่ถูกเรียกใช้เลย นั่นคือสาเหตุที่ opentle.org มีปัญหาดังกล่าว

การแก้ปัญหา


การแก้ไฟล์ php.ini ไม่ใช่ทางออกที่ดี ควรแก้ใน drupal ในไฟล์ sites/default/settings.php แทน โดยเพิ่ม

ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 100);

เข้าไป เท่านี้ก็เรียบร้อย ทิ้งไว้สักพัก session ก็ถูกจัดการได้ถูกต้องตามปกติแล้ว

วันพฤหัสบดีที่ 9 สิงหาคม พ.ศ. 2550

Setting up apache2-mpm-worker, mod-fcgid, php5-cgi on Debian Etch

เคยเจอปัญหาเว็บเซิร์ฟเวอร์เมื่อมีคนเข้าใช้เยอะๆ แล้วช้าลงมากๆ ไหม ทั้งๆ ที่ซีพียูก็แรง แรมก็มีไม่น้อย ปัญหามักจะเกิดขึ้นเมื่อเว็บเซิร์ฟเวอร์นั้นมี mod-php และบางครั้งมีไฟล์ static ใหญ่ๆ เช่นภาพถ่าย วิดีโอ ไฟล์พรีเซนต์ ไฟล์ดาวน์โหลดต่างๆ ให้ดาวน์โหลดผ่าน http

ปัญหามักเกิดจาก เมื่อเราใช้ mod-php ก็ต้องใช้ apache ที่ใช้ mpm-prefork ด้วย นั่นคือเมื่อมี connection เข้ามา apache ต้อง fork process เพื่อให้บริการ connection นั้นเป็นรายๆ ไป ปัญหาคือว่า mod-php ทำให้แต่ละ process มีขนาดใหญ่มาก ยิ่งเว็บแอ็พที่ใช้มีขนาดใหญ่ ยิ่งทำให้แต่ละ process ใหญ่เข้าไปอีก ปัญหาจะหนักขึ้น เมื่อต้องให้บริการดาวน์โหลดไฟล์ หรือมีรูปภาพจำนวนมากบนเว็บไซต์ด้วย เพราะแม้ว่าพวกนี้จะไม่ต้องการซีพียูในการประมวลผลมากนัก แต่การที่ apache ต้อง fork process มาเพื่อให้บริการไฟล์พวกนี้ ก็ทำให้ต้องเสีย memory มากขึ้นไปอีก ยิ่งเน็ตเวิร์คของไคลเอนต์ช้า ยิ่งทำให้ต้องใช้เวลาดาวน์โหลดนาน จะพบว่า จำนวน connection มีมากขึ้นเรื่อยๆ