RTMP与HLS压力测试工具安装与配置

服务器负载测试工具(st-load):

1. 模拟huge并发:2G内存就可以开300k连接。基于states-threads的协程。

2. 支持HLS解析和测试,下载ts片后等待一个切片长度,模拟客户端。支持HLS点播和直播。

3. 支持HTTP负载测试,所有并发重复下载一个http文件。可将80Gbps带宽测试的72Gbps。

4. 支持RTMP流测试,一个进程支持5k并发。使用nginx-rtmp的协议直接将chunk流解析为messgae。

state-threads用来模拟超级并发,并简化异步socket的逻辑为同步socket,http-parser解析http协议部分。

这两个库设计都很巧妙,所以我开了一个项目:https://github.com/winlinvip/st-load

state-threads之前就有写过文章说明,那时候主要是支持高并发的rtmp服务器,也是并发和异步变为同步的协程很方便。

http-parser用yum就可以search到,它其实设计得也相当巧妙,相当于只是解析buffer的http内容,并不负责网络部分。libcurl/poco等都带了网络处理,所以不合适。

举例说明,http_parser_parse_url这个函数,解析url,设计得非常有意思,不是返回字符串,而是返回位置索引,譬如主机头在什么位置长度多长等等。

[root@localhost ~]# yum install git unzip patch gcc gcc-c++ make
[root@localhost ~]# git clone https://github.com/winlinvip/st-load.git

[root@localhost st-load]# ./configure
[root@localhost st-load]# make

[root@localhost st-load]# ls objs/
http-parser-2.1 src st_hls_load st_rtmp_load st_rtmp_publish
Makefile st-1.9 st_http_load st_rtmp_load_fast
[root@localhost st-load]#
模拟RTMP用户
./st_rtmp_load -c 1 -r rtmp://127.0.0.1:1935/live/livestream
模拟HLS直播用户
./st_hls_load -c 1 -r http://127.0.0.1:3080/hls/hls.m3u8
模拟HSL点播用户
./st_hls_load -c 10000 -o -r http://127.0.0.1:3080/hls/hls.m3u8
模拟RTMP推流用户
./st_rtmp_publish -i doc/source.200kbps.768×320.flv -c 1 -r rtmp://127.0.0.1:1935/live/livestream
模拟RTMP多路推流用户
./st_rtmp_publish -i doc/source.200kbps.768×320.flv -c 1000 -r rtmp://127.0.0.1:1935/live/livestream_{i}

支持RTMP流播放测试,一个进程支持5k并发
支持RTMP流推流测试,一个进程支持500个并发。

CentOS6下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)

CentOS6下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)

1.先添加几个RPM下载源

     1.1)安装RPMforge的CentOS6源
     [root@AY130611215205Z ~]# wget -c http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
     [root@AY130611215205Z ~]# rpm –import http://apt.sw.be/RPM-GPG-KEY.dag.txt
     [root@AY130611215205Z ~]# rpm -i rpmforge-release-0.5.3-1.el6.rf.*.rpm    

     1.2)安装epel源
     [root@AY130611215205Z ~]# wget -c http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
     [root@AY130611215205Z ~]# rpm -Uvf epel-release-6-8.noarch.rpm

     安装完成,查看一下源列表,看到rpmforge和epel字样即可
     [root@AY130611215205Z ~]# ls -lh /etc/yum.repos.d

2.安装转码工具Mencoder及ffmpeg(约定:每个小点操作之前先回到用户主目录,即cd ~)

     2.1)安装一些基础包,不用担心重复,已经存在的会自动忽略或升级
     [root@AY130611215205Z ~]# yum install gcc make automake bzip2 unzip patch subversion libjpeg-devel
     [root@AY130611215205Z ~]# wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
     [root@AY130611215205Z ~]# tar zxvf yasm-1.2.0.tar.gz
     [root@AY130611215205Z ~]# cd yasm-1.2.0
     [root@AY130611215205Z yasm-1.2.0]# ./configure
     [root@AY130611215205Z yasm-1.2.0]# make && make install
     [root@AY130611215205Z yasm-1.2.0]# cd ~
     
     2.2)卸载系统原有的ffmgeg和x.264,没有则跳过
     [root@AY130611215205Z ~]# yum remove ffmpeg x264

     2.3)先安装一些Mplayer编码库(仅限于64位系统)
     [root@AY130611215205Z ~]# wget -c http://www2.mplayerhq.hu/MPlayer/releases/codecs/essential-amd64-20071007.tar.bz2
     上面这一步可能在部分VPS上无法下载,比如我的阿里云VPS就提示连接失败,但是可以用本机浏览器下载后上传到VPS的/root根目录去,然后继续下面的操作
     [root@AY130611215205Z ~]# tar xvjf essential-amd64-20071007.tar.bz2
     [root@AY130611215205Z ~]# mkdir /usr/local/lib/codecs
     [root@AY130611215205Z ~]# cp -Rvp essential-amd64-20071007/* /usr/local/lib/codecs/

     编辑下面文件
     [root@AY130611215205Z ~]# vim /etc/ld.so.conf
     添加以下两行到上面的文件里
     /usr/lib 
     /usr/local/lib
     
     2.4)再安装一些格式转换常用的编码库
     [root@AY130611215205Z ~]# yum install faac-devel  lame-devel amrnb-devel opencore-amr-devel amrwb-devel  libvorbis-devel libtheora-devel xvidcore-devel
     
     2.5)安装x.264
     [root@AY130611215205Z ~]# wget ftp://ftp.videolan.org/pub/videolan/x264/snapshots/last_stable_x264.tar.bz2
     [root@AY130611215205Z ~]# tar xvjf last_stable_x264.tar.bz2
     [root@AY130611215205Z ~]# cd x264-snapshot-20140219-2245-stable/     (这可能日期有区别,自己ls一下)
     [root@AY130611215205Z x264-snapshot-20140219-2245-stable]# ./configure –enable-shared –enable-pic
     [root@AY130611215205Z x264-snapshot-20140219-2245-stable]# make && make install
     [root@AY130611215205Z x264-snapshot-20140219-2245-stable]#  cd ~

     2.6)安装libvpx
     [root@AY130611215205Z ~]# wget http://webm.googlecode.com/files/libvpx-v1.2.0.tar.bz2
     [root@AY130611215205Z ~]# tar xvjf libvpx-v1.2.0.tar.bz2
     [root@AY130611215205Z ~]# cd libvpx-v1.2.0
     [root@AY130611215205Z libvpx-v1.2.0]# ./configure –enable-shared –enable-pic
     [root@AY130611215205Z libvpx-v1.2.0]# make && make install
     [root@AY130611215205Z libvpx-v1.2.0]# cd ~

     2.7)安装FFmpeg
     [root@AY130611215205Z ~]# wget http://ffmpeg.org/releases/ffmpeg-2.0.1.tar.bz2
     [root@AY130611215205Z ~]# tar xvjf ffmpeg-2.0.1.tar.bz2
     [root@AY130611215205Z ~]# cd ffmpeg-2.0.1
     [root@AY130611215205Z ffmpeg-2.0.1]# ./configure –enable-gpl –enable-version3 –enable-shared –enable-nonfree –enable-postproc –enable-libfaac –enable-libmp3lame –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libtheora –enable-libvorbis –enable-libvpx –enable-libx264 –enable-libxvid
     [root@AY130611215205Z ffmpeg-2.0.1]# make && make install
     [root@AY130611215205Z ffmpeg-2.0.1]# cd ~
     
     让动态链接库被系统共享
     [root@AY130611215205Z ~]# ldconfig

     2.8)最后安装mencoder
     [root@AY130611215205Z ~]# yum install mplayer mencoder flvtool2

     查看一下已经安装好的音频和视频编码器
     查看所有所支持的音频编码
     [root@AY130611215205Z ~]# mencoder -oac help
     查看所有所支持的视频编码
     [root@AY130611215205Z ~]# mencoder -ovc help
     具体结果可参考http://www.mplayerhq.hu/DOCS/HTML/zh_CN/menc-feat-selecting-codec.html

3.安装配置Nginx
     
     3.1)先安装各种依赖(nginx需要pcre支持,yamdi用来为flv创建关键帧才能随意拖动)
     [root@AY130611215205Z ffmpeg-2.0.1]# yum install gcc gcc-c++ openssl-devel zlib-devel pcre pcre-devel yamdi
     
     3.2)下载所需的nginx模块
     第一个是nginx_mod_h264_streaming,让nginx支持flv/mp4流播放
     [root@AY130611215205Z ~]# wget http://h264.code-shop.com/download/nginx_mod_h264_streaming-2.2.7.tar.gz
     [root@AY130611215205Z ~]# tar zxvf nginx_mod_h264_streaming-2.2.7.tar.gz
     注意:先要修改一下这家伙的源码,注释掉nginx_mod_h264_streaming-2.2.7/src/ngx_http_streaming_module.c的158到161行
     /* TODO: Win32 */
     //if (r->zero_in_uri)
     // {
     //   return NGX_DECLINED;
     // }

     第二个是nginx-rtmp-module,让nginx支持rtmp/hls协议
     [root@AY130611215205Z ~]# wget -O nginx-rtmp-module.zip  https://github.com/arut/nginx-rtmp-module/archive/master.zip
     [root@AY130611215205Z ~]# unzip nginx-rtmp-module.zip
     下载清缓存的模块
     [root@AY130611215205Z ~]# wget -O ngx_cache_purge.zip https://github.com/FRiCKLE/ngx_cache_purge/archive/master.zip
     [root@AY130611215205Z ~]# unzip ngx_cache_purge.zip
     
     3.3)下载安装nginx
     [root@AY130611215205Z ~]# wget http://nginx.org/download/nginx-1.2.9.tar.gz
     [root@AY130611215205Z ~]# tar zxvf nginx-1.2.9.tar.gz
     [root@AY130611215205Z ~]# cd nginx-1.2.9
     [root@AY130611215205Z nginx-1.2.9]# ./configure –user=daemon –group=daemon –prefix=/usr/local/nginx/ –add-module=../nginx-rtmp-module-master –add-module=../ngx_cache_purge-master –add-module=../nginx_mod_h264_streaming-2.2.7 –with-http_stub_status_module –with-http_ssl_module –with-http_sub_module –with-http_gzip_static_module –with-http_flv_module
     [root@AY130611215205Z nginx-1.2.9]# make && make install
     PS:若提示make[1]: *** [objs/addon/src/ngx_http_h264_streaming_module.o] Error 1,请参考3.3.2小节的注意点,然后重新运行./configure这一段 
     
     /**———以下是安装了Tengine后重新编译的代码,模块的路径自己对一下———**//
./configure –user=www –group=www –prefix=/usr/local/tengine/ –add-module=../../../nginx-rtmp-module-master –add-module=../../../ngx_cache_purge-master –add-module=../../../nginx_mod_h264_streaming-2.2.7 –with-http_stub_status_module –with-http_ssl_module –with-http_sub_module –with-http_gzip_static_module –with-http_flv_module –with-http_concat_module=shared –with-http_sysguard_module=shared –with-google_perftools_module –with-http_image_filter_module
     
     运行一下nginx
     [root@AY130611215205Z ~]# /usr/local/nginx/sbin/nginx
     然后用浏览器你的服务器IP,看到welcome就对了
     或者到nginx的sbin目录下,运行一下nginx -V,看看列表出来的modules对不对

     3.4)各种配置nginx
     编辑/usr/local/nginx/conf/nginx.conf文件,最好用sftp软件(如windows下的flashfxp/Mac下的tramnsmit)下载过来本地编辑。
     贴一下我的配置文件:(目录需要自己改动,我用的是阿里云的数据盘,所以到/mnt/里面去了)
     ———————————————————————nginx配置文件—————————————————
    #filename:nginx.conf
    #user  nobody;
    worker_processes  1;

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

    pid        logs/nginx.pid;

    events {
        use epoll;
        worker_connections  1024;
    }

    rtmp {
        server {
            listen 1935;
            chunk_size 4000;

            # video on demand
            application vod {
                play /mnt/media/vod;
            }

            # HLS
            # HLS requires libavformat & should be configured as a separate
            # NGINX module in addition to nginx-rtmp-module:
            # ./configure … –add-module=/path/to/nginx-rtmp-module/hls …
            # For HLS to work please create a directory in tmpfs (/tmp/app here)
            # for the fragments. The directory contents is served via HTTP (see
            # http{} section in config)
            #
            # Incoming stream must be in H264/AAC/MP3. For iPhones use baseline H264
            # profile (see ffmpeg example).
            # This example creates RTMP stream from movie ready for HLS:
            #
            # ffmpeg -loglevel verbose -re -i movie.avi  -vcodec libx264
            #    -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1
            #    -f flv rtmp://localhost:1935/hls/movie
            #
            # If you need to transcode live stream use ‘exec’ feature.
            #
            application hls {
                hls on;
                hls_path /mnt/media/app;
                hls_fragment 10s;
            }
        }
    }

    http {

        include mime.types;
        default_type application/octet-stream;
        sendfile on;
        keepalive_timeout 65;
        gzip on;
        
         #log format

        log_format  access  ‘$remote_addr – $remote_user [$time_local] “$request” ‘
                 ‘$status $body_bytes_sent “$http_referer” ‘
                 ‘”$http_user_agent” $http_x_forwarded_for’;    
        
         #定义一个名为addr的limit_zone,大小10M内存来存储session
        limit_conn_zone $binary_remote_addr zone=addr:10m;     

        server {
            listen 8080;
             server_name localhost;

             # HTTP can be used for accessing RTMP stats
            # This URL provides RTMP statistics in XML
            location /stat {
                rtmp_stat all;
                rtmp_stat_stylesheet stat.xsl;
            }
            location /stat.xsl {
                root /mnt/soft/nginx-rtmp-module-master;
            }
             location /control {
                rtmp_control all;
            }
            location / {
                root /mnt/soft/nginx-rtmp-module-master/test/rtmp-publisher;
            }
        }
        
         server {
            listen 80;
             server_name localhost;
             
            location / {
                    root /mnt/wwwroot;
                    index index.html;
                  }         

             location ~ \.flv$ {
                   root /mnt/media/vod;
                 flv;
                 limit_conn addr 20;
                 limit_rate 200k;
            }
            location ~ \.mp4$ {
                 root /mnt/media/vod;
                 mp4;
                 limit_conn addr 20;
                 limit_rate 200k;
            }

             location /hls {
                # Serve HLS fragments
                alias /mnt/media/app;
            }

             access_log  logs/nginxflv_access.log access;
        }
        
           
    }
     ——————————————————nginx配置文件——————————————
     
4.把自己的电影转换成mp4和flv格式来测试nginx搭的环境

     4.1)准备两部电影,硬盘上随便找,我找了“谍影重重A.mp4”和“鹿鼎记033.rmvb”,尽量找小一点十来分钟的,等下我们还要看完测试一下转换的结果有没有音影不同步的情况。
     我把两部电影重命名为 movie1.mp4和 movie2.rmvb,并上传到服务器/mnt/media/video下面,这里目录用来存放我们的原始视频。还有一个目录是/mnt/media/vod 用来存放转换后的视频。
     我这里的具体目录结构为:
     /mnt/media/video -> 存放原始视频
     /mnt/media/app  -> 存放转成m3u8的视频,供http访问(HLS)
     /mnt/media/vod  -> 存放转换后的flv和mp4视频,供http或rtmp访问

     4.2)用ffmpeg转换mp4文件(ffmpeg不支持rmvb)
     [root@AY130611215205Z ~]# cd /mnt/media/video/
     [root@AY130611215205Z video]# ffmpeg -i movie1.mp4 -y -vcodec libx264 -vf scale=”640:-1″ -r 15 -acodec libfaac ../vod/movie1.flv
     -y:文件覆盖,-vf scale=”640:-1”:尺寸调整为宽度640高度自动,-r 15:帧数15fps,这里用libfaac音频编码防止转成ts格式时iPhone没有声音
     
     添加关键帧用来支持拖动播放
     [root@AY130611215205Z video]# cd ../vod
     [root@AY130611215205Z vod]# mv movie1.flv movie1-src.flv
     [root@AY130611215205Z vod]# yamdi -i movie1-src.flv -o movie1.flv
     [root@AY130611215205Z vod]# rm -rf movie1-src.flv

     接下来测试的话,下载VLC Player到本地测试(VLC有时候会花屏,用JWPlayer就好了),或者不行麻烦的话装一个apache服务器并下载JWPlayer来测试。
     测试播放地址为(地址已失效,请勿访问)
     HTTP形式访问:      http://121.199.47.208/movie1.flv
     RTMP形式访问:      rtmp://121.199.47.208/vod/movie1.flv

     4.3)用mencoder转换rmvb文件
     
     4.4)把flv转换成hls的m3u8
     下载安装segmenter
     [root@AY130611215205Z ~]# yum install -y curl curl-devel zlib-devel openssl-devel perl perl-devel cpio expat-devel gettext-devel git
     [root@AY130611215205Z ~]# git clone https://github.com/johnf/m3u8-segmenter.git
     [root@AY130611215205Z ~]# cd m3u8-segmenter/
     [root@AY130611215205Z m3u8-segmenter]# gcc -Wall -g m3u8-segmenter.c -o segmenter -lavformat
     [root@AY130611215205Z m3u8-segmenter]# cp segmenter /usr/bin/
     
     转换成ts,片源大小及清晰度等取决于flv文件,所以转成flv的时候一定要统一起来
     [root@AY130611215205Z vod]# cd /mnt/media/vod
     [root@AY130611215205Z vod]# mkdir /mnt/media/app/movie1/
     [root@AY130611215205Z vod]# ffmpeg -y -i movie1.flv -f mpegts -c:v copy -c:a copy -vbsf h264_mp4toannexb /mnt/media/app/movie1/main.ts
     
     切片
     [root@AY130611215205Z movie1]# cd /mnt/media/app/movie1/
     [root@AY130611215205Z movie1]# segmenter -i main.ts -d 10 -p movie1 -m movie1.m3u8 -u http://121.199.47.208/hls/movie1/
     -d 10:每个切片为10秒,-p movie1:切片的名字的前缀
     -u URL地址:m3u8中播放列表的地址前缀,自己cat一下生成的movie1.m3u8就知道什么用 了
     

     测试一下,用iPhone的Safari访问一下http://121.199.47.208/hls/movie1/movie1.m3u8

     注:安装日志记录于半年前的evernote,现在才贴出来的,所以文中的视频访问地址都已经失效了。

Nginx搭建hls流媒体服务器

第一种方案:ffmpeg+nginx

 
新的ffmpeg已经支持HLS。(本人也参与了代码供献,给自己做个广告:))
 
点播:
生成hls分片:
ffmpeg -i <媒体文件> -c:v libx264 -c:a -f hls /usr/local/nginx/html/test.m3u8 
直播:
ffmpeg -i udp://@:1234 -c:v libx264 -c:a -f hls  /usr/local/nginx/html/test.m3u8
建立web服务器:
默认配置就可以。
 server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
}
 
 
 
启动nginx。
 
客户端访问:http://IP/test.m3u8
 
在windows上可以用vlc播放。
 
 
 
第二个文案,用nginx-rtmp-module
 
      
rtmp {
 
    server {
 
        listen 1935;
 
        chunk_size 4000;
      
        #HLS
 
        # For HLS to work please create a directory in tmpfs (/tmp/app here)
        # for the fragments. The directory contents is served via HTTP (see
        # http{} section in config)
        #
        # Incoming stream must be in H264/AAC. For iPhones use baseline H264
        # profile (see ffmpeg example).
        # This example creates RTMP stream from movie ready for HLS:
        #
        # ffmpeg -loglevel verbose -re -i movie.avi  –vcodec libx264 
        #    -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 
        #    -f flv rtmp://localhost:1935/hls/movie
        #
        # If you need to transcode live stream use ‘exec’ feature.
        #
        application hls {
            live on;
            hls on;
            hls_path /tmp/app;
            hls_fragment 5s;
        }
    }
}
 
http {
 
    server {
 
        listen      80;
        location /hls {
            # Serve HLS fragments
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            alias /tmp/app;
            expires -1;
        }
    }
}

Nginx防盗链根据UA屏蔽恶意User Agent请求

相对于 Apache,Nginx 占用的系统资源更少,更适合 VPS 使用。恶意盗链的 User Agent 无处不在,博客更换到 WordPress 没几天,就被 SPAM(垃圾留言)盯上,又被暴力破解后台用户名密码。以前介绍过 Apache 使用 .htaccess 屏蔽恶意 User Agent,今天来介绍 Nginx 屏蔽恶意 User Agent请求的方法。

先上规则&注释

#禁用未初始化变量警告
uninitialized_variable_warn off;
#匹配各种 bad user agent,返回403错误
if ($http_user_agent ~* "embeddedwb|NSPlayer|WMFSDK|qunarbot|mj12bot|ahrefsbot|Windows 98|MSIE 6.0; Windows 2000|EasouSpider|Sogou web spider") {
return 403;
}
#匹配POST方法,给变量iftemp赋值
if ($request_method ~* "POST") {set $iftemp X;}
#匹配 bad user agent,给变量iftemp赋值;这几个UA主要是发垃圾留言的
if ($http_user_agent ~* "MSIE 6.*NET|MSIE 7.*NET|MSIE 6.*SV1|MSIE 6.0; Windows NT 5.0") {
set $iftemp "${iftemp}Y";
}
#如果变量iftemp符合上面两个条件,返回403错误
if ($iftemp = XY) {return 403;}



禁用未初始化变量警告,不然会不停写入警告到错误日志error.log,如下

2014/09/11 09:21:11 [warn] 18649#0: *132 using uninitialized “iftemp” variable, client: 220.181.51.209, server: www.wilf.cn, request: “GET /wp-content/themes/dazzling/inc/fonts/glyphicons-halflings-regular.woff HTTP/1.0”, host: “www.wilf.cn”, referrer: “http://www.wilf.cn/”

2014/09/11 09:21:11 [warn] 18649#0: *92 using uninitialized “iftemp” variable, client: 66.249.79.55, server: www.wilf.cn, request: “GET /page/14?mod=pad&act=view&id=741 HTTP/1.1”, host: “www.wilf.cn”

Nginx 规则不支持2个以上的条件判断,绕个路,通过给变量两次赋值来完成2个条件判断。

Nginx 规则也是使用正则表达式匹配字符串,分析日志,根据需要自己定制。

检验成果的时候到了

183.60.214.51 — [10/Sep/2014:22:16:18 +0800] — Bytes: 13507 — GET /?mod=pad&act=view&id=460 HTTP/1.1 — 403 — – — Mozilla/5.0 (compatible; EasouSpider; +http://www.easou.com/search/spider.html) — – — –

220.181.125.169 — [11/Sep/2014:09:38:15 +0800] — Bytes: 169 — GET /page/51?mod=wap&act=AddCom&inpId=860 HTTP/1.1 — 403 — – — Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07) — – — –

EasouSpider 和 Sogou web spider,再也不见。

http://www.wilf.cn/post/block-bad-user-agent-on-nginx-sever.html

nginx配置limit_conn_zone来限制并发连接数以及下载带宽

配置方法如下:



1、在nginx.conf里的http{}里加上如下代码:

  1. #ip limit
  2. limit_conn_zone $binary_remote_addr zone=perip:10m;
  3. limit_conn_zone $server_name zone=perserver:10m;

复制代码

2、在需要限制并发数和下载带宽的网站配置server{}里加上如下代码:

  1. limit_conn perip 2;
  2. limit_conn perserver 20;
  3. limit_rate 100k;

复制代码

补充说明下参数:

  • $binary_remote_addr是限制同一客户端ip地址;
  • $server_name是限制同一server最大并发数;
  • limit_conn为限制并发连接数;
  • limit_rate为限制下载速度;
转另一篇文章:http://hxl2009.blog.51cto.com/779549/1324473

注意:

nginx 1.1.8 之后的版本的语法改为limit_conn_zone $binary_remote_addr zone=NAME:10m;

NAME 就是 zone 的名字详情请看这里 http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

限制连接数:

要限制连接,必须先有一个容器对连接进行计数,在http段加入如下代码:

“zone=” 给它一个名字,可以随便叫,这个名字要跟下面的 limit_conn 一致

$binary_remote_addr = 用二进制来储存客户端的地址,1m 可以储存 32000 个并发会话

… 省掉 N 字

http

{

limit_conn_zone $binary_remote_addr zone=addr:10m;

接下来需要对server不同的位置(location段)进行限速,比如限制每个IP并发连接数为1,则

server

{

listen 80;

server_name 192.168.11.128;

index index.html index.htm index.php;

limit_conn addr 1; #是限制每个IP只能发起1个连接 (addr 要跟 limit_conn_zone 的变量对应)

limit_rate 100k; #限速为 100KB/秒

root html;

注意事项:

limit_rate 100k; //是对每个连接限速100k。这里是对连接限速,而不是对IP限速!如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate * 2

直播及点播的视频码率,帧率和分辨率关系与区别

直播及点播视频码率,帧率和分辨率到底哪一个影响电影的清晰度

码率:影响体积,与体积成正比:码率越大,体积越大;码率越小,体积越小。

码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。也就是取样率(并不等同与采样率,采样率的单位是Hz,表示每秒采样的次数),单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真,围绕这个核心衍生出来cbr(固定码率)与vbr(可变码率), “码率”就是失真度,码率越高越清晰,反之则画面粗糙而多马赛克。

下面是通过一个wav文件的采样率来计算码率和文件大小,通过MediaInfo工具显示的文件信息如下:

概要

完整名称                             :audio\wav\adele-rolling_in_the_deep.wav

文件格式                             : Wave

文件大小                             : 38.3 MiB

长度                                    : 3分 47秒

平均混合码率                     : 1 411 Kbps

 

音频

ID                                         : 0

文件格式                             : PCM

格式设置,Endianness      : Little

编码设置ID                          : 1

编码设置ID/提示信息         : Microsoft

长度                                      : 3分 47秒

码率                                      : 1 411.2 Kbps

声道                                     : 2声道

采样率                                 : 44.1 KHz

位深度                                 : 16位

大小                                     : 38.3 MiB (100%)

 

1.码率计算公式:

码率=采样率 x 位深度 x 声道

所以,上面文件的码率= 44.1Khz x 16位 x 2声道 = 1411.2 Kbps

 

2.文件大小 = 码率 x 时长 = 1411.2 Kbps x (3 x 60 + 47 )s = 1411.2Kbps x 227s

 =38102.4 Kb

38102.4 Kb / 1024 Kb/M = 37.2M

近似等于mediainfo工具显示的文件大小38.3M。

注:此计算公式对未压缩的wav格式文件有效,不适用于mp3等被压缩的文件。

帧率:影响画面流畅度,与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。

帧率就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,

分辨率:影响图像大小,与图像大小成正比:分辨率越高,图像越大;分辨率越低,图像越小。

清晰度

在码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。
在分辨率一定的情况下,码率与清晰度成正比关系,码率越高,图像越清晰;码率越低,图像越不清晰。

 

带宽、帧率

例如在ADSL线路上传输图像,上行带宽只有512Kbps,但要传输4路CIF分辨率的图像。按照常规,CIF分辨率建议码率是512Kbps,那么照此计算就只能传一路,降低码率势必会影响图像质量。那么为了确保图像质量,就必须降低帧率,这样一来,即便降低码率也不会影响图像质量,但在图像的连贯性上会有影响。

php日志错误分析:网站http返回502与504错误分析

一. 戏说
不管你是做运维还是做开发,哪怕你是游客,时不时会遇到502 Bad Gateway或504 Gateway Time-out。出现这页面,把服务重启下,再实在不行重启下服务器,问题就解决了,但是,这问题还是会困扰着你,特别是做运维的人员。夜黑风高正酣睡 时,一个电话响起,让你重启服务或IISRESET,肯定是极大不爽,立马要问候他妈了。呵呵,本文总结502与504故障分析与解决方法。

二. 状态码解释
502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
504 Gateway Time-out:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。

三. 502 Bad Gateway原因分析
将请求提交给网关如php-fpm执行,但是由于某些原因没有执行完毕导致php-fpm进程终止执行。说到此,这个问题就很明了了,与网关服务如php-fpm的配置有关了。
php-fpm.conf配置文件中有两个参数就需要你考虑到,分别是max_children和request_terminate_timeout。
max_children最大子进程数,在高并发请求下,达到php-fpm最大响应数,后续的请求就会出现502错误的。可以通过netstat命令来查看当前连接数。
request_terminate_timeout设置单个请求的超时终止时间。还应该注意到php.ini中的max_execution_time参数。当请求终止时,也会出现502错误的。
当积累了大量的php请求,你重启php-fpm释放资源,但一两分钟不到,502又再次呈现,这是什么原因导致的呢? 这时还应该考虑到数据库,查看下数据库进程是否有大量的locked进程,数据库死锁导致超时,前端终止了继续请求,但是SQL语句还在等待释放锁,这时 就要重启数据库服务了或kill掉死锁SQL进程了。
对于长时间的请求可以考虑使用异步方式,可以参阅《关于PHP实现异步操作的研究》。

四. 504 Gateway Time-out原因分析
504错误一般是与nginx.conf 配置有关了。主要与以下几个参数有关:fastcgi_connect_timeout、fastcgi_send_timeout、 fastcgi_read_timeout、fastcgi_buffer_size、fastcgi_buffers、 fastcgi_busy_buffers_size、fastcgi_temp_file_write_size、 fastcgi_intercept_errors。特别是前三个超时时间。如果fastcgi缓冲区太小会导致fastcgi进程被挂起从而演变为 504错误。

五. 小结
总而言之,502错误主要从四个方向入手:
1. max_children
2. request_terminate_timeout、max_execution_time
3. 数据库
4. 网关服务是否启动如php-fpm

504错误主要查看nginx.conf关于网关如fastcgi的配置

php日志分析:解决NGINX+PHP-FPM failed to ptrace(PEEKDATA) Input/output error出错问题

今天查看php的错误日志 (error_log = /usr/local/php/var/log/php-fpm.log )  和 慢日志(slowlog = /usr/local/php/var/log/php-fpm.log.slow ) ,  发现错误日志里很多  “ ERROR: failed to ptrace(PEEKDATA) pid 4276: Input/output error (5)  ”这样的错误 , 想找出出现这错误的原因于是从网上搜了如下的  文章 。他说是他的网站经常出现 ”bad gateway“ 错误才去查日志 发现有这个错误 。 我现在还不知道 我的 日志里出现这样的错误 是不是 我的页面也出现  ”bad gateway“ 的错误 。 带查证ing。

查了 好几个资料都说是 php开启了慢日志 引起的 为了让系统不出现异常 决定吧慢日志 注释掉。

request_slowlog_timeout = 30
slowlog = /usr/local/php/var/log/php-fpm.log.slow 

资料 一:

网站总是出现bad gateway 提示,时有,时无,查看了一下error_log日志,居然出现一堆错误,如下

[29-Mar-2014 22:40:10] ERROR: failed to ptrace(PEEKDATA) pid 4276: Input/output error (5)
[29-Mar-2014 22:53:54] ERROR: failed to ptrace(PEEKDATA) pid 4319: Input/output error (5)
[29-Mar-2014 22:56:30] ERROR: failed to ptrace(PEEKDATA) pid 4342: Input/output error (5)
[29-Mar-2014 22:56:34] ERROR: failed to ptrace(PEEKDATA) pid 4321: Input/output error (5)
[29-Mar-2014 22:56:40] ERROR: failed to ptrace(PEEKDATA) pid 4314: Input/output error (5)

网上也找了很多方法,很多人说是 rlimit_files 打开文件数的问题,但是觉得不太靠谱,最后找到鬼佬的话,看上去还有几分道理。

http://serverfault.com/questions/406532/i-o-error-with-php5-fpm-ptracepeekdata-failed

It appears you have request_slowlog_timeout enabled. This normally takes any request longer than N seconds, logs that it was taking a long time, then logs a stack trace of the script so you can see what it was doing that was taking so long.

In your case, the stack trace (to determine what the script is doing) is failing. If you’re running out of processes, it is because either:

After php-fpm stops the process to trace it, the process fails to resume because of the error tracing it
The process is resuming but continues to run forever.
My first guess would be to disable request_slowlog_timeout. Since it’s not working right, it may be doing more harm than good. If this doesn’t fix the issue of running out of processes, then set the php.ini max_execution_time to something that will kill the script for sure.

看样子是因为我打开了slowlog 然后,再设置 了 request_slowlog_timeout 这个参数,,所以后php 没有执行完就出错了。。

上面解决的办法是:

禁用 php-fpm.conf 里的 request_slowlog_timeout 和 slowlog ,然后,修改 php.ini 里的max_execution_time 参数

资料 二 :

最近服务器频繁出现502(nginx+php+php-fpm的架构),调试过程中在php-fpm的日志中发现了大量的:

[02-Aug-2014 08:55:24] ERROR: failed to ptrace(PEEKDATA) pid 4046: Input/output error (5)
[02-Aug-2014 08:55:24] NOTICE: finished trace of 4046
[02-Aug-2014 08:55:24] NOTICE: child 4047 stopped for tracing
[02-Aug-2014 08:55:24] NOTICE: about to trace 4047
[02-Aug-2014 08:55:24] ERROR: failed to ptrace(PEEKDATA) pid 4047: Input/output error (5)
[02-Aug-2014 08:55:24] NOTICE: finished trace of 4047
[02-Aug-2014 08:55:24] NOTICE: child 4054 stopped for tracing
[02-Aug-2014 08:55:24] NOTICE: about to trace 4054
[02-Aug-2014 08:55:24] ERROR: failed to ptrace(PEEKDATA) pid 4054: Input/output error (5)
[02-Aug-2014 08:55:24] NOTICE: finished trace of 4054
[02-Aug-2014 08:55:24] NOTICE: child 4076 stopped for tracing
[02-Aug-2014 08:55:24] NOTICE: about to trace 4076

经对比最近两次系统调优所使用的配置文件发现,是因为php-fpm的配置引起:

#request_slowlog_timeout = 5s
#slowlog = /usr/local/php/var/log/php-fpm.log.slow

解决办法是注释掉上面的配置即可。/etc/init.d/php-fpm restart生效

scons-2.4.1 和jsoncpp 库配置

由于需要将项目能够在某平台上跑起来,所以需要对服务器进行重新编译,将boost库版本降下来,比较悲催。

平台是CentOS release 6.5 (Final)

首先是编译jsoncpp,步骤如下:

1. 下载scons-2.4.1.tar.gz,解压得到scons-2.4.1  下载入口:http://sourceforge.net/projects/scons/files/scons/2.4.1/

2. 进目录去,执行python setup.py install

3. 下载jsoncpp-src-0.5.0.tar.gz,解压得到jsoncpp-src-0.5.0 下载入口:http://sourceforge.net/projects/jsoncpp/?source=typ_redirect

4. 进目录去,执行:scons platform=linux-gcc,可能结果报错:No module named SCons.Script

5. 修改scons命令:vim /usr/local/bin/scons,在187行:import SCons.Script前面添加一行:sys.path.append(“/usr/local/lib64/scons-2.2.0”)

    我的系统是64位的,如果你的是32位的,那么可能是:sys.path.append(“/usr/local/lib/scons-2.2.0”),自己去/user/local/lib和lib64目录下看看就行了

6. 保存修改后,重新执行:scons platform=linux-gcc,O了

7.当然你可以把库直接放到/usr/lib.

cp jsoncpp-src-0.5.0/libs/linux-gcc-4.4.7/libjson_linux-gcc-4.4.7_libmt.* /usr/lib/

Nginx + FastCgi + Spawn-fcgi + c 的架构搭建

Php写的很有段时间了,最近看公司一些关键的后端CGI都是用C写的,以lighthttp 最为server 。忽然也有种学习用C写CGI的想法。虽然php结合php-fpm的fastcgi模式也有不错的性能,反正多学一种东西又有和不可以呢?何况,某些情况下C的性能还是php无法比拟的。



先有必要有这样第一个认识:ngxin作为一个webserver,本身并不包含CGI的解释器,需要通过一个中间件【例如php-fpm】来运行CGI。他们之间的模式大致是:

      nginx   <–   socket   –>   php-fpm——–>php  

那么nginx既然要运行c写的CGI那么也应该有类似php-fpm的东西。baidu, google了下,发现有一个spawn-fcgi的东西。原本是lighttp 内的fastcgi进程管理器。 于是又搜索了下,折腾了一个下午,终于抛出了经典的hello world !!!   。下面是具体步骤:

大致分为5步:

1、安装Spawn-fcgi    【启动cgi的时候需要】

wget   http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz tar zxvf  lighttpd-1.4.19.tar.gz    cd  lighttpd-1.4.19 ./configure make

复制 编译好的spawn-fcgi到 nginx目录,很主要!!!!

cp ./src/spawn-fcgi /usr/local/nginx/sbin/

2、安装fastcgi库:: 【提供编写cgi时的类库】

wget  http://www.fastcgi.com/dist/fcgi.tar.gz tar zxvf  fcgi.tar.gz cd  fcgi ./configure make make install

fcgio.cpp:50: error: ‘EOF’ was not declared in this scope解决办法PS:

我想这个fcgi开发一点也不活跃,而gcc的最新版本不断出来,很有可能是由于这方面引的原因,我又调整了一下关键字

gcc compile fcgi,(之前都是没有方向的搜索)。终于在第一条结果中找到原因了:http://bugs.gentoo.org/256654

解决办法:

在/include/fcgio.h文件中加上 #include <cstdio>,然后再编译安装就通过了。

3、测试代码::

#include <fcgi_stdio.h> int main( int argc, char *argv[] ) {   while( FCGI_Accept() >= 0 )   {       FCGI_printf( "Status: 200 OK\r\n" );       FCGI_printf( "Content-Type: text/html\r\n\r\n" );       FCGI_printf( "Hello world in C\n" );   }   return 0; }

编译::

g++ -o test.cgi test.cpp -L /usr/local/lib/ -lfcgi

4、启动Spawn-fcgi::

spawn-fcgi  -a 127.0.0.1 -p 7000 -u www  -f   /data/cgi-bin/test.cgi

如果报:   error while loading shared libraries: libfcgi.so.0: cannot open shared object file: No such file or directory  

请执行如下命令:为了这个错误,折腾了很长时间哦!

cp /usr/local/lib/libfcgi.so.0   /usr/lib

5、配置nginx.conf

  location ~ \.cgi$   {         fastcgi_pass  127.0.0.1:7000;         fastcgi_index index.cgi;         fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;         include fastcgi_params;     }

重启nginx

/etc/init.d/nginx reload