วันอังคารที่ 31 ตุลาคม พ.ศ. 2560

เปลี่ยนมารันคิวแบบใช้โปรแกรมฐานข้อมูล(MySql) กันดูบ้าง

เปลี่ยนมารันคิวแบบใช้โปรแกรมฐานข้อมูล(MySql) กันดูบ้างซิ จะได้รู้ว่าวิธีไหนทำได้สะดวกและดีที่สุด

ผู้เขียนเองได้ทดสอบการติดตั้งโปรแกรมการจัดการคิวไฟล์แบบง่ายไปครั้งแรกมาแล้ว http://www.s-techthai.com/2017/05/queue-file-php.html พบว่ามีข้อจำกัดอยู่มากโดยเฉพาะการแข่งขันกันจัดเก็บคิวทำได้ไม่สมบูรณ์ในบางครั้ง จึงเป็นที่มาของการปรับปรุงให้ดีขึ้นด้วยโปรแกรม beanstalk  http://www.s-techthai.com/2017/05/beanstalk.html พบว่ามีการใช้งานได้ง่ายดาย แก้ไขปัญหาเรื่องการแข่งขันกันจัดเก็บข้อมูลได้อย่างเด็ดขาด 100%  แต่ผู้เขียนยังพบว่าการบริหารจัดการที่ดูว่าง่ายดายกว่า หากสามารถคอนฟิกค่าต่าง ๆ ได้ดีก็เป็นการทำงานคิวที่สมบูรณ์แบบด้วยซ้ำ สำหรับวันนี้จะเป็นการสร้างคิวแบบใช้โปรแกรมฐานข้อมูล MySql ดูบ้างเพื่อเปรียบเทียบกัน

ขั้นตอนที่ 1 สร้างคลาสสำหรับใช้งานโปรแกรมคิวให้ไปดาวน์โหลดตามลิงค์ที่ผู้เขียนแปะไว้ให้ได้เลย

https://github.com/kotas/myqueue/blob/master/MyQueue.php
จากนั้นตั้งชืื่อไฟล์ตามตัวอย่าง MyQueue.php

ขั้นตอนที่ 2 สร้างฐานข้อมูลจากไฟล์ต่อไปนี้ได้เลย

 CREATE TABLE myqueue (
   `id`           BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
   `locked_until` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `data`         BLOB NOT NULL,
   PRIMARY KEY  (`id`)
 ) ENGINE=InnoDB;

ขั้นตอนที่ 3 สร้างโปรแกรมทดสอบการทำงานคิวตามตัวอย่างง่าย ๆ ต่อไปนี้

<?php
include_once 'MyQueue.php';
$servername = 'localhost';
$username = 'username';
$password = 'password';
$dbname = 'myqueue';
$PDO = new PDO("mysql:host=$servername;dbname=$dbname",$username,$password);
$queue = new MyQueue($PDO, 'myqueue');
$queue->push('Testing insert data to MyQueue!!!!');
echo $queue->pop();
?>
สำหรับโปรแกรมคิวแบบใช้โปรแกรมฐานข้อมูลนี้จะพบว่าทำงานได้ค่อนข้างดี มีประสิทธิภาพ และใช้งานได้ง่ายมาก เหมาะสมอย่างยิ่งสำหรับการนำไปพัฒนาปรับปรุงโค๊ดกันต่อเพื่อใช้บริการจัดการข้อมูลที่มีความสลับซับซ้อนเพิ่มมากขึ้น เนื้อหาดี ๆ ในวันนี้จะสำเร็จลุล่วงไปไม่ได้เลยหากไม่ได้รับการสนับสนุนจาก gps โคราช ด้วยคุณภาพชั้นนำของอุปกรณ์ ผ่านมาตรฐานกสทช. ถูกกว่า คุ้มค่ากว่า ทุกบาทที่จ่ายไป


วันพฤหัสบดีที่ 27 กรกฎาคม พ.ศ. 2560

แก้ปัญหาพาร์ติชั่นบูต(boot)เต็มสำหรับระบบปฏิบัติการ Ubuntu 16.04.2 LTS

 

แก้ปัญหาพาร์ติชั่นบูต(boot)เต็มสำหรับระบบปฏิบัติการ Ubuntu  16.04.2 LTS หนักใจที่สุดก็คือระบบจะมีปัญหาในการบูตครั้งต่อ ๆ ไป สาเหตุที่พาร์ติชั่นบูตเนื้อที่ไม่พอ

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

สิ่งที่ต้องระมัดระวังก็คือหากมีการอัพเกรดแล้วไม่ค่อยได้รีบูตเครื่องใหม่ ล่าสุดพบข้อผิดพลาดที่ระบบลินุกส์ไม่สามารถอัพเกรมเคอร์นอลใหม่ได้สมบูรณ์เพราะพื้นที่ฮาร์ดดิสก์ในพาร์ติชั่นบูตไม่เพียงพอ

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

ขั้นตอนที่ 1 ต้องตรวจสอบพื้นที่ว่างของพาร์ติชั่นบูตดูก่อนว่ามีพื้นที่เหลือเพียงพอหรือไม่ จากตัวอย่างข้างล่างจะพบว่า พาร์ติชั่น boot มีการใช้งานไปถึง 465M จากพื้นที่เต็ม 472M คิดเป็นเปอร์เซนต์ที่ 100%

นี่แหล่ะคือปัญหาที่เกิดขึ้นสำหรับเนื้อหาในวันนี้

# df -h
Filesystem                   Size  Used Avail Use% Mounted on
udev                         3.9G     0  3.9G   0% /dev
tmpfs                        799M  8.7M  790M   2% /run
/dev/mapper/ubuntu--vg-root   28G   22G  5.2G  81% /
tmpfs                        3.9G     0  3.9G   0% /dev/shm
tmpfs                        5.0M     0  5.0M   0% /run/lock
tmpfs                        3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda1                    472M  465M     0 100% /boot
tmpfs                        799M     0  799M   0% /run/user/1000

ขั้นตอนที่ 2 เป็นการตรวจสอบเคอร์นอลที่ใช้งานอยู่ว่าเป็นเวอร์ชั่นไหน จากตัวอย่างพบว่าเป็นเวอร์ชั่น 4.4.0-63 ผู้เขียนจึงได้ย้ายข้อมูลในพาร์ติชั่นบูตที่ต่ำกว่าเวอร์ชั่นที่ใช้งานอยู่ออก เพื่อเพิ่มพื้นที่ให้

ระบบการอัพเกรดเคอร์แนลทำงานได้สมบูรณ์แบบ หลังจากนั้นใช้คำสั่ง apt-get -f install

#uname -r
4.4.0-63-generic

#apt-get -f install

ขั้นตอนที่ 3 หลังจากที่ดำเนินการอัพเกรดได้เสร็จสิ้นไม่มีข้อผิดพลาดใด ๆ เรียบร้อยแล้วในขั้นตอนที่ 2 ให้ใช้คำสั่ง apt-get autoremove เพื่อจัดการกับเคอร์เนลเก่าที่ไม่ได้ใช้งานออกไป

#apt-get autoremove

จากนั้นตรวจสอบพื้นที่ว่าของพาร์ติชั่นบูตดูใหม่ ตามตัวอย่างพบว่ามีพื้นที่ว่างเพิ่มขึ้น 287M หรือคิดเป็น 37% นั่นเอง
# df -h
Filesystem                   Size  Used Avail Use% Mounted on
udev                         3.9G     0  3.9G   0% /dev
tmpfs                        799M  8.6M  790M   2% /run
/dev/mapper/ubuntu--vg-root   28G   21G  6.0G  78% /
tmpfs                        3.9G     0  3.9G   0% /dev/shm
tmpfs                        5.0M     0  5.0M   0% /run/lock
tmpfs                        3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda1                    472M  162M  287M  37% /boot

ขั้นตอนที่ 4 เป็นการรีสตาร์ทเพื่อเริ่มระบบใหม่ ปรากฎว่าผ่านการบูตไปไม่ได้ หน้าจอไปติดอยู่ที่ initramfs ก็ไม่ต้องตกใจให้ดำเนินการตามนี้ ให้เลือก y เพื่อทำการแก้ไขไฟล์และinodeที่ผิดพลาดทั้งหมด ตอบใช่ในทุก ๆ ขั้นตอนรอจนระบบบูตได้สมบูรณ์

(initramfs) fsck /dev/mapper/ubuntu--vg-root
select 'y' to all 'Fix?' prompts

ต้องขอขอบพระคุณพื้นที่เวบไซต์บล็อกเนื้อหาดี ๆจาก https://thaigpstrackers.com สนับสนุนเนื้อหาดี ๆในวันนี้ให้เราได้ศึกษากัน สนใจระบบจีพีเอสติดตามรถยนต์ มาตรฐานไทย ต้องอย่าลืมแวะเข้าไปเยี่ยมชมที่ลิงค์ดังกล่าวข้างต้น

GPS ติดตามรถ

วันเสาร์ที่ 17 มิถุนายน พ.ศ. 2560

เข้าสู่โหมดการเชื่อมต่อแบบปลอดภัย ssl อย่างถูกวิธี เพื่อการให้บริการเว็บไซต์ดูดี มีมาตรฐานที่เหนือชั้นกว่า

 

เข้าสู่โหมดการเชื่อมต่อแบบปลอดภัย ssl อย่างถูกวิธี เพื่อการให้บริการเวบไซต์ดูดี มีมาตรฐานที่เหนือชั้นกว่า 

บ่อยครั้งที่ผู้เขียนเปิดเวบไซต์ของตัวเองโดยใช้ google chrome บนพื้นที่ด้านบนตำแหน่งให้ป้อน url ขึ้นเครื่องหมายตกใจ !ไม่ปลอดภัย  หากเปิดด้วยมือถือเตือนหนัก การเชื่อมต่อกับเว็บไซต์นี้ไม่ปลอดภัย คุณไม่ควรป้อนข้อมูลที่ละเอียดอ่อนบนเว็บไซต์นี้(ตัวอย่างเช่น รหัสผ่านหรือบัตรเครดิต) เนื่องจากผู้โจมตีอาจขโมยข้อมูลดังกล่าวไปได้ แต่บางเวบไซต์ขึ้นสัญลักษณ์รูปกุญแจสีเขียวแล้วแสดงคำว่า ปลอดภัย

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

สำหรับระบบโอเอสที่ผู้เขียนใช้เขียนบทความในวันที่ก็คือ Ubuntu 16.04.2 LTS  นั่นเอง เนื้อหาในวันนี้ค่อนข้างซับซ้อนพอสมควร มีความสัมพันธ์กันหลาย ๆ เรื่องแนะนำมือใหม่ว่าอย่าใจร้อนโดยเด็ดขาด

ขั้นตอนที่ 1 ให้สร้างคีย์ส่วนตัว(private key) สำหรับเป็นฐานสำหรับสร้างคีย์อื่น ๆ รวมถึงสร้างการร้องขอการใช้  Certification Request(csr) ไฟล์เพื่อใช้สำหรับร้องขอคีย์สาธารณะของเซิร์ฟเวอร์ รวมถึงคีย์สาธาระของผู้ให้บริการ CA

#openssl genrsa -des3 -out www_gpsthai_com.key 2048
#mv www_gpsthai_com.key www_gpsthai_com_secure.key
#openssl rsa -in www_gpsthai_com_secure.key -out www_gpsthai_com.key
#openssl req -new -key www_gpsthai_com.key -out www_gpsthai_com.csr


ในขั้นตอนที่มีคีย์อยู่ด้วยกัน 2 ไฟล์ที่สำคัญก็คือ www_gpsthai_com.key เป็นคีย์ส่วนตัวสำหรับเซิร์ฟเวอร์ และ www.gpsthai.com.csr เป็นคีย์สาธารณะสำหรับร้องขอเพื่อขอบริการ CA

ขั้นตอนที่ 2 หลังจากสร้างคีย์เพื่อทำการร้องขอได้เรียบร้อยแล้ว ผู้เขียนได้ทำการร้องขอไปยังผู้ให้บริการ CA ในที่นี้คือ Codomo ส่วนการสั่งซื้อก็เลือกเพียงแค่ Positive SSL หลังจากการร้องขอสมบูรณ์ผู้ให้บริการ CA จะส่งไฟล์คีย์สาธารณะของCA และไฟล์คีย์ของเซิร์ฟเวอร์มาให้ ตัวอย่างไฟล์ที่ผู้เขียนได้รับมาจาก Codomo

ดังนี้

AddTrustExternalCARoot.crt
COMODORSAAddTrustCA.crt
COMODORSADomainValidationSecureServerCA.crt
www_gpsthai_com.crt
ไฟล์หลักสำหรับคีย์สาธาระของCA ก็คือ COMODORSADomainValidationSecureServerCA.crt ส่วนไฟล์คีย์สาธารณะสำหรับเซอร์เวอร์ ก็คือ www_gpsthai_com.crt นั่นเอง เราจะได้ใช้ค่าต่าง ๆ เหล่านี้สำหรับกำหนดค่าคอนฟิกให้กับโปรแกรม apache

ล่าสุดเมื่อวันที่ 13 เมษายน พ.ศ.2561 ผู้เขียนสร้างโหมดการเชื่อมต่อแบบปลอดภัยให้กับเวบไซต์ vanvip.net ปรากฏว่า COMODO สร้างไฟล์มาให้แค่ 2 ไฟล์คือ www_vanvip_net.crt และ www_vanvip_net.ca-bundle ก็ไม่ต้องตกใจ ตัวไฟล์ crt ใช้เหมือนเดิมคือในส่วนของ SSLCertificateFile ส่วนไฟล์ ca-bundle เอาไปแทน SSLCertificateChainFile

www_vanvip_net.crt
www_vanvip_net.ca-bundle


ขั้นตอนที่ 3 ความสลับซับซ้อนเริ่มเพิ่มมากขึ้นมาเรื่อย ๆ ครั้งนี้จะเป็นการจัดการเซิร์ฟเวอร์ให้สามารถเปิดให้บริการระบบ ssl ได้ ดูตำแหน่งของไฟล์ให้ถูกต้อง เพื่อให้การทำงานเป็นไปได้ด้วยความราบรื่น
 #mkdir /etc/apache2/ssl
 #a2enmod ssl
 #cp default-ssl.conf gpsthai-ssl.conf
<VirtualHost _default_:443>
                ServerAdmin webmaster@localhost
                ServerAlias www.gpsthai.com
                ServerName gpsthai.com
                DocumentRoot /var/www/gpsthai
                <Directory "/var/www/gpsthai">
                        Options Indexes FollowSymLinks
                        AllowOverride All
                </Directory>
        SSLCertificateFile      /etc/apache2/ssl/www_gpsthai_com.crt
        SSLCertificateKeyFile /etc/apache2/ssl/www_gpsthai_com.key
        SSLCertificateChainFile /etc/apache2/ssl/COMODORSADomainValidationSecureServerCA.crt

ขั้นตอนที่ 4 เมื่อกำหนดค่าให้กับเซิร์ฟเวอร์เพื่อเปิดใช้บริการ ssl เรียบร้อยแล้ว ยังต้องสร้างไซต์ให้รองรับการสร้างเนื้อหาแบบ ssl สำหรับผู้เ่ขียนใช้งาน Joomla ต้องติดตั้งโปรแกรม php-curl เพิ่มเติม

#apt-get install php-curl
#a2ensite gpsthai-ssl
#service apache2 reload

ขั้นตอนที่ 5 เป็นการแก้ไขในส่วนของ htaccess ไฟล์เพื่อให้รีไดเรคเซอร์วิสจาก http ไปเป็น https โดยอัตโนมัติ

 RewriteEngine On
 RewriteCond %{HTTPS} !=on
 RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
#Also, you can also redirect based on port number, for example:
 RewriteCond %{SERVER_PORT} ^80$
 RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

ขั้นตอนที่  6 ต้องสร้างไฟล์ sitemap.xml ขึ้นมาใหม่หมดเพราะเราเปลี่ยนจาก http ไปเป็น https โดยสมบูรณ์แล้ว สามารถกลับไปทบทวนวิธีการได้ที่ วิธีสร้างไซต์แม็บดี ๆ ไม่มีค่าใช้จ่าย 

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





วันอังคารที่ 30 พฤษภาคม พ.ศ. 2560

รันโปรแกรมสคริป php อัตโนมัติ สำหรับบริการเซิร์ฟเวอร์ TCP ฉบับเซียน

ผู้เขียนเคยแนะนำวิธีการ สร้าง PHP ทำหน้าที่เป็น TCP server รองรับจำนวนลูกข่ายมากกว่า 10 เครื่องพร้อมกัน โดยโปรแกรมจะทำงานในโหมดโฟร์กราวด์(foreground) คือหากปิดหน้าต่างหรือปิดเทอร์มินอลโปรแกรมก็หยุดทำงาน จากนั้นผู้เขียนได้พัฒนาให้ทำงานในโหมดแบ็กกราวด์(background)ดีขึ้นมาหากปิดเทอร์มินอลโปรแกรมก็ยังทำงานได้ดีอยู่ จากนั้นก็สร้าง cron ให้ทำงานทุก ๆ 5-10 นาทีเพื่อตรวจสอบดูว่าหากโปรแกรมสคริปหยุดทำงาน ก็ให้สตาร์ทเซอร์วิสใหม่ การรันโปรแกรมสคริป php ที่ทำหน้าที่เป็นเซิร์ฟเวอร์แบบนี้ หากเราหยุดโปรแกรมโดยการฆ่าโฟรเซส(kill process)บางครั้งโปรแกรมก็ไม่สามารถสตาร์ทได้ใหม่ในทันใด
socket_bind() failed: reason: Address already in use
ปํญหาที่พบเจอก็คือข้อผิดพลาด "Address already in use" วิธีแก้ของผู้เขียนก็คือรอเวลาระหว่างการรีสตาร์ทเซอร์วิสให้นานขึ้น แต่การรอเพื่อจะสตาร์ทเซอร์วิสใหม่นานถึง 5-10 นาที ข้อมูลที่ต้องการติดต่อระหว่างนั้นก็จะหายไปหรือปิดเซอร์วิสการให้บริการชั่วคราว นับเป็นปัญหาหนึ่งของการให้บริการ

ผู้เขียนเคยใช้งานโปรแกรมควบคุมเซอร์วิสให้ทำงานอยู่ตลอดเวลา  ไม่ต้องเสียน้ำตากับการรันโปรแกรมสคริป php อัตโนมัติ supervisor แบบมืออาชีพ ซึ่งเซอร์วิสนี้พบว่าทำงานได้อย่างดีเยี่ยมโดยเฉพาะการควบคุมคิวการทำงาน(beanstalk)

ครั้งนี้จะนำมาประยุกต์ให้ใช้ทำงานร่วมกันให้ได้อย่างมีประสิทธิภาพ สำหรับรันโปรแกรมสคริป php อัตโนมัติ สำหรับบริการเซิร์ฟเวอร์ TCP ฉบับเซียน


ขั้นตอนที่ 1 หากยังไม่เคยใช้งานโปรแกรม supervisor แนะนำให้กลับไปอ่านบทความ ไม่ต้องเสียน้ำตากับการรันโปรแกรมสคริป php อัตโนมัติ supervisor แบบมืออาชีพ ก่อน สำหรับขั้นตอนนี้ให้เพิ่มคอนฟิกไฟล์ตามตัวอย่าง

  [program:ywt6035v2]
command=bash -c "ulimit 10000; exec /usr/bin/php /var/www/ywt7035v2/ywt7035v2.php"             ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1                    ; number of processes copies to start (def 1)
directory=/tmp                ; directory to cwd to before exec (def no cwd)
umask=022                     ; umask for process (default None)
priority=999                  ; the relative start priority (default 999)
autostart=true                ; start at supervisord start (default: true)
startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)
autorestart=true        ; when to restart if exited after running (def: unexpected)
exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)
stopsignal=QUIT               ; signal used to kill process (default TERM)
stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A="1",B="2"       ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)
ปัญหาการรีสตาร์ทเซอร์วิสสำหรับสคริปของ php ได้ถูกแก้ไขโดยใช้แบทไฟล์(bash file) ครอบไว้อีกทีหนึ่งเพื่อป้องกันปัญหาการหยุดการทำงานของสคริป php แต่ยังค้างพอร์ตไว้อีกระยะหนึ่ง ทำให้เซอร์วิสลูกใหม่ไม่สามารถสตาร์ทได้ทันที

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

/etc/init.d/supervisor reload
สำหรับการตรวจสอบเซอร์วิสว่าทำงานหรือไม่ให้ใช้คำสั่ง supervisorctl
#supervisorctl
pheanstalkget                    STARTING
ywt2035v2                        STARTING
ywt3035v2                        STARTING
ywt4035v2                        STARTING
ywt6035v2                        STARTING
ywt7035v2                        STARTING
supervisor> 
หรือคำสั่ง status
supervisor> status
pheanstalkget                    RUNNING   pid 19998, uptime 0:01:37
ywt2035v2                        RUNNING   pid 19467, uptime 0:41:05
ywt3035v2                        RUNNING   pid 19468, uptime 0:41:05
ywt4035v2                        RUNNING   pid 19999, uptime 0:01:22
ywt6035v2                        RUNNING   pid 19985, uptime 0:03:20
ywt7035v2                        RUNNING   pid 19925, uptime 0:03:56
จากคำสั่ง status จะเห็นได้ว่าเซอร์วิส uptime นานที่สุดแค่า 41.05 นาที ส่วนเซอร์วิสอื่น ๆ ก็เพิ่งจะทำงานได้ไม่นาน หากการหยุดทำงานในแต่ละครั้งกินเวลาถึง 5-10 นาทีแบบเดิม ข้อมูลที่สูญหายไปในแต่ละวันย่อมมากเกินกว่าค่าที่จะรับได้

จากการทดลองรันโปรแกรม supervisorctl สำหรับควบคุมโปรแกรมสคริป php พบว่าต้องเพิ่มบรรทัดในส่วนการเรียกใช้งานแอดเดรสใหม่ด้วยตามสคริปที่แนบให้ ให้เพิ่มก่อนถึงบรรทัด socket_bind()
// modified to correct Address already in use
        if (!socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1)){
                echo "socket_set_option() failed: reason: ".socket_strerror(socket_last_error())."\n";
        }
ดังนั้นการรันโปรแกรมสคริป php อัตโนมัติ สำหรับบริการเซิร์ฟเวอร์ TCP ฉบับเซียน จะช่วยแก้ปัญหาเรื่องนี้ได้อย่างชัดเจนและเป็นรูปธรรมที่สุด ข้อสำคัญเนื้อหาบทความดี ๆ อย่างนี้จะเกิดขึ้นไม่ได้เลยหากไม่ได้รับการสนับสนุนจากบริการเวบไซต์ thai-gpstracker.com ผู้นำ รู้ลึก รู้จริง ด้านการให้บริการระบบจีพีเอสติดตามรถยนต์ บริหารงานโดยทีมงานวิศวกร



วันจันทร์ที่ 29 พฤษภาคม พ.ศ. 2560

ใช้งานโปรแกรมจัดการคิวแบบง่าย ประสิทธิภาพสูง beanstalk

หลังจากที่ผู้เขียนได้ผ่านการใช้งานโปรแกรมคิวไฟล์แบบเท็กซ์ไฟล์แบบง่ายไปได้ 3-4 เดือนที่ผ่านมา สร้างคิวไฟล์(queue file)แบบเท็กซ์ไฟล์แบบง่ายโดยใช้โปรแกรม php พบว่าผลการทำงานเป็นไปอย่างไม่ประทับใจ กล่าวคือมีการแย่งกันบันทึกไฟล์พร้อม ๆ กันหลาย ๆ ครั้งส่งผมให้ข้อความที่บันทึกลงในคิวไฟล์ไม่สมบูรณ์ ผิดพลาดค่อนข้างมาก ทำให้ต้องกลับมาทบทวนหาวิธีอื่นดู จนได้พบกับ ใช้งานโปรแกรมจัดการคิวแบบง่าย ประสิทธิภาพสูง beanstalk

การติดตั้งโปรแกรม beanstalk สามารถทำได้ไม่ยากเย็น เพียงแค่คำสั่งเดียวก็สามารถรันคิวได้แบบสมบูรณ์แบบ ส่วนโปรแกรมที่ผู้เขียนใช้บริหารจัดการคิวก็คือโปรแกรม pheanstalk ที่พัฒนาด้วยภาษา php นั่นเอง ปัญหาใหญ่ของการเริ่มต้นใช้งานภาษา php ก็คือเรื่องการติดตั้งโปรแกรมที่เรียกว่า composer ที่มีใช้งานกันอย่างกว้างขวาง ประโยชน์ของการติดตั้งโปรแกรม php โดยใช้ composer ก็คือจะทำให้ขั้นตอนการติดตั้งไลบรารี่อื่น ๆ ที่โปรแกรมต้องการใช้งานเป็นไปได้อย่างอัตโนมัติ เนื้อหารายละเอียดเชิงลึกในส่วนนี้จะยังไม่กล่าวถึงสำหรับบทความในวันนี้


ขั้นตอนที่ 1 เป็นการติดตั้งโปรแกรมคิว beanstalk

apt-get install beanstalkd

ขั้นตอนที่ 2 เป็นการติดตั้งโปรแกรม pheanstalk สำหรับการติดตั้งผ่าน composer ให้สร้างไฟล์ที่ชื่อว่า composer.json

{
        "require": {
                "pda/pheanstalk": "3.0.2"}
}
จากนั้นทำการติดตั้งโปรแกรม pheanstalk โดยใช้คำสั่งติดตั้งข้างล่าง

#composer install --no-dev

ขั้นตอนที่ 3 เป็นการสร้างไฟล์ สำหรับทดสอบคิวโดยการป้อนข้อมูลลงในคิว 

<?php
require_once("vendor/autoload.php");
use \Pheanstalk\Pheanstalk;

$pheanstalk = new Pheanstalk('127.0.0.1');

// ----------------------------------------
// producer (queues jobs)

$pheanstalk
   ->useTube('testtube')
   ->put("job payload goes here\n");
?>

ขั้นตอนที่ 4 เป็นการสร้างไฟล์เพื่อดึงข้อมูลจากคิวมาใช้งาน

<?php
require_once("vendor/autoload.php");
use \Pheanstalk\Pheanstalk;

$pheanstalk = new Pheanstalk('127.0.0.1');

// ----------------------------------------
// worker (performs jobs)

  $job = $pheanstalk
   ->watch('testtube')
   ->ignore('default')
   ->reserve();
  echo $job->getData();
  $pheanstalk->delete($job);
?>

จะเห็นว่าเนื้อหาที่นำเสนอจะคัดมาแบบสั้น ๆ ง่าย ๆ จุดประสงค์ก็คือหากการเริ่มต้นลงลึกไปมาก ก็จะทำให้เสียกำลังใจไม่อยากจะทดลองทำ สุดท้ายก็ไม่ได้ประโยชน์ ผู้เขียนเสียเวลาไปหลายวันสำหรับศึกษาการติดตั้งโปรแกรมโดย composer ทั้ง ๆ ที่จริง ๆ หากเข้าใจใช้งานง่ายมากและนำไปประยุกต์ใช้งานได้อย่างกว้างขวางในเอกสารส่วนใหญ่ของโปรแกรมสคริป php

การรันโปรแกรมเพียงลำพังโปรแกรมเดียวครั้งเดียวโดยใช้สคริป php ยังเป็นการดำเนินการที่ค่อนข้างยุ่งยากมาก ยังไงลองศึกษา การใช้งานโปรแกรม supervisor สำหรับควบคุมสคริปต่าง ๆ ของ php ดูพบว่าเป็นเรื่องที่ง่ายขี้น

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









วันอาทิตย์ที่ 28 พฤษภาคม พ.ศ. 2560

ไม่ต้องเสียน้ำตากับการรันโปรแกรมสคริป php อัตโนมัติ supervisor แบบมืออาชีพ

หลายครั้งพัฒนาโปรแกรมเรียบร้อยแล้ว นำไปใช้งานจริงกลับทำงานได้เพียงแค่สักครู่เดียว โปรแกรมก็หยุดทำงานลง ไม่สามารถทำให้ทำงานแบบต่อเนื่องตลอดเวลาได้ แนวทางสมัยก่อน ๆ ที่ผู้เขียนนิยมใช้ก็คือทำโปรแกรมให้รันแบบเบื้องหลัง(daemon) และใช้ cron ตั้งเวลาสำหรับตรวจสอบโพรเซสว่าทำงานอยู่หรือไม่ ทุก ๆ 5 - 10 นาทีเป็นต้น

ผู้เขียนเองทดสอบการใช้งานโปรแกรมสำหรับใช้งานคิว(queue) ที่ใช้ไลบรารี่ pheanstalk อยู่พบว่าการทำงานในแบบเบื้องหลังหรือตั้งเวลาให้ทำงานไม่สามารถใช้งานได้ โปรแกรมสคริป php จะหยุดทำงานไม่ต่อเนื่อง เสียเวลาไปหลายวันก็ยังไม่สามารถหาวิธีการสำหรับตรวจสอบสคริป php ที่สร้างใหม่ให้ทำงานตลอดเวลา รวมทั้งบันทึกล็อกไฟล์ข้อมูลการทำงานได้เองแบบอัตโนมัติด้วย ยิ่งเพิ่มงานให้ยุ่งยากมากขึ้นเป็นสองสามเท่าตัว

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


 ขั้นตอนที่ 1 สำหรับโปรแกรมที่ใช้งานก็คือโปรแกรม supervisor การติดตั้งบนเครื่องลีนุกส์เพียงแค่พิมพ์คำสั่งตามที่ผู้เขียนแนบให้แค่นั้น

#apt-get install supervisor

ขั้นตอนที่ 2 กำหนดค่าคอนฟิกให้กับโปรแกรม ตามตัวอย่างผู้เขียนต้องการรันสคริป php แบบอัตโนมัติ แบบตรวจสอบเซอร์วิสให้ด้วยหากหยุดทำงานก็เริ่มต้นสตาร์ทให้ใหม่ด้วย ตามตัวอย่างให้สร้างไฟล์ชื่อ pheanstalk.conf ไว้ในโฟลเดอร์ /etc/supervisor/conf.d/ ข้อสำคัญที่สุดห้ามรันโปรแกรมแบบ daemon หรือแบบเบื้องหลัง

[program:pheanstalkget.php]
command=/usr/bin/php /var/www/tpit/gprmc/pheanstalk/pheanstalkget.php              ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1                    ; number of processes copies to start (def 1)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
umask=022                     ; umask for process (default None)
priority=999                  ; the relative start priority (default 999)
autostart=true                ; start at supervisord start (default: true)
autorestart=true        ; whether/when to restart (default: unexpected)
startsecs=1                   ; number of secs prog must stay running (def. 1)
startretries=3                ; max # of serial start failures (default 3)
exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)

ขั้นตอนที่ 3 เป็นการเริ่มใช้งานโปรแกรม supervisor และการควบคุมโปรแกรมสคริป php โดยใช้โปรแกรม supervisorctl

#/etc/init.d/supervisor start
# supervisorctl
pheanstalkget.php                   RUNNING   pid 30700, uptime 0:16:55
supervisor>


ผู้เขียนได้ทำการทดสอบการทำงานพบว่าได้ผลเป็นที่น่าพึงพอใจในเบื้องต้น แต่อย่างไรก็ตามยังต้องใช้เวลาพิสูจน์การทำงานจริงอีกระยะหนึ่ง ผลการทดลองจะได้นำมาอัพเดทกันอีกครั้งหนึ่งในส่วนของเนื้อหา เรื่องราวดี ๆ อย่างนี้ยังมีให้พบเห็นกันได้ที่ gpstrackingthailand.com อีกเวบไซต์หนึ่งที่ผู้เขียนได้มีโอกาสพัฒนาขึ้นมาเอง สำหรับข้อมูลเนื้อหาสาระดี ๆ จากผู้ให้บริการระบบจีพีเอสติดตามรถยนต์ ส่วนเนื้อหาเรื่องถัดไปที่พลาดไม่ได้ก็คือการรันโปรแกรมคิว beanstalk พร้อมกับโปรแกรมไลบรารี่ pheanstalk สำหรับบริหารจัดการคิวแบบง่าย ๆ สไตล์ที่เราถนัด ทำจริง ประสบการณ์จริง เพื่อการพัฒนาองค์ความรู้แบบยั่งยืน






สร้างคิวไฟล์(queue file)แบบเท็กซ์ไฟล์แบบง่ายโดยใช้โปรแกรม php

หลายครั้งที่การสั่งให้ทำงานแบบเรียลไทม์หรือทันทีทันใดไม่สามารถดำเนินการได้โดยเฉพาะการข้อมูลผ่านระบบเครือข่ายอินเทอร์เน็ตบางครั้งสำเร็จ บางครั้งไม่สำเร็จ สำหรับงานลักษณะนี้ ผู้เขียนจะขอแนะนำให้ใช้คิวไฟล์(queue file)แบบง่ายโดยใช้คลาสของโปรแกรมที่ใช้งานง่ายที่สุดก็คือ php นั่นเอง

สำหรับการใช้งานคิวไฟล์เองก็ไม่ยุ่งยาก เช่นหากต้องการเพิ่มข้อมูลเข้าไปในคิวไฟล์ก็ใช้คำสั่ง enqueue() หากต้องการดึงข้อมูลออกจากคิวไฟล์ก็แค่ใช้คำสั่ง dequeue() และหากต้องการให้คิวไฟล์สามารถจัดเก็บข้อมูลในเท็กซ์ไฟล์ก็ใช้คำสั่ง save() นับว่าการใช้งานสามารถนำไปประยุกต์ใช้งานได้อย่างมากมาย


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

ขั้นตอนการสร้างคิวไฟล์แบบเท็กซ์ไฟล์แบบง่ายโดยใช้โปรแกรม php

ขั้นตอนที่ 1 ในการสร้างการป้อนข้อมูลเข้าคิวไฟล์ ผู้เขียนแนะนำให้ใช้โค๊ดอย่างง่าย ๆ ที่แปะไว้ให้ข้างล่างนี้ โดย include เป็นการเรียกใช้งานคลาสคิวไฟล์ คำสั่ง new เป็นการสร้างออปเจคขึ้นมาใหม่ เมทธอด enqueue เป็นการป้อนข้อมูลเข้าคิวไฟล์ จากนั้นทำการ save ลงในเท็กซ์ไฟล์

<?php
include "queue/TitleManager.php";
$qt = new TitleManager();
$qt->enqueue($msgs);
$qt->save();
?>

ขั้นตอนที่ 2 เป็นการสร้างโค๊ดสำหรับดึงข้อมูลออกจากคิวไฟล์ include เป็นการเรียกใช้งานคลาสคิวไฟล์ คำสั่ง new เป็นการสร้างออปเจคขึ้นใหม่ ส่วนเมทธอด dequeue เป็นการอ่านค่าจากคิวไฟล์ในตำแหน่งที่พอยเตอร์อยู่ และเมทธอด save เป็นการบันทึกข้อมูลลงเท็กซ์ไฟล์

<?php
include "queue/TitleManager.php";
qt = new TitleManager();
$msg = $qt->dequeue();
$qt->save();
?>   

ขั้นตอนที่ 3 เป็นการสร้างไฟล์สำหรับคลาสคิวไฟล์ ให้ตั้งชื่อว่า TitleManager.php

<?php

// Title Manager class (essentially a queue) that uses a simple text file for storage
class TitleManager {
        private $filename = "/tmp/gpsmessages.txt";
        private $queueLimit = 10000;
        private $titles;

        // Upon creation, load up our titles from the file
        public function __construct() {
                $this->titles = array();
                $this->loadTitles();
        }


        private function loadTitles() {
                if (file_exists($this->filename)) {
                        $this->titles = file($this->filename, FILE_SKIP_EMPTY_LINES);
                }
        }

        // Add a title to the queue and if we are at our limit, drop one off the end.
        public function enqueue($strTitle) {
                if (!empty($strTitle)) {
                        array_unshift($this->titles, $strTitle . "\n");

                        if (count($this->titles) > $this->queueLimit) {
                                $this->dequeue();
                        }
                }
        }

        // Remove a title item from the end of our list
        public function dequeue() {
                if (count($this->titles) > 0) {
                        return trim(array_pop($this->titles));
                }
                return "";
        }

        // Save the contents of our array back to the file.
        public function save() {
                if (file_put_contents($this->filename, $this->titles)) {
                        return true;
                }
                return false;
        }


        // Check if an item is already in our list.
        // Note: We could have also used in_array here instead of a loop.
        public function isTitlePresent($strTitle = "") {
                if (!empty($strTitle)) {
                        foreach ($this->titles as $title) {
                                $trimmedTitle = trim($title);
                                $strTitle = trim($strTitle);
                                if (strtolower($strTitle) == strtolower($trimmedTitle)) { return true; }
                        }

                        return false;
                }
                return -1;
        }


        // Mainly a debug function to print our values to screen.
        public function printValues() {
                foreach ($this->titles as $value) {
                        echo "$value<br/>";
                }
        }
}
?>


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

ส่วนวิธีการที่ดีกว่าการใช้คิวแบบเท็กซ์ไฟล์ ผู้เขียนได้ทดลองใช้งานอยู่ในปัจจุบันก็คือ "beanstalk" นั่นเองจัดว่าเป็นโปรแกรมจัดการคิวแบบง่าย ๆ ที่มีประสิทธิภาพสูง ซึ่งผู้เขียนจะได้นำเสนอบทความการใช้งาน beanstalk กันอีกครั้งหนึ่งในภายภาคหน้า เนื้อหาดี ๆเหล่านี้จะสำเร็จลุล่วงไปไม่ได้เลย หากไม่ได้รับการสนับสนุนจาก บจก.ไทย พรอสเพอรัส ไอที ผู้นำด้านการให้บริการระบบจีพีเอสติดตามรถยนต์ อันดับหนึ่งของประเทศไทย ดำเนินการด้วยทีมงานวิศวกร ช่วยให้รถยนต์ของเราไม่พลาดการเชื่อมต่อ




วันอังคารที่ 18 เมษายน พ.ศ. 2560

คัดลอกพาร์ติชั่นอิมเมจ Ubuntu server ใหม่โดยใช้ lvm

บทความเมื่อครั้งก่อน วิธีการสำรองพาร์ติชั่นแบบ logical volumn management(lvm) โดยใช้ snapshot มาในวันนี้ ผู้เขียนจะพาไปแนะวิธีการคัดลอกพาร์ติชั่นอิมเมจ โดยระบบปฏิบัติการที่ใช้คือเซิร์ฟเวอร์ Ubuntu นั่นเอง การทำงานที่อาศัยการทดลองและปฏิบัติตามขั้นตอนอย่างระมัดระวัง ย่อมสร้างความปลอดภัยให้ข้อมูลรวมถึงความน่าเชื่อถือของการให้บริการ(service availability)

ขั้นตอนที่ 1 ตรวจสอบพาร์ติชั่นเดิมกันก่อนว่ามีข้อมูลใดอยู่บ้าง และต้องการคัดลอกอิมเมจจากพาร์ติชั่นไหน จากตัวอย่างเราต้องการคัดลอกพาร์ติชั่น vm2_01 ขนาดข้อมูล 30 GBytes นั่นเอง อยู่ในกลุ่มโวลลุ่ม innova-vg โดยใช้คำสั่ง lvs

# lvs
  LV            VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
                              
  root          innova-vg -wi-ao----  19.08g                                    
  swap_1        innova-vg -wi-ao----  35.95g                                    
  vm2_01        innova-vg -wi-ao----  30.00g                                    
 

ขั้นตอนที่ 2 เป็นการสร้าง snapshot สำหรับพาร์ติชั่นที่ต้องการคัดลอก คำสั่งนี้สามารถทำได้โดยขั้นตอนดังต่อไปนี้ lvcreate นั่นเอง -L หมายถึง ขนาดของอิมเมจใหม่ -s หมายถึงสร้าง snapshot -n หมายถึงชื่อของอิมเมจใหม่ ตามด้วยพาร์ติชั่นที่ต้องการคัดลอก

#lvcreate -L30G -s -n vm2_01_snapshot innova-vg/vm2_01

ขั้นตอนที่ 3 หลังจากคัดลอก snapshot ได้แล้วก็เป็นขั้นตอนการสำรองข้อมูลของอิมเมจใหม่ที่สร้างขึ้นมานั่นเอง คำสั่งที่ใช้ก็คือ คำสั่ง dd ต้องใช้เวลาสักพักขึ้นอยู่กับขนาดของอิมเมจ


#dd if=/dev/innova-vg/vm2_01_snapshot of=/mnt/usb/vm2_04_ubuntu

ขั้นตอนที่ 4 เป็นการนำอิมเมจใหม่ที่ได้ทำการสำรองข้อมูลไว้ เพื่อใช้เป็นการสร้างพาร์ติชั่นใหม่ ขั้นตอนนี้ทำได้ไม่ยาก ต้องใช้เวลา  คำสั่งแรกเป็นการสร้างพาร์ติชั่นอิมเมจโดยใช้คำสั่ง lvcreate จากนั้นคัดลอกข้อมูลไปยังพาร์ติชั่นใหม่ที่สร้างเสร็จเรียบร้อยแล้ว โดยใช้คำสั่ง dd



#lvcreate -n vm2_04_ubuntu -L30G innova-vg
#dd if=/mnt/usb/vm2_04_ubuntu of=/dev/innova-vg/vm2_04_ubuntu
หรือหากต้องการดูว่าคำสั่ง dd ทำงานได้กี่เปอร์เซนต์ก็ให้ใช้คำสั่งนี้แทน
#dd if=/mnt/usb/vm2_04_ubuntu | pv -s 2G | dd of=/dev/innova-vg/vm2_04_ubuntu bs=4096
ขั้นตอนที่ 5 เป็นขั้นตอนสุดท้าย ให้ลบ snapshot ที่ได้สร้างไว้ในขั้นตอนที่ 2 ออก

#lvremove /dev/innova-vg/vm2_01_snapshot

สรุปว่าการคัดลอกพาร์ติชั่นอิมเมจ Ubuntu server ใหม่โดยใช้ lvm สามารถทำได้โดยขั้นตอนง่าย ๆ ข้างต้นไม่ต้องปิดเครื่องหรือออฟไลน์เพื่อดำเนินการด้วย แน่นอนที่สุดความน่าเชื่อถือของการให้บริการจะมีอย่างครบถ้วนสมบูรณ์นั่นเอง บทความดี ๆ เหล่านี้จะไม่สามารถดำเนินการได้เลย หากไม่ได้รับการสนับสนุนจาก บจก.ไทย พรอสเพอรัส ไอที ผู้นำด้านการให้บริการระบบจีพีเอสติดตามรถยนต์ ที่สมบูรณ์แบบที่สุดในปัจจุบัน พร้อมกันนี้เตรียมพบกับอุปกรณ์เซ็นเซอร์ระดับน้ำมันเชื้อเพลิงรุ่นใหม่ติดตั้งได้กับรถบรรทุกทุกทุกประเภท แม่นยำระดับสูงกว่ามาตรฐานโรงงาน เพื่อผู้ประกอบการขนส่งตัวจริงโดยเฉพาะ

วันพฤหัสบดีที่ 23 มีนาคม พ.ศ. 2560

สร้าง PHP ทำหน้าที่เป็น TCP server รองรับจำนวนลูกข่ายมากกว่า 10 เครื่องพร้อมกัน

บทความนี้ผู้เขียนใช้เวลาทดสอบมายาวนานกว่า 3 เดือนและสามารถใช้งานได้จริงรองรับจำนวนลูกข่ายเข้ามาแอคเซสในเวลาเดียวกันมากกว่า 10 เครื่องพร้อมกัน  การเขียนโปรแกรมแบบซ็อกเกต(socket)เพื่อรองรับจำนวนลูกข่ายเข้ามาใช้งานพร้อม ๆ กันสามารถทำได้อยู่หลายวิธีด้วยกัน แต่ที่พบมากมีอยู่ 3 แบบคือ forking หรือการสร้างโพรเซสลูก, threading หรือการทำงานพร้อม ๆกันยังไม่มีใน php และ select methods เป็นการรอเพื่ออ่านค่าเฉพาะที่มีการส่งมาจากลูกข่าย

สำหรับเนื้อหานี้จะใช้วิธีการที่เรียกว่า select methods โดยฟังก์ชั่น select จะทำงานเฉพาะเมื่อมีกิจกรรมเกิดขึ้นหรือมีการส่งข้อมูลจากฝั่งเครื่องลูกข่ายมายังเซิร์ฟเวอร์นั่นเอง โค๊ดเบื้องต้นผู้เขียนพัฒนาจากอินเทอร์เน็ต เน้นว่าเป็นสคริปง่าย ๆ สะดวกต่อการทำความเข้าใจ ไม่ต้องการไลบราลี่หรือสร้างเป็นคลาสให้ยุ่งยาก

<?php
        error_reporting(E_ALL);
        set_time_limit(0);
        ob_implicit_flush();
        $address = "0.0.0.0";
        $port = "4444";
        $client_socks = array();
        if (($server = socket_create(AF_INET, SOCK_STREAM,0))===false){
                echo "socket_create() failed: reason: ".socket_strerror(socket_last_error())."\n";
                die('something went wrong while creating');
        };
        if (socket_bind($server,$address,$port)===false){
                echo "socket_bind() failed: reason: ".socket_strerror(socket_last_error())."\n";
                die('something went wrong while binding');
        };
        if (socket_listen($server)===false){
                echo "socket_listen() failed: reason: ".socket_strerror(socket_last_error())."\n";
                die('something went wrong while listening');
        };
        while(true){
                //prepare readable sockets
                $read_socks = $client_socks;
                $read_socks[] = $server;
                //start reading and use a large timeout
                if(!socket_select ( $read_socks, $write, $except, 300000 )){
                        die('something went wrong while selecting');
                }
                //new client
                if(in_array($server, $read_socks)){
                        $new_client = socket_accept($server);
                        if ($new_client) {
                                //print remote client information, ip and port number
                                //echo 'Connection accepted from ' . socket_getsockname($new_client, true) . "n";
                                $client_socks[] = $new_client;
                                echo "Now there are total ". count($client_socks) . " clients.n";
                        }
                        //delete the server socket from the read sockets
                        unset($read_socks[ array_search($server, $read_socks) ]);
                }
                //message from existing client
                foreach($read_socks as $sock) {
                        $data = socket_read($sock, 128);
                        if(!$data){
                                unset($client_socks[ array_search($sock, $client_socks) ]);
                                socket_close($sock);
                                echo "A client disconnected. Now there are total ". count($client_socks) . " clients.n";
                                continue;
                        }
                        //send the message back to client
                        socket_write($sock, $data);
                }
        }


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

ต้องขอขอบพระคุณ บจก.ไทย พรอสเพอรัส ไอที ผู้นำด้านการให้บริการระบบจีพีเอสติดตามรถยนต์ รู้ลึกรู้จริงเรื่องติดตาม บริหารงานโดยทีมงานวิศวกร

วันอาทิตย์ที่ 15 มกราคม พ.ศ. 2560

การสำรองข้อมูลพาร์ติชั่นแบบ lvm โดยใช้ snapshot

 

วิธีการสำรองพาร์ติชั่นแบบ logical volumn management(lvm) โดยใช้ snapshot 

เป็นวิธีการที่สะดวกที่สุด โดยไม่ส่งผลกระทบต่อระบบการทำงานทั้งหมดของโอเอส กล่าวคือขั้นตอนการสำรองข้อมูลโดยทั่ว ๆ ไป ต้องทำการปิดระบบเกสต์โอเอสก่อน จากนั้นค่อยทำการคัดลอกเกสต์โอเอสอิมเมจไฟล์ไปยังฮาร์ดดิสก์ที่ใช้สำหรับสำรองข้อมูลนั่นเอง 

สำหรับการสำรองข้อมูลพาร์ติชั่นแบบ lvm โดยใช้ snapshot นั้นไม่ต้องปิดเครื่องที่เป็นเกสต์โอเอสทำให้ลูกค้าไม่ทราบว่าขณะนี้ระบบกำลังทำการสำรองข้อมูลอยู่นั่นเอง สำหรับเนื้อหาดี ๆเหล่านี้ต้องของขอบพระคุณเวบไซต์ดี ๆ thaigpstrackers.com ผู้นำด้านการให้บริการระบบติดตามรถยนต์ที่ทันสมัยที่สุด ประหยัดสุดในปัจจุบัน การดำเนินการสามารถทำได้โดยขั้นตอนต่อไปนี้

ขั้นตอนที่ 1 ตรวจสอบด้วยคำสั่ง lvs เพื่อตรวจสอบดูว่ามีพาร์ติชั่นไหนบ้างในระบบ จากตัวอย่างจะแสดงพาร์ติชั่นทั้งหมดประกอบไปด้วย vm2_02 อยู่ มีขนาดความจุ 80GB มีชื่อของ VG คือ innova-vg


# lvs
  LV            VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vm2_02                innova-vg owi-aos---  80.00g                                   

ขั้นตอนที่ 2 เป็นการสร้างพาร์ติชั่นแบบ snapshot ขนาด 80gb เพื่อทำการคัดลอกเกสต์โอเอสอิมเมจที่กำลังทำงานอยู่


#lvcreate -L80G -s -n vm2_02_snapshot innova-vg/vm2_02

ขั้นตอนที่ 3 ใช้คำสั่ง lvs ตรวจสอบพาร์ติชั่นที่ทำการสร้างขึ้นมาใหม่ จะพบว่ามีพาร์ติชั่น vm2_02_snapshot ขนาด 80gb ที่ถูกสร้างในขั้นตอนที่ 2 นั่นเอง


# lvs
  LV            VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  vm2_02                innova-vg owi-aos---  80.00g                                
  vm2_02_snapshot innova-vg swi-a-s---  80.00g      vm2_02 1.16                                          

ขั้นตอนที่ 4 เป็นการสำรองข้อมูลไปยัง USB drive หรือ external harddisk โดยใช้คำสั่ง dd หลังจากสำรองของมูลเสร็จเรียบร้อยแล้วให้ดำเนินการตามขั้นตอนถัดไป


#dd if=/dev/innova-vg/vm2_02_snapshot of=/mnt/usb/idcbackup/vm2_02

 หรือต้องการดูความก้าวหน้าของการทำงานของคำสั่ง dd

#dd if=/dev/innova-vg/vm2_02_snapshot | pv -s 80G | dd of=/mnt/usb/idcbackup/vm2_02 bs=4096

 

ขั้นตอนที่ 5 เป็นการลบ snapshot ที่ได้สร้างขึ้นมาออก เป็นขั้นตอนสุดท้ายของการดำเนินการ


#lvremove /dev/innova-vg/vm2_02_snapshot

จะพบว่าการดำเนินการทั้งหมดสามารถทำได้โดยมีขั้นตอนที่ไม่ยุ่งยาก และสามารถทำได้ทันที ย่อมเป็นวิธีการที่แนะนำให้ใช้กันแทนวิธีเดิม เพราะไม่ต้องปิดระบบเพื่อทำการสำรองข้อมูลนั่นเอง ผู้เขียนเองมีระบบเกสต์โอเอสที่จำเป็นต้องปิดระบบเพื่อทำการสำรองข้อมูลอยู่พอสมควร เนื้อหาในเรื่องต่อ ๆ ไปจะได้ศึกษาวิธีการย้ายจากระบบเดิมมาเป็นแบบ lvm ทั้งหมด