天天看点

分布式直播系统(十)【一条配置搞定流量计费】流量计费方式配置说明QQ交流群:697773082

转载请注明出处:https://blog.csdn.net/impingo

项目地址:https://github.com/im-pingo/pingos

项目官网:http://pingos.io

一条配置搞定流量计费

  • 流量计费方式
    • 网宿
    • 阿里云
  • 配置说明
    • 配置详解
      • 变量列表
  • QQ交流群:697773082

流量计费方式

在直播系统中最暴力直接的计费方式莫过于记录下每段时间内客户的流量了,然后根据流量总值进行收费,而CDN行业则流传着一种被称作95峰值计费的方案。

我们以网宿和阿里的95峰值计费方式为例介绍这种流量计费场景。

网宿

计费方式说明:当前的计费方式为95%值计费方式,即取查询时间段中,所有带宽数据点,按带宽大小从低到高排序后,取第95%个点所对应的值作为计费带 宽。如一段时间内有N(N=100)个带宽数据点,将这些点从低到高排序,第N*95%(100×95%=95)个点对应的带宽大小为该计费带宽的值。

阿里云

95带宽峰值计费按自然月结算,在一个自然月内,按账户取每5分钟有效带宽值进行降序排列,然后去掉带宽数值较高的5%的点,剩下的较高带宽就是95带宽峰值计费值。以1个月30天为例,默认均为有效取值点:每5分钟1个带宽取值点,每小时12个带宽取值点,每月取值点数为:12 x 24 x 30 = 8640个,将所有的点按带宽数值降序排列,去掉前5%的点 8640 x 5% = 432 个,即第433个点为计费点。

中国大陆和海外的95带宽将分开计费,且带宽分别排序,取各自的95峰值和对应的峰值时刻用于计费值。

**不管是哪一家的计费方式他们都有一个共同点就是记录单位时间内的流量,**所以如果我们要实现流量计费就必须记录下单位时间内的流量。

使用https://github.com/im-pingo/pingos(原https://github.com/im-pingo/nginx-rtmp-module)可以轻松记录下直播过程中每条流的流量使用情况,从而达到计费的效果。

配置说明

user  root;
daemon on;
master_process on;
worker_processes  1;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

worker_rlimit_nofile 102400;
worker_rlimit_core   2G;
working_directory    /tmp;

#pid        logs/nginx.pid;

events {
    use epoll;
    worker_connections  1024;
}

stream_zone buckets=1024 streams=4096;

rtmp {
    log_format log_bandwidth '{"app":"$app","name":"$name","bitrate":$bitrate,"args":"$args","timestamp":$ntp,"ts":"$time_local","type":"$command","remote_addr":"$remote_addr","domain":"$domain"}';
    access_log logs/bandwidth.log log_bandwidth trunc=60s;
    server {
        listen 1935;
        serverid 000;
        out_queue 2048;
   
        application live {
            rtmp_auto_pull on;
            rtmp_auto_pull_port unix:/tmp/rtmp;

            live on;
            hls on;
            hls_path /tmp/hls;
            hls_fragment 4000ms;
            hls_max_fragment 6000ms;
            hls_playlist_length 12000ms;
            hls_type event;

            hls2memory on;
            mpegts_cache_time 20s;

            hls2_fragment 1300ms;
            hls2_max_fragment 1600ms;
            hls2_playlist_length 3900ms;

            wait_key on;
            wait_video on;
            cache_time 3s;
            low_latency off;
            fix_timestamp 0s;
# h265 codecid, default 12
            hevc_codecid  12;
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_X-Forwarded-For" "$http_X-Real-IP" "$host"';


    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #reset_server_name www.test1.com www.test2.com;
    #gzip  on;
    server {
         listen 80;
        location /rtmp_stat {
            rtmp_stat all;
            rtmp_stat_stylesheet /stat.xsl;
        }

        location /xstat {
            rtmp_stat all;
        }

        location /sys_stat {
            sys_stat;
        }

        location /control {
            rtmp_control all;
        }
         location /live {
            flv_live 1935;
         }
         location /ts {
            ts_live 1935 app=live;
         }
         location /hls {
            # Serve HLS fragments
             types {
                 application/vnd.apple.mpegurl m3u8;
                 video/mp2t ts;
             }
             root /tmp;
             expires -1;
             add_header Cache-Control no-cache;
             add_header 'Access-Control-Allow-Origin' '*';
         }

        location /hls2 {
             hls2_live 1935 app=live;
             add_header 'Access-Control-Allow-Origin' '*';
             add_header Cache-Control no-cache;
         }
         location / {
             chunked_transfer_encoding on;
             root html/;
         }
    }
}
           

配置详解

上述配置模板中起到计费作用的配置有两项:

log_format log_bandwidth '{"app":"$app","name":"$name","bitrate":$bitrate,"args":"$args","timestamp":$ntp,"ts":"$time_local","command":"$command","remote_addr":"$remote_addr","domain":"$domain"}';
access_log logs/bandwidth.log log_bandwidth trunc=60s;
           
  • log_format 用来描述日志输出格式,后面跟两个参数,第一个参数是用来标记这项配置的名字;第二个参数用来描述日志输出格式,最关键的是支持变量,变量以$符号开始,输出到日志文件后变量会自动被真实值所替换。
  • access_log 这项配置的第一个参数指定日志输出路径和日志文件名称;第二个参数用来描述采用哪种日志输出格式;第三个参数描述针对每条流隔多久输出一次日志记录。

变量列表

变量名 说明
$connection 连接序号,nginx服务器对每个tcp连接都分配一个整型数字
$remote_addr 客户端IP
$app nginx.conf里对应的application名称
$flashver rtmp连接中flashver的值
$swfurl rtmp连接中swfurl的值
$tcurl rtmp连接中tcurl的值,注意这个值有点类似http协议中url,如rtmp://ip/app/name ,是一个完整的rtmp地址
$domain 客户端连接服务器时候使用的域名
$parg_ rtmp请求中如果携带参数,可以使用这个变量获取,如rtmp://ip/app/name?session=123,如果你想获取session这个参数的值,可以用$parg_session来获取,其他以此类推
$pageurl rtmp连接中pageurl的值
$command 推流产生的记录是publish,拉流产生的记录是play
$name 流名
$args rtmp连接里的全量参数,如rtmp://ip/app/name?k0=v0&k1=v1&k2=v2,则args就是k0=v0&k1=v1&k2=v2
$bytes_sent 这条连接上发出去的字节数
$time_local 打这条记录时的服务器时间,如31/Oct/2019:15:24:04 +0800
$msec utc时间,精确到毫秒
$session_time 从连接建立开始计算,到目前为止过了多久,单位秒
$session_readable_time 与session_time含义相同,只不过是格式化后的更方便人眼读取的时间

QQ交流群:697773082

继续阅读