TVH 스트리밍 QOS 스크립트 (리눅스 네트워크 대역폭 제한 / wondershaper)

category 서버/리눅스 서버 2019. 9. 15. 11:28

안녕하세요? 


저는 공유기 1번 포트를 공인아이피로 설정하여 TVH를 사용중입니다.


이때 IGMP 를 이용한 동일 네트워크 상에서 사용하는 방식 보다는 끊김이 덜하지만, 메인 서버에서 극한 작업을 할 경우 끊기는 것은 마찬가지 입니다.


그래서 리눅스로 된 메인 서버의 인터넷 속도를 TVH 스트리밍 갯수에 맞추어 제한 하기로 했습니다.


반기가 였다면, 이런 고민을 하지 않았을 거 같은데 아직 100메가 인터넷이라 이런 고민을 하고 있습니다.


아래의 구조라면, 아래의 설정으로 쓰고 계시다면, 혹시 비슷한 고민을 하고 계시다면 참고해보시길 바랍니다.




일단 tvh의 스트림 카운트 정보를 api 를 통해 받아와야합니다. 아래 주소를 들어가 보시면 스트림 갯수를 알 수 있습니다.


https://tvhurl:9981/api/status/subscriptions



이 정보를 리눅스 쉘 스크립트로 처리하기 위해 jq 라는 패키지를 설치합니다.


apt install jq curl


쉘에서 한번 받아 보겠습니다. curl 로 데이터를 받고 pipe 로 jq에 넘겨주면 아래와 같은 정렬이 가능합니다.


그리고 필요한 필드에 대해서 .totalCount 라고 하면 스트림 갯수를 알 수 있습니다.


root@openmediavault:~# curl -s http://ect.com:9981/api/status/subscriptions | jq .

{

  "entries": [

    {

      "id": 346,

      "start": 1568514186,

      "errors": 0,

      "state": "Running",

      "hostname": "",

      "username": "admin",

      "client": "VLC/3.0.7.1 LibVLC/3.0.7.1",

      "title": "HTTP",

      "channel": "C TIME",

      "service": "C TIME/C TIME",

      "pids": [

        655,

        1655,

        2655,

        3655

      ],

      "profile": "pass",

      "in": 1321076,

      "out": 1321076,

      "total_in": 162325404,

      "total_out": 162325404

    },

    {

      "id": 345,

      "start": 1568514037,

      "errors": 0,

      "state": "Running",

      "hostname": "",

      "username": "admin",

      "client": "VLC/3.0.4 LibVLC/3.0.4",

      "title": "HTTP",

      "channel": "KBS2",

      "service": "KBS2/KBS2",

      "pids": [

        61,

        62,

        63

      ],

      "profile": "pass",

      "in": 1554008,

      "out": 1554008,

      "total_in": 422708224,

      "total_out": 422708224

    }

  ],

  "totalCount": 2

}



root@openmediavault:~# curl -s http://ject.com:9981/api/status/subscriptions | jq .totalCount

2


다음으로 속도를 제한하는 매커니즘을 찾야아하는데.. 현재 목적은 전체 속도 제한을 걸고 싶은 것입니다.


속도 제한을 하려면 qdisc / hfifo 등 랜카드에 큐를 걸거나, 아니면 아예 속도 링크를 낮추거나 하는 방법이 있습니다. 그러나 아직까지 정확하게 이해를 못하고 있어서 제일 쉽게 적용이 가능한 패키지를 조금 검색해 보았습니다.


tc : 기본적으로 내장 되어 있으며 속도 제한 가능 (아직 이해 못함)

trickle : 프로그램에 제한 적용 가능


trickle 의 경우 데몬모드로 실행하면 전체 트래픽에 제한을 준다고 하는 부분이 있어서 데몬 모드로 실행해 보았지만 다운로드에 대해서는 제한이 되지 않았습니다. 


물론 tc도 마찬가지였네요.. 그러다 쉽게 좀 할 수 있는게 없나.. 하고 찾아본 것이 wondershaper 입니다.


root@openmediavault:~# apt install wondershaper

Reading package lists... Done

Building dependency tree       

Reading state information... Done

wondershaper is already the newest version (1.1a-10).

0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

root@openmediavault:~#


명령은 아래와 같이 넣습니다.


wondershaper [ethernet] [down] [up]


속도는 kbit/s 로만 입력이 가능함으로 1mbps 를 입력하려고 할 때에는 1024를 입력하면 됩니다.


# 제한 해제

wondershaper clear enp2s0


# 업 다운 1mbps 로 제한

wondershaper enp2s0 1024 1024


# 다운 8메가 / 업 1메가 제한

wondershaper enp2s0 8192 1024


# 다운 50메가 / 업 50메가 제한

wondershaper enp2s0 51200 51200


이런식으로 제한이 가능하고 제 시스템은 아래와 같은데 잘 작동합니다. 


tc나 trickle 을 사용할 때 처럼 다운로드에는 제한이 적용되지 않는 에러가 없네요. ㅎㅎ


i5-4350U / 16GB / DEBIAN 10 (native) X86_64


그럼 필요한 json 파싱과 속도 제한 부분을 만들었으니, 스크립트로 만들어 봐야 하지 않겠습니까?


바로 아래의 스크립트를 눈 깜짝할 사이에 만들었습니다.


https://github.com/djjproject/scripts/blob/master/tvh_qos.sh


#!/bin/bash

// 현 스크립트가 실행중이면 pid 리턴 후 종료 if pidof -o %PPID -x "$0"; then exit 1 fi

// wondershaper 바이너리 위치 지정 WONDER=/usr/sbin/wondershaper


// 인터페이스 지정 INTERFACE=enp2s0


// 전체 네트워크 대역폭 지정 (100mpbs) NETRATE=102400


// TVHeadend 스트리밍시 소모되는 대역폭 설정 (13mbps) TVHRATE=13312 // 처음 한번 속도 제한 해제 $WONDER clear $INTERFACE

// 여러번 적용을 하지 않기 위한 임시 변수 TMP_VIEWCNT=0 while true; do sleep 3         

// tvheadend json 을 긇어 VIEWCNT 변수 초기화

VIEWCNT=`curl -s http://id:pw@ipaddr:9981/api/status/subscriptions | jq .totalCount` if [ "$VIEWCNT" -ne "$TMP_VIEWCNT" ]; then DNRATE=`expr $NETRATE - $TVHRATE \* $VIEWCNT` UPRATE=`expr $NETRATE - $TVHRATE \* $VIEWCNT`

$WONDER $INTERFACE $DNRATE $UPRATE TMP_VIEWCNT=$VIEWCNT echo "CURRNT COUNT : $VIEWCNT | CURRENT SPEED : $DNRATE / $UPRATE" fi done exit 0


모바일로 작성하고 있어서 편집이 어려워서 밑에 작성합니다. 속도를 (토탈 - 카운트 * 빼는속도) 이런식으로 계산하여 속도 제한을 걸고 그게 변할 때마다 한번만 실행하도록 되어 있습니다.


이 스크립트를 세팅하여 아래와 같이 실행하면 로그가 남게 되어 있습니다.


root@openmediavault:~# /opt/scripts/tvh_qos.sh 

Wondershaper queues have been cleared.

CURRNT COUNT : 1 | CURRENT SPEED : 82944 / 82944

CURRNT COUNT : 0 | CURRENT SPEED : 97280 / 97280

CURRNT COUNT : 1 | CURRENT SPEED : 82944 / 82944

CURRNT COUNT : 2 | CURRENT SPEED : 68608 / 68608

CURRNT COUNT : 3 | CURRENT SPEED : 54272 / 54272

CURRNT COUNT : 4 | CURRENT SPEED : 39936 / 39936

CURRNT COUNT : 3 | CURRENT SPEED : 54272 / 54272

CURRNT COUNT : 4 | CURRENT SPEED : 39936 / 39936

CURRNT COUNT : 3 | CURRENT SPEED : 54272 / 54272

CURRNT COUNT : 4 | CURRENT SPEED : 39936 / 39936

CURRNT COUNT : 3 | CURRENT SPEED : 54272 / 54272

CURRNT COUNT : 2 | CURRENT SPEED : 68608 / 68608

CURRNT COUNT : 1 | CURRENT SPEED : 82944 / 82944


UHD 방송을 스트리밍 중일 때 스트리밍하고 있는 엔트리에서 grep 이든 sed 혹은 jq로 걸러낼 수 있기 때문에 UHD 방송을 스트리밍중일 때 또 다르게 조건을 적용할 수 있습니다.


그러나 아무래도 100mbps 에서는 UHD 방송 스트리밍도 어려움이 있어서 그 부분은 제외 하였습니다. 


감사합니다.





댓글을 달아 주세요