Topic List
#ffffff; display: block; color: #000000; font-weight: normal; font-size: 10px; text-decoration: underline; text-align: center;" target="_blank">Online video chat by Ustream
ปัญหาเกิดมาจาก script สำหรับตรวจสอบสถานะและแสดงชื่อเพลงที่กำลังเปิดอยู่นั้นกิน CPU time เยอะมาก และ script นั้นยังถูกกำหนดให้ refresh ทุก 30 วินาที เมื่อมีคนเปิดฟังวิทยุพร้อมกับดูสถานะเป็นจำนวนมาก จะทำให้เกิดปัญหากับ CPU load
เลยศึกษา script นั้นดูและเปลี่ยนวิธีการเพื่อไม่ให้เกิด CPU load
แนวทางการทำงานของ script เดิมที่เป็นอยู่
- จะดึงข้อมูลของ Shoutcast จาก host ด้วย fsocket method GET จำนวน 2 ครั้ง คือ ชื่อเพลง กับจำนวนคนฟัง โดยกำหนด timeout ไว้ที่ 6 วินาที
- ตัดข้อความที่ไม่ต้องการออกและแยกแยะเอาข้อความที่ต้องการออกมา
- แสดงผลในหน้าเว็บโดยให้ refresh ทุก ๆ 30 วินาที
ปัญหาที่เกิดขึ้นคือ
- การดึงข้อมูลผ่าน fsocket แต่ละครั้งใช้เวลาพอสมควรเนื่องจาก script อยู่คนละที่กับ Shoutcast server
- เกิด CPU load ในกระบวนการไหนไม่แน่ใจ
- จำนวน request ที่เยอะมากเกิดจาก จำนวนคนฟังหรือหน้าเว็บที่เปิดดูสถานะ x 2 คร้ง/นาที เช่น 150x2=300 ครั้ง/นาที = 5 ครั้ง/วินาที ทำ script ทำงานไม่ทัน
แนวทางใหม่ที่คิดคือ
แทนที่จะให้ทุกคน request แล้วต้องอ่านข้อมูลทุกครั้ง ก็ให้ script ทำงานอัตโนมัติทุก ๆ 30 วินาที ไปดึงข้อมูลจาก Shoutcast แล้วบันทึกเก็บไว้ในไฟล์ แล้วให้ทุกคนอ่านจากไฟล์นี้แทน
ดูตัวอย่าง script ได้จากด้านในนะครับ
ผมทดลองเปิดสถานีวิทยุออนไลน์ ซึ่งมีหลายสถานี (port) และต้องการให้มันเปิดแบบอัตโนมัติในตอนเปิด server ก็ไปเจอวิธีการและ code ในเว็บนี้
ลองทำตามโค๊ดข้างล่าง
#!/bin/bash
#
# chkconfig: 345 91 35
# description: Starts and stops sc_serv.<br />
# You know, the mp3 streaming thang.
#
# Version 1.3 (nov 4 2001)
# Now with more revisions! System now checks for pid file before cat
# to display so that we receive no error messages. System also displays
# pids as we are killing old processes. Profanity was removed from the<br />
# startup messages. Tests for a pid file before reporting success. Displays
# the relay server name when we start the daemon up, so that we know
# which servers are getting booted. Pushed the success marker over to the<br />
# right and added [] because I am just a slave to fashion.
#
# Version 1.2 (nov 3 2001)
# Same exact shit, but runs as nobody for security reasons. Just
# in case we are worried about buffer overflows or whatnot.
#
# Version 1.1 (nov 3 2001)
# Starts stops and restarts jobs. Also checks for existing daemons
# before calling a start, and exits without starting new ones. This
# prevents you from being a dumbass and starting multiple listeners
# on the same port. I would suggest using the restart command
# in these cases. Also creates a shoutcast.pid file that can be used
# to discover all of the (many) pids used by shoutcast when running.
#
# Version 1.0 (nov 3 2001)<br />
# Starts and stops successfully.<br />
# Kills old jobs on start command. Dirty, but<br />
# does the job well enough. Tested functional on
# mandrake version 8.1 but should work on redhat<br />
# or any other distro that supports a standard<br />
# sysv startup script.
#
# Instructions for use.
# 1: untargzip shoutcast into the directory of your choosing
# 2: copy sc_serv into the /usr/sbin directory<br />
# 3: Create the directory /etc/shoutcast
# 4: copy the shoutcast.conf file into your /etc/shoutcast dir.
# 5: Edit the shoutcast.conf file to match your needs.
# 6: Make as many more conf files as needed to support<br />
# multiple streams. Be sure to edit these files so that
# you are not starting multiple shoutcast servers that
# are either listening or broadcasting on the same port.
# 7: Copy this file into the /etc/rc.d/init.d directory
# 8: chmod this file +x (chmod ug+x /etc/rc.d/init.d/shoutcast)
# 9: run chkconfig --add shoutcast from the /etc/rc.d/init.d dir.
# 10:Run /etc/rc.d/init.d/shoutcast start<br />
# 11:Drink a beer, or light one up, and enjoy the tunes.
#
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up. This line may cause an error on incompatible
# distributions. Remove it if necessary. Also remove if the startup always
# fails for no apparent reason.
[[ ${NETWORKING} = "no" ]] && exit 0<br />
<br />
<br />
stop (){
<a class="hashtag" href="/tags/First">#First</a> we want to kill the original servers, so we don't get errors.
echo "Killing old shoutcast servers."
for oldpid in `ps -A | grep sc_serv | cut -c 0-6`; do
kill -9 $oldpid
if [[ $1 == "-v" ]]
then
echo $oldpid
fi
done
rm -f /var/run/shoutcast.pid
}<br />
<br />
<br />
start (){
<a class="hashtag" href="/tags/Now">#Now</a> we can start the servers up.
if [[ $1 == "-v" ]]<br />
then
echo "Starting up the new shoutcast servers. Starting..."
fi
<br />
servcount=`expr 0`
for cfile in `ls /etc/shoutcast`; do
echo -n $cfile
echo -n " -> "
grep ^RelayServer /etc/shoutcast/$cfile
# This is the line where we actually run the shoutcast program!
<a class="hashtag" href="/tags/sudo">#sudo</a> -u nobody /usr/bin/sc_serv /etc/shoutcast/$cfile > /dev/null &
/usr/bin/sc_serv /etc/shoutcast/$cfile > /dev/null &
let servcount=servcount+1
done
<a class="hashtag" href="/tags/Create">#Create</a> the pid file...
ps -A | grep sc_serv | cut -c 0-6 > /var/run/shoutcast.pid
<a class="hashtag" href="/tags/Done">#Done</a> now!
echo "Started $servcount servers."
}<br />
<br />
<br />
case "$1" in
start)
if [[ ! -e /var/run/shoutcast.pid ]]
then
start $2
if [[ -e /var/run/shoutcast.pid ]]<br />
then
echo "Startup [SUCCESS]"
fi
else
if [[ $2 == "-v" ]]
then
echo "Shoutcast is already running these processes:"
#Toldja! Checks before displaying pid file.
if [[ -e /var/run/shoutcast.pid ]]
then
cat /var/run/shoutcast.pid
fi
echo "Try calling shoutcast restart in order to kill old processes."
else
echo "SC_SERV is already running. Try calling shoutcast restart."
fi
echo "Startup [FAILED]"
fi
;;
restart)
stop $2
if [[ $2 == "-v" ]]
then
echo "Waiting for the old servers to die..."
fi
sleep 4
start $2
if [[ -e /var/run/shoutcast.pid ]]<br />
then
echo "Startup [SUCCESS]"
fi
;;
stop)
if [[ -e /var/run/shoutcast.pid ]];
then
stop $2
echo "Shoutcast shutdown [SUCCESS]"
else
echo "There are no registered shoutcast servers running right now. Attempting to kill anyways."
stop $2
fi
;;
*)
echo "Usage: shoutcast (start|stop|restart) [-v]"
esac
ขั้นตอนการติดตั้ง
- สร้างไฟล์ /etc/init.d/shoutcast แล้วเปลี่ยน attr เป็น 755
- copy ไฟล์ sc_serv (ที่ดาวน์โหลดมา) ไปไว้ที่ /usr/bin
- สร้างโฟล์เดอร์ /etc/shoutcast แล้วนำไฟล์คอนฟิกมาใส่ไว้ในนี้ จะกี่ไฟล์ก็ได้ ตอนเปิดเครื่องมันจะ start ให้หมด