월별 글 목록: 2014년 6월월

LSB Init 표준을 기반으로 리눅스 Init 스크립트를 작성하는 법

참조 원문 : How to Write Linux Init Scripts Based on LSB Init Standard

  LSB란 Linux Standard Base의 약자로서 리눅스 재단이 배포판 사이의 차이점을 줄여 다른 배포판으로 이식할 때 드는 비용을 줄이기 위해 만든 표준입니다. Init 스크립트도 표준화된 것들 중 하나입니다.

  Init 스크립트는 소프트웨어나 서비스를 시작하거나 중단할 때 사용합니다. 예를 들어 postgresql 소프트웨어를 사용하고 있다면 /etc/init.d/postgresql 이라는 Init 스크립트를 가지고 있을 것이며 인자로 start, stop, restart, reload, force-reload, status를 사용할 수 있습니다.

  LSB 호환 Init 스크립트는 아래 사항을 지켜야 합니다.

  • 최소한 ‘start, stop, restart, force-reload, status’를 제공해야 한다.
  • 적절한 exit code를 return해야 한다.
  • 실행 의존성(run-time dependencies)을 문서화해야 한다.

  추가적으로 이 스크립트들은 메시지를 남기기 위해 “log_success_msg”나 “log_failure_msg” 같은 init.d 함수를 사용할 수 있습니다.

  LSB는 /lib/lsb/init-functions에 있는 기본 함수들을 제공합니다. Init 스크립트로 실행되는 프로세스들은 /var/run/ 디렉토리에 프로세스의 pid를 기록하는데 이것은 Init 스크립트가 프로세스의 상태를 조사할 때 큰 도움이 됩니다.

  이제 Init 스크립트를 작성해봅시다. 먼저 아래처럼 헤더를 넣습니다.

### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO

  Provides에는 해당 Init 스크립트가 제공하는 기능(facility=서비스)을 적습니다. 이 이름은 유일해야 합니다.

  Requred-Start에는 이 서비스를 시작하기 전에 작동하고 있어야 하는 일련의 기능들을 적습니다. 이 예제의 경우 postgresql과 networking이 미리 실행되어 있어야 함을 나타내고 있습니다. 기억해야 할 점은 이 ‘postgresql’가 ‘Provides: postgresql’이라고 적힌 별도의 Init 스크립트를 가지고 있어야 한다는 것입니다. 이를 통해 부팅 시 의존성을 보장합니다. ‘inserv’ 명령어나 ‘update-rc.d’ 명령어를 사용할 때 이 의존성을 바탕으로 대상 런레벨 디렉토리에 적절한 순번을 매겨 집어넣게 됩니다.

/etc/rc2.d/S12postgresql
/etc/rc2.d/S03networking
/etc/rc2.d/S13my_daemon

  예를 들어 위와 같은 엔트리가 있을 경우 networking, postgresql, my_daemon 순서로 실행됩니다.

  Required-Stop에는 이 기능을 중단한 후에만 중단할 수 있는 일련의 기능들을 적습니다. 이 예제의 경우 my_daemon이 중단된 후에만 postgresql과 networking 기능을 중단할 수 있습니다.

  Default-Start Default-Stop에는 이 서비스가 시작되거나 중단돼야 하는 런레벨을 정의합니다.

  Short-Description Description에는 해당 기능에 대한 설명을 적습니다. Short-Description에는 한 줄만 적을 수 있으며, Description에는 여러 줄에 걸쳐 적을 수 있습니다.

  아래는 실제 Init 스크립트의 예입니다.

### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO

# Using the lsb functions to perform the operations.
. /lib/lsb/init-functions
# Process name ( For display )
NAME=my-daemon
# Daemon name, where is the actual executable
DAEMON=/home/user1/my_daemon
# pid file for the daemon
PIDFILE=/var/run/my_daemon.pid

# If the daemon is not there, then exit.
test -x $DAEMON || exit 5

case $1 in
 start)
  # Checked the PID file exists and check the actual status of process
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON “$NAME process” && status=”0″ || status=”$?”
   # If the status is SUCCESS then don’t need to start again.
   if [ $status = “0” ]; then
    exit # Exit
   fi
  fi
  # Start the daemon.
  log_daemon_msg “Starting the process” “$NAME”
  # Start the daemon with the help of start-stop-daemon
  # Log the message appropriately
  if start-stop-daemon –start –quiet –oknodo –pidfile $PIDFILE –exec $DAEMON ; then
   log_end_msg 0
  else
   log_end_msg 1
  fi
  ;;
 stop)
  # Stop the daemon.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON “Stoppping the $NAME process” && status=”0″ || status=”$?”
   if [ “$status” = 0 ]; then
    start-stop-daemon –stop –quiet –oknodo –pidfile $PIDFILE
    /bin/rm -rf $PIDFILE
   fi
  else
   log_daemon_msg “$NAME process is not running”
   log_end_msg 0
  fi
  ;;
 restart)
  # Restart the daemon.
  $0 stop && sleep 2 && $0 start
  ;;
 status)
  # Check the status of the process.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON “$NAME process” && exit 0 || exit $?
  else
   log_daemon_msg “$NAME Process is not running”
   log_end_msg 0
  fi
  ;;
 reload)
  # Reload the process. Basically sending some signal to a daemon to reload
  # it configurations.
  if [ -e $PIDFILE ]; then
   start-stop-daemon –stop –signal USR1 –quiet –pidfile $PIDFILE –name $NAME
   log_success_msg “$NAME process reloaded successfully”
  else
   log_failure_msg “$PIDFILE does not exists”
  fi
  ;;
 *)
  # For invalid arguments, print the usage message.
  echo “Usage: $0 {start|stop|restart|reload|status}”
  exit 2
  ;;
esac

  위 스크립트는 LSBInit 스크립트 작성을 위한 템플릿입니다. DAEMON, PIDFILE, NAME 변수, 헤더 등을 적절히 바꿔 사용할 수 있습니다.

  LSB가 제공하는 함수에 대해 더 알고 싶다면 InitScript Functions를 참조하시기 바랍니다.

  Init 스크립트를 작성한 후 자동으로 시작되거나 중단되게 만들려면 아래 형식으로 명령어를 실행합니다.(데비안 계열 기준)

update-rc.d filename defaults

  이 명령어는 지정한 런레벨에 의존성을 고려한 적절한 순번을 가진 ‘S’와 ‘K’ 엔트리를 추가합니다.

예제로 배우는 sed

참조 원문1 : SED(Stream EDitor ) Explained in detail for Linux/Unix
참조 원문2 : Learn SED with examples

1. 검색과 치환(s는 search의 약자)
  아래는 단어를 찾아 다른 단어로 치환하는 문법이다.
sed ‘s/searchterm/replaceterm/’ inputfile
또는
cat inputfilename | sed ‘s/searchterm/replaceterm/’
또는
echo “This is test message” | sed ‘s/searchterm/replaceterm/’

예제1: test.txt 파일에서 google을 찾아 yahoo로 치환
sed ‘s/google/yahoo/’ test.txt

예제2: sed는 기본적으로 처음 찾은 단어만 치환한다. 모든 단어를 치환하려면 g 스위치를 사용해야 한다.
echo “sheena leads, sheila needs” | sed ‘s/sh/le/g’

예제3: Separator 변경법. Separator가 검색하려는 단어에 포함된 경우 유용하다. 예를 들어 /var/ftp/pub을 검색하여 /opt/ftp/com으로 치환하려고 할 때 아래처럼 해도 제대로 작동하지 않는다.
sed ‘s//var/ftp/pub//opt/ftp/com/’ test.txt
이럴 땐 separator를 /에서 #나 $ 같은 다른 문자로 바꿔야 한다. 아래는 _를 사용하는 예제다.
sed ‘s_/var/ftp/pup_/opt/ftp/com_’ test.txt

예제4: 아래는 surendra를 Mr. surendra로 바꾸는 예제다.
sed ‘s/surendra/Mr. &/’ test.txt

예제5: 아래는 abc123suri 같은 패턴을 suriabc123으로 바꾸는 예제다.
echo “abc123suri” | sed ‘s/([a-z]*)([0-9]*)([a-z]*)/312/’


2. 출력(-n과 p 스위치)
예제6: 기본적으로 sed는 모든 줄을 출력하지만 -n(출력 억제)과 p 옵션을 사용하여 바뀐 줄만 출력할 수 있다.
cat tem.txt | sed -n ‘s/surendra/bca/p’


3. 수정(-i, w, d 스위치와 쉘 리다이렉션)
예제7: -i 옵션을 사용하면 변경점을 원본 파일에 적용할 수 있다.
sed –i ‘s/bca/Surendra/’ tem.txt

예제8: 리다이렉션으로도 같은 일을 할 수 있다.
sed ‘s/baby/dady/’ < tem.txt > abc.txt

예제9: w 옵션으로 변경점을 다른 파일에 저장할 수 있다.
sed ‘s/baby/dady/w abc.txt’ tem.txt


4. 여러 SED 명령어와 연속 연산자(-e와 ; 스위치)
예제10: Surendra, mouni, baby를 bca, mca, bba로 치환
sed -e ‘s/surendra/bca/’ -e ‘s/mouni/mca/’ -e ‘s/baby/bba/’ tem.txt

예제11: ;(연속 연산자)로 더 위보다 더 줄이기
sed ‘s/Surendra/bca/;s/mouni/mca/;s/baby/bba/’ tem.txt


5. 줄 번호 연산자(,와 = 스위치)
예제12: 3번째 줄 내용만 검색해서 치환하기
sed ‘3 s/Surendra/bca/’ tem.txt

예제13: 1~4번째 줄 내용만 검색해서 치환하기
sed ‘1,4 s/Surendra/bca/’ tem.txt

예제14: 2번째 줄에서부터 문서 끝까지 검색해서 치환하기
sed ‘2,$ s/Surendra/bca/’ tem.txt

예제15: 매 두 줄마다 한 줄로 결합. 아래는 N 옵션으로 두 줄을 합치는 예제. 치환으로 \n을 공백 같은 것으로 바꿔줘야 원하는 의도대로 나온다. sed는 기본적으로 한 줄씩 처리하여 출력하는데 두 줄을 하나로 합쳐놔도 라인피드(\n)가 그대로 남아있기 때문에 전혀 변하지 않은 것처럼 보이기 때문이다. 그리고 사실 아래 소개할 예제를 위해서 말고는 잘 안 쓰인다.
sed ‘N;s/\n/ /’ tem.txt

예제16: 검색해서 치환 후 모든 줄에 번호 넣기(‘=’ 옵션 사용)
sed = tem.txt

예제17: 번호를 같은 줄에 넣기
sed = tem.txt | sed ‘N;s/n/t/’


6. 검색 연산자(/단어/)
예제18: 한 단어를 검색해서 걸린 줄에서 작업하기
sed ‘/surendra/ s/audi/xyz/’ tem.txt

예제19: 위를 응용해서 특정 범위의 줄 내에서 작업하기
sed ‘3,/Surendra/ s/audi/xyz/’ tem.txt

예제20: 더 응용해서 찾은 단어가 있는 줄부터 문서 끝까지를 범위로 작업하기
sed ‘/Surendra/,$ s/audi/xyz/’ tem.txt


7. 부정 연산자(!)
  이 연산자는 w, p, d 옵션과 함께 사용한다.
예제21: abc 라는 단어가 없는 모든 줄을 출력
sed –n ‘/abc/ !p’ tem.txt

예제22: surenda 라는 단어가 있는 줄을 제외한 모든 줄을 삭제
sed ‘/surendra/ !d’ tem.txt

예제23: 1~3 줄만 빼고 모든 줄 삭제
sed ‘1,3 !d’

bash의 잘 알려지지 않은 기능 7가지

참조 원문 : 7 hidden features of bash

1. 이전 명령어 다시 실행
  sudo를 사용 안 하고 root 권한이 필요한 명령어를 했을 때 아주 유용한 기능. 파라미터로 !! 를 입력하면 마지막으로 실행했던 명령어를 반복한다. 예를 들어 apt-get 명령어를 사용했는데 sudo를 쓰지 않아서 앞에 sudo를 붙여 다시 실행해야 하다면 sudo !! 라고 실행한다.

2. bash 스크립트
bash -n bashscript.sh  ->  실제로 스크립트를 실행하지 않고 문법만 검사.
bash -x bashscript.sh  ->  디버그 모드로 스크립트 실행. 각 명령어와 그 결과를 단축하여 출력.

3. 이전 명령어의 특정 문자열을 치환
  ^이전문자열^새문자열^ 문법으로 달성할 수 있다.

$ sudo apt-get install wrongpackagename
$ ^wrongpackagename^rightpackagename^
sudo apt-get install rightpackagename

  sed나 vi와 비슷한 다른 방법도 있다.

$ sudo apt-get install wrongpackagename
$ !!:s/wrongpackagename/rightpackagename
sudo apt-get install rightpackagename


4. 이전 줄의 마지막 파라미터 사용
  가끔 명령어에서 긴 파라미터를 썼는데 그걸 또 써야 할 때가 있다. 예를 들어 어떤 디렉토리를 만들고 그 디렉토리로 이동하려고 할 때 아래와 같은 방법으로 이동할 수 있다.

# mkdir -p /this/is/mylong/pathto/some/directory
# cd $_

  $_는 마지막에 사용했던 명령어의 마지막 파라미터를 뜻한다. 그 이전 명령어들의 마지막 파라미터를 사용하고 싶다면 ‘Alt + .’ 단축키를 사용하면 된다. 이 단축키를 사용하면 마지막 파라미터를 출력하며, 한 번 더 누를 때마다 그 이전 명령어의 마지막 파라미터를 출력한다.

5. 지금 있는 디렉토리에서 하위 디렉토리만 출력

ls -d */

  -d 옵션은 디렉토리 엔트리만 보여주는 옵션이지만 파라미터를 입력하지 않으면 현재 디렉토리를 파라미터로 사용하기 때문에 ‘.’만 나온다.

6. 예전 명령어 검색
  ‘Ctrl + r’을 누르면 예전에 사용한 명령어를 검색할 수 있다. Ctrl + r을 누르고 타이핑을 치면 입력한 모든 텍스트를 포함하고 있는 명령어들 중 가장 최근에 사용한 것을 보여주며 Ctrl + r을 누를 때마다 더 오래된 명령어를 보여준다. 만약 지나쳤다면 Ctrl + s를 눌러 앞으로 검색하면 된다.

  하지만 Ctrl + s는 일반적으로 XOFF(interrupt data flow)로 맵핑되어 있는데 현대에는 거의 필요가 없는 기능이므로 stty -ixon 명령어를 통해 맵핑을 끊으면 된다.

7. 길고 복잡고 어려운 명령어를 입력하기 위해 기본 편집기($EDITOR 환경 변수에 설정된 에디터) 즉시 소환
  명령어를 쓰다가 Ctrl + x + e를 누르면 편집기가 실행되면서 쓰던 명령어가 그곳에 적힌다. 편집기에서 명령어를 완성하고 저장 후 종료하면 작성했던 내용이 쉘에서 실행된다.

고가용성 환경에서 cron을 운용하기 위한 rcron

참조 원문 : What is RCRON.. & How to Setup High Availability of cron Jobs Using RCRON

  HA(High Availability) 환경에서 cron을 사용해보신 분들이라면 이 프로그램이 유용하단 걸 동감하실 수 있으실 겁니다. 서버가 2대 있고 이 2대가 클러스터 구성일 때 액티브 서버에서만 실행되어야 할 cron 스케줄이 있다면 꽤 귀찮은 일이 생깁니다. 액티브와 스탠바이가 바꼈을 때 두 서버의 cron을 수동으로 수정해야 하기 때문이죠. Rcron은 이런 경우에 사용하는 프로그램으로서 구성 서버들 간의 상태를 확인하고 액티브 상태의 서버에서만 지정한 작업을 실행할 수 있게 해줍니다.

  그런데 rcron은 다른 서버의 생존을 파악하는 능력이 없기 때문에 그 역할을 위한 프로그램을 추가로 함께 사용해야 합니다. 이를 위해 이 글에서는 keepalived라는 별도의 데몬을 사용할 것입니다. Keepalived는 상대 노드에 신호를 보내고 응답이 없을 경우 링크가 죽었다고 판단하는 역할을 합니다.

  여기서는 하나의 노드를 keepalived 마스터로 설정하고 다른 한 노드를 keepalived 백업으로 설정할 겁니다. 마스터 노드는 rcron 상태가 액티브로 되며, 백업 노드는 패시브로 설정됩니다. 마스터 노드는 죽을 때 백업 노드에게 0 우선순위 신호를 보내며 이를 받은 백업 노드는 마스터 노드가 되어 rcron을 액티브 상태로 전환합니다. 그러다가 이전의 마스터 노드가 다시 살아나면 마스터 권한을 넘긴 후 백업 모드로 돌아가게 설정할 겁니다.

  설정 환경은 레드햇 계열 배포판인 것으로 가정합니다.


1. /etc/sysctl.conf 파일을 수정하여 두 노드의IP 포워딩 활성화시키기

net.ipv4.ip_forward = 1
# sysctl -p      ; 리부팅 없이 변경사항 적용


2. 두 노드에 EPEL 저장소 추가

# wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# rpm -ivh epel-release-6-8.noarch.rpm


3. 두 노드에 필요한 패키지 설치

# yum install subversion byacc flex gcc


4. 프록시 서버를 통해 인터넷 연결을 할 경우 svn에 대한 http_proxy 설정(직접 인터넷 연결을 할 경우 생략)

# mkdir /root/.subversion/
#  vi ~/.subversion/servers
http-proxy-exceptions = *.example.com
http-proxy-host = www.example.com
http-proxy-port = 8080
http-compression = no


5. SVN으로 rcron 설치

# cd /root;
# svn co http://rcron.googlecode.com/svn/trunk rcron
# cd rcron/rcron
# ./configure
# make
# make install


6. 두 노드에 디렉토리 및 설정 파일 생성

# mkdir /etc/rcron/
# vi /etc/rcron/rcron.conf

(1) 마스터 서버 노드
  아래 내용 입력

# An arbitrary name
cluster_name        = cluster

# A file containing either the word “active” or the word “passive”
state_file          = /var/run/rcron/state

# The default state in case state_file can’t be read
#default_state       = active
syslog_facility     = LOG_CRON
syslog_level        = LOG_INFO

# We can tune jobs niceness/priorities
nice_level          = 19

  아래 명령어 실행

# mkdir /var/run/rcron
# touch /var/run/rcron/state
# echo “active” > /var/run/rcron/state

(2) 백업 서버 노드
  아래 내용 입력

# An arbitrary name
cluster_name = cluster
# A file containing either the word “active” or the word “passive”
state_file = /var/run/rcron/state
# The default state in case state_file can’t be read
#default_state = passive
syslog_facility = LOG_CRON
syslog_level = LOG_INFO
# We can tune jobs niceness/priorities
nice_level = 19

  아래 명령어 실행

# mkdir /var/run/rcron
# touch /var/run/rcron/state
# echo “passive” > /var/run/rcron/state


7. 두 노드에 Keepalive 패키지 설치
(1) 최신 소스 다운로드

# cd /root
# wget http://cgit.luffy.cx/keepalived/snapshot/keepalived-1.2.7.tar.gz

(2) RPM BUILD 패키지 설치

# yum -y install rpm-build

(3) 압축 풀기 및 keepalived.spec.in 파일 수정

# tar -zxvf keepalived-1.2.7.tar.gz
# mkdir -p /root/rpmbuild/SOURCES/
# cp /root/keepalived-1.2.7.tar.gz /root/rpmbuild/SOURCES/
# vi /root/keepalived-1.2.7/keepalived.spec.in
(Version 1.2.2를 Version 1.2.7로 수정)
# yum -y install popt*
# cd /root/keepalived-1.2.7
# rpmbuild -ba keepalived.spec.in

  위 명령어를 사용하면 소스를 이용해 컴파일된 RPM이 /root/rpmbuild/RPMS/x86_64/keepalived-1.2.7-5.x86_64.rpm라는 경로 및 파일명으로 생성됩니다. 이 파일을 이용해 설치합니다.

# rpm -ivh /root/rpmbuild/RPMS/x86_64/keepalived-1.2.7-5.x86_64.rpm


8. keepalived 설정
(1) 마스터 노드(172.16.243.144)

# vi /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
state MASTER
interface eth0
lvs_sync_daemon_inteface eth0
virtual_router_id 31
priority 101
advert_int 5
vrrp_unicast_bind 172.16.243.144
vrrp_unicast_peer 172.16.243.145

authentication {
auth_type PASS
auth_pass 1111
}

notify_backup “/bin/echo passive > /var/run/rcron/state”
notify_master “/bin/echo active > /var/run/rcron/state”
notify_fault “/bin/echo passive > /var/run/rcron/state”
}

(2) 백업 노드(172.16.243.145)

# vi /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
state BACKUP
interface eth0
lvs_sync_daemon_inteface eth0
virtual_router_id 31
priority 100
advert_int 5
vrrp_unicast_bind 172.16.243.145
vrrp_unicast_peer 172.16.243.144

authentication {
auth_type PASS
auth_pass 1111
}

notify_backup “/bin/echo passive > /var/run/rcron/state”
notify_master “/bin/echo active > /var/run/rcron/state”
notify_fault “/bin/echo passive > /var/run/rcron/state”
}


9. 두 노드에 실험용 crontab 항목 생성

* * * * * /usr/local/bin/rcron –conf /etc/rcron/rcron.conf echo `date` >> /tmp/output

  두 노드 모두 keepalive 서비스를 시작합니다.

# service keepalived start ; chkconfig keepalived on


10. keepalived 데몬이 죽을 경우에 대비
  아래의 crontab 항목을 추가합니다.

* * * * * * /root/keep-alive-monitor

  그리고 아래 스크립트를 생성합니다.

# vi /root/keep-alive-monitor

#!/bin/sh
echo “test” >> /tmp/monitor;
ps -ef|grep -v grep|grep -i keepalived;
if [ $? -eq 0 ] ; then
exit 0
else
echo “passive” > /var/run/rcron/state;
/etc/init.d/keepalived restart;
fi

 

mysql replication

MySQL 에서  Replication 이 적용되는 방식은 아래 그림을 요약할 수 있다.

1. Master 에서 데이터의 변경작업이 발생하면 Master DB의 변경 실행

2. 변경된 이력을 Binary Log 에 기록

3. Slave 의 IO Thread 가 Master 의 변경 Event 를 감지하고 Master 의 Binary Log 를 자신(Slave)의 Relay Log 에 기록한다.

4. Slave 의 SQL Thread 는 Relay Log 를 읽고 자신(Slave)의 DB에 기록한다.

위 그림에서처럼 Master 에서 Slave 방향으로 단방향으로만 처리가 이루어 지므로 변경작업(Write)는 Master에만 하여야 한다.

Slave에서 변경작업을 할 경우 Master에는 당연히 반영이 안되며, Slave에서 변경작업한 Object 에 대하여 Master 서 변경작업을 다시 시도할 경우 변경은 되지만 다시 slave에 는 적용되지 않는다.

린킨파크

[embedplusvideo height=”500″ width=”625″ editlink=”http://bit.ly/1l6PnCa” standard=”http://www.youtube.com/v/MntoTf90Mx4?fs=1″ vars=”ytid=MntoTf90Mx4&width=625&height=500&start=&stop=&rs=w&hd=0&autoplay=0&react=1&chapters=&notes=” id=”ep7148″ /]

일산 토네이도

[embedplusvideo height=”500″ width=”625″ editlink=”http://bit.ly/1l6M3qQ” standard=”http://www.youtube.com/v/RyXtlvVnHeA?fs=1″ vars=”ytid=RyXtlvVnHeA&width=625&height=500&start=&stop=&rs=w&hd=0&autoplay=0&react=1&chapters=&notes=” id=”ep2423″ /]