0085 | DirectAdmin + mod_fcgid + php fastcgi

Saturday, November 14th, 2009 Posted in Linux, Web Server | 12 Comments »

ก่อนอื่น copy & paste ตามสูตร

cd /usr/local/src
wget http://mirrors.issp.co.th/apache/httpd/mod_fcgid/mod_fcgid-2.3.4.tar.bz2
tar jxf mod_fcgid-2.3.4.tar.bz2
cd mod_fcgid-2.3.4
APXS=/usr/sbin/apxs ./configure.apxs && make && make install
chmod 755 -R /var/lib/httpd
mkdir /fcgi

ไปที่ /usr/local/directadmin/custombuild/
เปิดไฟล์ options.conf แก้ php5_cgi=yes ส่วน php อันอื่น no ให้หมด
แล้วสั่ง ./build php จนเสร็จ

แล้วเปิดไฟล์ /etc/httpd/conf/extra/httpd-info.conf
เพิ่มไอ้นี่ต่อท้าย

LoadModule fcgid_module /usr/lib/apache/mod_fcgid.so
 
SharememPath /var/run/fcgid_shm
SocketPath /var/lib/httpd/fcgid/sock
 
 
 
<IfModule mod_fcgid.c>
  IdleTimeout 3600
  ProcessLifeTime 7200
  MaxProcessCount 128
  DefaultMaxClassProcessCount 4
  IPCConnectTimeout 60
  IPCCommTimeout 90
  DefaultInitEnv RAILS_ENV production
#  DefaultInitEnv PHP_FCGI_CHILDREN 4
#  MaxRequestsPerProcess 500
</IfModule>
 
<Directory "/home">
        AllowOverride All
        Options SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
        <IfModule sapi_apache2.c>
        php_admin_flag engine off
        </IfModule>
        <IfModule mod_php5.c>
        php_admin_flag engine off
        </IfModule>
</Directory>

เสร็จแล้วเข้าไป folder /usr/local/directadmin/data/templates
เปิดไฟล์ที่ขึ้นต้นด้วย virtual_host2*.conf (มีทั้งหมด 4 ไฟล์)
ใน section เดิมที่เป็น PHP ทั้งหมด ให้ comment ไว้ จะได้ประมาณนี้

|*if CLI="1"|
#               php_admin_flag engine |PHP|
#               <IfModule !mod_php6.c>
#                       php_admin_flag safe_mode |SAFE_MODE|
#               </IfModule>
#               php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f |USER|@|DOMAIN|'
|*endif|
|*if OPEN_BASEDIR="ON"|
#               php_admin_value open_basedir |OPEN_BASEDIR_PATH|
|*endif|
|*if SUPHP="1"|
#                suPHP_Engine |PHP|
#               suPHP_UserGroup |USER| |GROUP|
|*endif|

แล้วแทรกไอ้นี่เข้าไปด้านบนของไอ้เมื่อกี้

	<IfModule mod_fcgid.c>
		<Files ~ (\.fcgi)>
			SetHandler fcgid-script
			Options +FollowSymLinks +ExecCGI
		</Files>
	</IfModule>
	<IfModule mod_fcgid.c>
	<Files ~ (\.php)>
		SetHandler fcgid-script
		FCGIWrapper "/fcgi/|USER|/public_html/fcgid.sh" .php
		Options +ExecCGI
		allow from all
	</Files>
	</IfModule>

แล้วเข้าไป folder /usr/local/directadmin/scripts/custom/
สร้างไฟล์ชื่อ fcgid.sh ใส่ข้อมูลตามนี้

#!/bin/sh
export PHP_FCGI_MAX_REQUESTS=0
exec /usr/local/php5/bin/php-cgi

ใน folder เดียวกัน สร้างไฟล์ชื่อ domain_create_post.sh ใส่ข้อมูลตามนี้

#!/bin/sh
 
mkdir -p /fcgi/${username}/public_html
cp /usr/local/directadmin/scripts/custom/fcgid.sh /fcgi/${username}/public_html/fcgid.sh && chmod 0700 /fcgi/${username}/public_html/fcgid.sh
cp /usr/local/directadmin/scripts/custom/php.ini /fcgi/${username}/public_html/php.ini
perl -pi -w -e "s/PHPCFG_BASEDIR/\/home\/${username}\//g;" /fcgi/${username}/public_html/php.ini
chown -R ${username}:${username} /fcgi/${username}
echo "`date`  ${domain} created  " >> /var/log/directadmin/domain_create.log

แล้วสั่ง copy file php.ini มาใส่ไว้ใน /usr/local/directadmin/scripts/custom/php.ini
เปิดไฟล์ /usr/local/directadmin/scripts/custom/php.ini ที่ก๊อปมาเมื่อกี้ แล้วหา open_basedir
ซึ่งปกติมันจะ comment ไว้ ให้แก้เป็นประมาณนี้

open_basedir = PHPCFG_BASEDIR:/tmp:/var/tmp

เสร็จแล้วสั่ง chmod a+x /usr/local/directadmin/scripts/custom/*.sh

*** วิธีทั้งหมดไม่รับประกันผล และควรใช้กับเครื่องเพิ่งลงใหม่เท่านั้น

Tags: , , ,

0004 | PHP Memory Limit

Saturday, May 3rd, 2008 Posted in PHP Coding | No Comments »

Fatal error: Allowed memory size of 262144 bytes exhausted (tried to allocate 4864 bytes) in /path/to/script.php on line 1074

ข้อผิดพลาดนี้ (อันที่จริงก็ทุกอัน) คนทำเว็บคนไหนก็คงไม่ชอบให้มันขึ้นมาหรอกจริงมั้ยครับ
วันนี้จะมาอธิบายการทำงานของ memory limit นิดนึง…

การที่ error อันนี้ขึ้นมาเนี่ย มันกำลังพยายามบอกว่า
ก่อนหน้านี้ มีการขอใช้หน่วยความจำไปแล้วจนเกือบเต็ม 262144 byte (คือเหลือหน่วยความจำว่างๆ อีกไม่เยอะ)
แล้วมีการขอใช้เพิ่มอีก 4864 byte แต่พื้นที่หน่วยความจำที่เหลืออยู่ (ตามที่อนุญาตไว้) มีไม่พอให้ใช้
มันก็เลยต้องจบการทำงานลง เพราะหน่วยความจำหมด

นี่แหละครับคือหน้าที่ของ memory limit

ตัว memory limit มีไว้สำหรับจำกัดการใช้งานหน่วยความจำ ของ “ตัวแปร” ใน PHP ครับ
แบ่งเป็นตัวแปรจากระบบ (พวก $_SERVER $_GET $_POST $_ENV $_SESSION $_COOKIE)
พวกนี้กินอย่างมากก็ประมาณ 50 KB ครับ แล้วที่เหลือก็เป็นส่วนของการทำงานใน code ไป

เชื่อมั้ยครับว่าค่าที่เหมาะสมสำหรับเว็บทั่วไปอยู่ที่ “2M” เอง เพราะปกติเราก็ไม่ใช้อะไรเยอะแยะอยู่แล้ว
สำหรับเว็บที่มีการเรียกใช้ gd library (พวกที่มี captcha อะไรพวกนี้ด้วย) ควรปรับประมาณ 16-24 M
แล้วก็ เว็บฝากไฟล์…. ใช้เท่ากะเว็บปกติครับ (สำหรับส่วนของการ upload)
เนื่องจาก content ในไฟล์ ไม่ได้ถูกนำมาเก็บในหน่วยความจำครับ
ส่วนพวก CMS ต่างๆ เช่น joomla / mambo / phpnuke / wordpress / drupal พวกนี้ควรตั้งขั้นต่ำที่ 8M ครับ
แล้วก็พวก webboard เช่น SMF / IPB / vBullentin / phpBB ควรตั้งขั้นต่ำ 16M ครับ

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

$test = “”;
while (1) {
$test .= “more”;
}

ถ้าเกิดไม่มี memory limit นี่เครื่องพังแน่นอนครับ (ใช้แรมเกิน)
แต่กรณีปกติที่อาจจะเกิด คือเขียน script วนซ้ำ แล้วเงื่อนไขการวนซ้ำผิดพลาด
ทำให้เกิดการวนซ้ำไม่รู้จบ (infinite loop) จนมีการจองหน่วยความจำเพิ่มขึ้นเรื่อยๆ
แล้วสุดท้าย หน่วยความจำล้น (buffer overflow) เป็นเหตุให้โดน hack หรืออะไรต่างๆ ตามมาได้มากครับ

วิธีการตรวจสอบหน่วยความจำที่ใช้ไปแล้ว
ใน PHP จะมี function ตัวนึงครับ ไว้เรียกใช้เพื่อดูว่า
ตั้งแต่บรรทัดแรก จนถึง code บรรทัดที่เรียกคำสั่งนี้ ใช้ memory ไปแล้วเท่าไหร่

http://th.php.net/manual/en/function.memory-get-usage.php

ดูใน docs นะครับ ใช้ไม่ยากๆ

ปล. entry นี้อ้างอิงจากที่ > ThaiSEOBoard # ความงี่เง่าของ SLHost <

ปปล. entry นี้เขียน ปล. ก่อนเนื้อหาซะอีก

Tags: , ,