หาว่า Code PHP ส่วนไหนทำงานช้าด้วย Xdebug PHP Extension by

31
Oct
0

เคยเจอปัญหา Code PHP ทำงานช้าโดนไม่ทราบสาเหตุไหม? แถมเราไม่รู้อีกตะหากว่าไฟล์ไหน บรรทัดที่เท่าไหร่ทำงานช้า จะให้ไปไล่ Code ด้วยมือก็ Code มีเป็นหมื่นเป็นแสนบรรทัด ไม่รู้จะเริ่มยังไงกว่าจะหาเจอ แถมดันช้าเฉพาะบน Server Production อีกตะหาก แต่ชีวิต PHP Developer ก็ไม่ได้ยากขนาดนั้นหากเรารู้จัก Tools ตัวนี้ มันชื่อว่า Xdebug ครับ เป็น PHP Extension นั่นเอง วิธีลงก็แสนง่ายดาย

sudo apt-get install php-xdebug

แค่นี้จบ (Debian/Ubuntu นะ) แต่ถ้าคุณใช้ Linux OS เก่าๆ หน่อย สั่งแล้วหา package ไม่เจอ ก็อาจจะต้อง Download มา compile ด้วย phpize เองดังนี้

  1. Download version ล่าสุดที่เว็บ Xdebug (เขียนว่า source)
  2. tar -xvzf xdebug-x.x.x.tgz (เปลี่ยนชื่อไฟล์ตามเวอร์ชั่นที่โหลดมา)
  3. cd เข้า dir ที่แกะ zip ออกมาตะกี้
  4. phpize
  5. ./configure
  6. make
  7. cp modules/xdebug.so

หลังจากลงเรียบร้อย (ไม่ว่าจะวิธีใดก็ตาม) แก้ไข php.ini โดยเพิ่มคำสั่งตามด้านล่าง (ถ้าลงผ่าน apt-get install อาจจะมีไฟล์ 20-xdebug.ini อยู่แล้ว ให้แก้ไขที่ไฟล์นั้นแทน php.ini)

zend_extension=xdebug.so // อันนี้สั่ง enable extension
xdebug.profiler_output_dir=<save_path> // อันนี้แก้ <save_path> เป็น path ที่เราจะเก็บไฟล์ profiler เอาไว้ write permission ต้อง write โดย user ที่รัน Process php ได้ ส่วนใหญ่จะเป็น www-data ถ้าขี้เกียจคิดมากก็ chmod 0777 <save_path> ไปเลย
xdebug.profiler_enable=0 // สั่ง enable ให้เซพไฟล์ profiler ตรงนี้ถ้ายังไม่ใช้ให้ใส่เป็น 0 ไปก่อน จะใช้เมื่อไหร่ค่อยปรับเป็น 1

** xdebug.profiler_enable นี้สำคัญมาก ไม่ควรใส่ 1 ตลอดเวลา ไม่อย่างนั้นพื้นที่ Harddisk คุณจะเต็มเร็วมาก!!

ก่อนจะใช้งานกับ Production Server ตัวจริงแนะนำให้ทดลองกับ Development Server ที่มีคนเข้าแค่คนภายในก่อน แล้วแก้ php.ini บรรทัด xdebug.profiler_enable=1 ครับ พร้อมเมื่อไหร่ก็สั่ง restart apache หรือ php-fpm (แล้วแต่ว่า server ใช้ตัวไหนอยู่) เพื่อให้ Xdebug เริ่มทำงาน แล้วให้ลองเข้าหน้าเว็บผ่าน browser สักหน้าหนึ่ง แล้วแวะไปดูที่ <save_path> ที่กำหนดเอาไว้แต่แรก หากทุกอย่างถูกต้องจะมีไฟล์ cachegrind.out.xxxx ปรากฏออกมาหลายๆ ไฟล์ ก็ให้ Download file พวกนี้แหละลงมาที่เครื่องเราให้หมด (แนะนำให้สั่ง tar -zcvf <save_zip_file_name> <save_dir> ก่อน)

ขั้นตอนสุดท้าย Download โปรแกรมดูผล Profiler ครับ มีสองตัว ใครใช้ Windows โหลด WinCacheGrind ใครใช้ Linux โหลด KCacheGrind โหลดเสร็จก็เปิดมาสั่ง File -> Open cachegrind.out.xxxx ที่พึ่ง Download มาตะกี้ก็จะดูได้แล้วดังรูปครับ

xdebug

ดูที่ช่อง Self กับ Cum. ก็จะรู้เวลาที่ใช้เรียบร้อย โดย Self ตัวเฉพาะ function นี้ที่ตัวมันเองเรียกเนี่ยใช้เวลาเท่าไหร่ และ Cum. คือรวมเวลา function ลูกที่ function นี้ไป call ต่ออีกทีทั้งหมดใช้เวลาเท่าไหร่ (- แสดงว่าน้อยมากจนแทบไม่มีผล) และจะบอกว่าไฟล์ไหน บรรทัดอะไรให้เสร็จสรรพ ดับเบิ้ลคลิกเข้าไปทีละชั้นๆ ได้เลย

ก็เท่านี้แหละครับสำหรับวิธีใช้งาน หากต้องการใช้บน Production Server หลังจากแก้ไข xdebug.profiler_enable=1 แล้ว restart php-fpm หรือ apache แล้วถ้าคนเล่น active เยอะหน่อยก็ไม่ต้องเปิดนานครับ สัก 5-10 วิพอ แล้วแก้ xdebug.profiler_enable=0 กลับ แล้วรีบ restart php-fpm หรือ apache ทันที มิฉะนั้นมันจะกินที่ไปมหาศาลครับ Download ลงเครื่องเราก็เสียเวลาเยอะอีก

ขอให้โชคดีครับ :)

การแก้ปัญหาขณะติดตั้ง PHP Agent ของ Newrelic by

5
Sep
0

วันก่อนผมเจอปัญหา process newrelic ส่วนของ PHP Monitoring ไม่ทำงาน ไม่มี Process สร้างขึ้นมาเลย และพอไปดู log ก็พบ error ดังนี้

errno=ECONNREFUSED. Failed to connect to the newrelic-daemon

ตอนสั่ง start newrelic PHP Agent แล้วปรากฏว่ารันไม่ขึ้น ซึ่งไม่เคยเจอปัญหานี้มาก่อน เลยไปค้นหาวิธีแก้ พบว่ามีทางแก้สองแบบ

แบบแรก

แก้ไขไฟล์ 20-newrelic.ini จาก

newrelic.daemon.port = "/tmp/.newrelic.sock"

เป็น

newrelic.daemon.port = "@newrelic-daemon"

แล้วสั่ง


service php5-fpm restart
service newrelic-daemon restart

แต่ผมลองแล้วไม่ได้ผล เลยต้องหาวิธีใหม่ได้แบบที่สองคือ

แบบที่สอง

1. พิมพ์ 

getent group newrelic

จะได้ผลลัพธ์ประมาณ newrelic:x:GroupID: ออกมา ให้จำค่า GroupID ไว้สำหรับใช้ต่อไป

2. แก้ไขไฟล์ /etc/sysctl.conf โดยเพิ่ม ข้อมูลดังนี้เข้าไป

fs.proc_can_see_other_uid = 0
fs.proc_super_gid = GroupID

ข้อควรระวังคือ fs.proc_super_gid สามารถใส่ GroupID ได้เพียงอันเดียว ถ้ามี fs.proc_super_gid อยู่ก่อนแล้วให้คุณสร้าง group ใหม่ขึ้นมาแล้วใส่ users ที่ต้องการใช้งานเข้าไปใน group ให้ครบทุก user แล้วใช้ group ใหม่นั้นแทนไปเลย แต่ถ้าไม่เคยสั่ง fs.proc_super_gid มาก่อนก็ไม่ต้องสนใจส่วนนี้

3. 

sysctl -p

4. 

service php5-fpm restart
service newrelic-daemon restart

5. เสร็จเรียบร้อย

วิธีติดตั้ง/ใช้งาน Facebook SDK (PHP) v5 by

30
Aug
0

ตอนนี้ Facebook SDK ของ PHP ก็ก้าวมาสู่ version 5 กันแล้ว มีขั้นตอนติดตั้งดังนี้ (สำหรับ Linux นะ ถ้า Windows Download ตัวนี้ไปเลย)

การติดตั้ง

1. รันคำสั่งตามด้านล่างใน bash เพื่อติดตั้ง composer (Facebook เก็บตัว Code ไว้ที่นี่) ถ้าใครไม่รู้จัก composer มันคือตัวจัดการ library และ dependency ของ library ต่างๆ ของ php ถ้าใครเคยใช้ nodejs มาก่อนให้นึกถึง npm ครับคล้ายๆ กัน
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === 'e115a8dc7871f15d853148a7fbac7da27d6c0030b848d9b3dc09e2a0388afed865e6a3d6b3c0fad45c48e2b5fc1196ae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

2. รันครบเราจะได้ไฟล์ composer.phar มา ก็เอาไปเก็บไว้ไหนก็ได้ตามสะดวก

3. เพิ่มด้านล่างเข้าไฟล์ composer.json หากยังไม่เคยมีมาก่อนให้สร้างขึ้นใหม่เลย
{
"require" : {
"facebook/php-sdk-v4" : "~5.0"
}
}

4. ./composer.phar install

5. ใช้งานได้เรียบร้อย

การใช้งาน

1. ตั้งต้น code ดังนี้ โดยส่วนนี้เน้นการใช้งานกับ Canvas ของ Facebook App (directory vendor อยู่ตำแหน่งเดียวกับ composer.json)

require 'vendor/autoload.php';

use Facebook\FacebookCanvasLoginHelper;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookRequestException;

$fb = new Facebook\Facebook([
'app_id' => '{app-id}',
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.7', // แก้เวอร์ชั่นเป็นเวอร์ชั่นล่าสุด ตรวจสอบได้ที่ https://developers.facebook.com/tools/explorer ว่าเวอร์ชั่นล่าสุดเป็นอะไร
'persistent_data_handler'=>'session'
]);

$helper = $fb->getCanvasHelper();
try {
$access_token = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// There was an error communicating with Graph
die( "Error: ". $e->getMessage() );
//exit;
}
$this->setDefaultAccessToken((string) $access_token);

2. การ Redirect ไปขอ permission การใช้งาน Facebook App ครั้งแรก

$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'user_likes']; // optional
$loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions);
header("Location: ".$loginUrl)
exit;

3. ตัวอย่างการใช้งาน graph api ที่ได้ค่ากลับมาเป็น JSON เรียบร้อย
try {
$response = $fb->get('/me');
$json_data = $response->getDecodedBody();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
}

ข้อพึงระวังคือ facebook SDK ใช้การตรวจจับว่าเว็บไซต์ของเราเป็น https หรือไม่จาก header ชื่อ SERVER_PORT (ใน php เรียกโดยผ่านตัวแปร $_SERVER['SERVER_PORT']) ดังนั้นหาก server ของคุณมีการใช้ nginx หรือ webserver ตัวอื่นๆ ในการโยน request ต่อกันหลายๆ ทอดจนทำให้ https ดันระบุ port ผ่านตัวแปรนี้เป็น 80 แทนก็ให้ระวังไว้ด้วยครับ facebook SDK ไม่ได้เช็คค่าจาก $_SERVER['HTTPS'] ดังนั้นเราอาจต้อง Hack code แก้ตรงนี้เอง

Install lua php extension อย่างไร? by

26
Oct
0

เนื่องจากเกมผมมีการใช้งาน Lua ทั้งฝั่ง Unity (C#) และ php จึงต้องหาทาง install lua ที่ใช้ php รันให้ได้ ค่อนข้างวุ่นวายหลายอย่าง มั่วอยู่นาน ก็ได้ขั้นตอนมาดังนี้

  1. apt-get install lua5.2 – install ตัวรัน lua จริงๆ
  2. apt-get install liblua5.2 – install source code lua เพื่อช่วย compile lua php extension
  3. apt-get install php5-dev – install ตัว compile php extension ต่างๆ
  4. เข้า https://github.com/laruence/php-lua ไป download หรือ clone code php extension ตัวล่าสุดมาลงและแกะ zip ให้เรียบร้อย
  5. เข้า dir ที่แกะแล้วจากข้อ 4 แล้วรัน phpize
  6. ./configure –with-php-config=/usr/bin/php-config –with-lua=/usr –with-lua-version=5.2
    (ควรรัน which php-config เพิ่อ check path ของ php-config อีกทีเพื่อความชัวร์สำหรับ os ที่ลงอาจได้ path ไม่เหมือนกัน)
  7. nano /etc/php5/fpm/conf.d/lua.ini สร้างไฟล์ขึ้นมา (หรืออาจเป็น php.ini ก็ได้ในบาง os) แล้วพิมพ์ไปว่า extension=lua.so
  8. restart php5-fpm หรือ apache ตามแต่ web server ที่ Install ไว้
  9. ใช้งานได้เล้ย!

วิธีใช้งานก็ประมาณนี้


$lua = new Lua();
$lua->include($path);
$result = $lua->myFunction($param);

วิธี scale PHP ไปยัง server หลายตัว by

31
Mar
0

หากเว็บไซต์ของคุณรับโหลดมาก คนเข้าเยอะฝุดๆ จน CPU หรือ Memory ล้นจนเกินไปแล้ว เปิด APC แล้วก็ยังไม่ช่วย และมั่นใจว่าปัญหาไม่ได้เกิดจาก database ช้าแน่ๆ หรือขยาย cloud แบบ vertical (up CPU up Ram) ไปจนสุดก็รับไม่ไหวแล้ว ก็ถึงเวลาที่จะต้องขยายของด้านข้าง (Horizontal Scale) แล้วละครับ วิธีการก็คือเราต้องมี Load Balancer มาคอยช่วยกระจายโหลดออกไป

Load Balance

จากรูปจะเห็นว่า Load Balancer เป็นเหมือนตัวกลางที่คอยรับส่งข้อมูลแทนระหว่าง Client กับ Server โดยที่การประมวลผลจริงๆ จะยังอยู่ที่ฝั่ง Server ซึ่งเราสามารถติดตั้ง Load Balancer ที่เครื่องแยกออกมาต่างหากหรือจะติดตั้งรวมกับ Server ตัวใดตัวหนึ่งก็ได้(เนื่องจากตัว Load Balance ไม่ได้กิน Resource เครื่องมากนัก) โดยหลักการแล้วจะมี public IP ยิงเข้า Load Balance เพื่อรับข้อมูลจาก Client ทุกคน และแอบส่งข้อมูลต่อไปยัง Server ผ่านทาง Private IP แล้วจึงตอบกลับไปยัง Client ซึ่งสุดท้าย Client จะรู้แค่ว่าต้องติดต่อกับ Load Balancer เท่านั้น ไม่จำเป็นต้องรู้เลยว่าจริงๆ แล้วเขากำลังคุยกับ Server ตัวไหนอยู่ และไม่สามารถรู้ได้ด้วยว่าจริงๆ แล้วมี Server ให้บริการทั้งหมดกี่เครื่อง

ตัว Load Balancer จะแบ่งออกเป็น 2 ประเภทคือชนิด Hardware (เป็นเครื่องที่ออกแบบมาให้ทำหน้าที่นี้โดยเฉพาะ) และชนิด Software (เราลงโปรแกรมที่ server ตัวใดตัวหนึ่งให้มันทำงานเป็น Load Balancer) ซึ่งส่วนใหญ่แล้วเพื่อประหยัดงบเรามักจะใช้ Load Balancer ชนิด Software ซึ่งแค่นี้ก็เพียงพอสำหรับการรองรับคนเข้าวันละแสนคนได้สบายๆ อยู่แล้ว

สำหรับ Software ยอดนิยมก็จะมี Nginx และ Haproxy ซึ่งผมแนะนำให้ใช้ Nginx เนื่องจากเอาไว้ Serv พวก Static File เช่นรูปภาพได้ด้วย load ที่ต่ำมาก ควบคู่ไปกับการแบ่ง load ซึ่งทำได้ในตัวเดียวเลย ซึ่งตัวอย่างการใช้งาน Nginx ให้ทำตัวเป็น Load Balancer ให้ใส่ config ดังตัวอย่างด้านล่าง


http {
upstream backend_php {
server 127.0.0.1:9000 weight=14;
server 192.168.0.1:9000 weight=13;
server 192.168.0.2:9000 weight=13;
}
}

จาก code ด้านบนคือส่ง load เข้าเครื่องแรกเป็นเครื่องตัวเอง เครื่องที่สองและสามเป็น ip 192.168.0.1 และ 192.168.0.2 port 9000 (เป็น Default port ของ Fast-CGI) แล้ว restart nginx แค่นี้ก็เรียบร้อย :)

ปัญหาสุดท้ายหลังจากใช้งาน Load Balancer คือ PHP Session จะไม่ได้สามารถใช้ได้เพราะปกติ Session จะเก็บลงไฟล์ที่เครื่อง server ที่ติดต่อ พอ user เข้าเครื่องไหนก็ได้ Session ก็จะไม่ตามไปยังอีกเครื่องด้วย ปัญหานี้แก้ด้วยการใช้ Redis เข้ามาช่วยเก็บข้อมูล Session PHP แทนครับ โดยต้อง Install Redis และ phpredis (Extension PHP เอาไว้คุยกับ Redis) ให้เรียบร้อยก่อน จากนั้น แก้ไขไฟล์ php.ini ตามด้านล่าง แก้ไข ip เป็นเครื่องที่ติดตั้ง redis ไว้ (server ทุกตัวต้องใช้ redis ตัวเดียวกัน) ก็เป็นอันเรียบร้อย ขอให้โชคดีกับการ scale server นะครับ :)


session.save_handler = redis
session.save_path = "tcp://localhost:6379"

กู้เงิน | เศรษฐกิจพอเพียง | สินเชื่อบุคคล | สมัครบัตรกดเงินสด | สินเชื่อ | เงินกู้ด่วน | ยืมเงินทรูมูฟ | เงินด่วนนอกระบบ