0147 | PHP Fatal error: Out of memory

Tuesday, February 5th, 2013 Posted in Linux, PHP Coding, Web Server | No Comments »

Fatal error: Out of memory (allocated 4194304) (tried to allocate 14156 bytes) in /var/www/html/script.php on line 123

เชื่อว่าคนทำเว็บที่ใช้ PHP หลายๆ คนคงเคยเจอปัญหานี้มาไม่มากก็น้อยกันอยู่ช่าม้า (แบ๊วซะ) หลายๆ คนเห็น error อันนี้แล้วก็ไปเข้าใจผิดว่า server แรมหมดอะไรงี้ด้วย เดี๋ยวจะมาอธิบายให้ครับ

  • Error นี้ไม่ได้เกี่ยวห่าอะไรเลยกับ RAM ของ server หมดครับ การ reboot เครื่องหรือ upgrade spec ของ VPS ของท่านไม่ได้ช่วยให้อาการนี้หายแต่อย่างใด
  • มันคือ Error ที่มาจากระบบจัดการการใช้ Memory ของ PHP เอง (ตั้งใน php.ini ชื่อ option ว่า memory_limit)
  • มันกำลังบอกว่า เจ้าของ server ตั้งจำกัดการใช้งาน Memory ของ PHP ไว้ (allocated ***) bytes
  • และมันบอกว่า script ใช้จนเต็ม limit ไปแล้ว แต่จะขอใช้เพิ่มอีก (tried to allocate *** bytes)
  • พอใช้เกิน limit ของที่ตั้งไว้ใน php.ini PHP ก็เลยสั่งตัดการทำงาน พร้อมกับพ่น error นั่นออกมา

ความจริง option นี้มีประโยชน์มากสำหรับ shared hosting เพื่อป้องกันไม่ให้มี script ใดๆ สามารถใช้งานแรมจนหมดได้… (อาจจะเกิดจากเขียน code ผิด หรืออะไรก็แล้วแต่) แต่การตั้งค่านี้ต่ำไปก็มีผลกระทบกับ CMS ที่เขียนมาไม่ดี และมีการใช้ทรัพยากรหนักๆ ครับ (WordPress / Joomla เป็นต้น)

ค่า memory_limit ของ PHP เนี่ย เท่าที่ใช้งานมาไม่ควรตั้งต่ำกว่า 8M (8388608) ครับ และสำหรับการใช้งาน CMS อย่าง wordpress หรือ joomla ที่ call stack ไม่รู้จะยาวไปหาอะไร แนะนำให้ตั้งที่ไม่ต่ำกว่า 64M (67108864) ครับ

Tags: ,

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: , , ,