分类目录归档:nginx

nginx 视频服务器 架设

1.web服务器选用,建议使用0.8的稳定版

2.nginx默认自带了flv解码,编译的时候加上参数–with-http_flv_module即可

3.比较流行的mp4编码,需要另外安装第三方模块,建议使用http://h264.code-shop.com的H246方案

这个模块最新版本是2.3.2(不是官网介绍的2.2.7),并且需要打patch fix两个bug

1)zero_in_uri在0.8系列取消

2)404  错误返回415

模块可以从 http://h264.code-shop.com/download/nginx_mod_h264_streaming-2.3.2.tar.gz 下载

补丁可以从   http://www.4os.org/video/nginx/h246_stream_2.3.2.patch 下载

(不建议使用2.2.7版本,该版本有fclose空指针漏洞,并根据迅雷给我的反馈看存在编码兼容性造成的高负载问题)

4. 编译参数,简单示例下:

./configure –with-http_flv_module  –add-module=/path_to/nginx_mod_h264_streaming-2.3.2

如果不想自己patch,这里有patch好的模块,一样可用:

h264_stream_2.3.2.tar.gz

5.防盗链/限速/IO优化等,将在后续详细讲解:

1)防盗链:防盗链分为简单的refer引用判断和较为复杂的动态链接两种(比如时间/文件名双因子加密)

2)限速:nginx天然的支持了限速,limit-rate参数不仅仅能让视频流平滑的输出,还能极大的缓解IO压力

3)IO优化:包括内核调整/磁盘raid设置/使用SSD设备,在具备优秀开发人员的情况下甚至可以打散磁盘放置多份热点等

any question,mail to favortel#qq.com

Nginx启动初始化过程(转载)

main函数做的第一件事情就是对参数选项进行处理,和普通的Linux程序如出一辙,如下:

if (ngx_get_options(argc, argv) != NGX_OK) { return 1; }

Nginx用此函数对参数选项进行解析,从而采取相应的动作,比如:显示版本、测试配置等功能。其实此函数实现的很简陋,远没有Linux提供的getopt()那么强悍,但却可以达到跨平台的目的。

     ngx_time_init();
#if (NGX_PCRE)
    ngx_regex_init();
#endif
    ngx_pid = ngx_getpid();
    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

上述几行代码的功能如其名,主要完成Nginx在时间和日志等方面的初始化工作。

    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK){
        return 1;
    }

将命令行参数保存到ngx_os_argv、ngx_argc以及ngx_argv这几个全局的变量中。这算是一个备份存储,方便以后master进程做热代码替换之用。

     if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

完成操作系统的一些信息获取,如内存页面大小、系统限制资源等信息;所有的这些资源都将会被保存在对应的全局变量中,因此后续访问将会很便利。

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

初始化一个做循环冗余校验的表,由此可以看出后续的循环冗余校验将采用高效的查表法。crc算法此处就不做分析,网上一堆一堆的相关资料,有兴趣的同学可以了解。

    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。在NGINX环境变量中,每个socket中间用冒号或分号隔开。完成继承同时设置全局变量ngx_inherited为1。

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

额!!!这个循环中的ngx_modules数组好像没见定义,难不成是火星来的?当然不是,如其名,这就是一个存储所有模块的信息,包括自己开发的模块都会放到这个数组中,而这个神秘的数组却是在自动编译的时候生成的,位于objs/ngx_modules.c文件中。这个循环的目的是清晰可见的——对所有模块进行索引编号,方便以后访问;同时借助ngx_max_module对所有模块进行了一次点数,确定究竟有多少模块。而神秘数组ngx_modules的长相大概如下:

ngx_module_t *ngx_modules[] = {
    &ngx_core_module,
    &ngx_errlog_module,
    &ngx_conf_module,
    &ngx_events_module,
    &ngx_event_core_module,
    &ngx_epoll_module,
    &ngx_openssl_module,
    &ngx_http_module,
    。。。
};
    cycle = ngx_init_cycle(&init_cycle);

这里将会初始化很多的东东到全局变量cycle中,是Nginx启动初始化的核心之处。ngx_init_cycle函数的过程比较多,放下一篇blog中逐段分析。

    if (ngx_init_signals(cycle->log) != NGX_OK) {
        return 1;
    }

注册一堆信号处理程序,需要注册的信号及相应的信号处理函数被放在一个类型为ngx_signal_t的数组signals中。数组定义在src/os/unix/ngx_process.c中。ngx_signal_t结构类型定义了信号值,信号名字,信号对应动作名以及信号处理函数。

     if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) {
            return 1;
        }
        ngx_daemonized = 1;
    }

ngx_daemon肯定就是用来实现守护进程的函数了,此处就不多废话了,有需要写server程序的,可以直接copy这段代码实现守护进程。

    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

玩过Nginx的人都知道,Nginx启动后有一个记录进程id的文件,这个文件里面就一个pid。原来这个pid就是在这个地方记录下来的。查看ngx_create_pidfile函数可以看到这样的一行代码

if (ngx_process > NGX_PROCESS_MASTER) {
return NGX_OK;
},这行代码就说明了,不是master进程时,就不创建这样的一个pid文件。

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);
    } else {
        ngx_master_process_cycle(cycle);
    }

到此就基本完成Nginx的启动初始化过程了,即将开始进程相关的工作了,这里最重要的ngx_master_process_cycle这个过程,在这个过程里实现了master-worker模式的进程模型,也是生成环境下Nginx的常用模型。既然此处已不再是初始化工作,那么就留到后续分析吧。

上述所有过程都是在main函数里完成的,下一篇分析ngx_init_cycle函数。

From: http://www.tbdata.org/archives/1092

nginx core dump trace

问题: 如何core dump

答案: 配置方法如下

1. 配置nginx跑在非daemon和非master_process模式,配置样例

daemon off;

master_process off;

2. 配置worker_processes个数,可设置为1

worker_processes 1;

3. 启动nginx

ulimit -c unlimited;

/opt/soft/nginx/sbin/nginx -c /opt/soft/nginx/conf/nginx.conf;

4. 阅读coredump

gdb sbin/nginx  -c core.$pid$

gdb>where

#貌似说最新的coredump办法,不影响在线业务

nginx配置方法
worker_rlimit_core  500M;
working_directory   /path/to/cores/;
要保证nginx进程用户对working_directory可写
原来的配置都不用动,也跑在daemon模式下,有master进程
只需要增加这两行就成了
worker_rlimit_core限制生成core大小的,如果占内存多就搞大
确认需要以下方式:
#新建一个文件夹, 并确认nginx可以读写
$ mkdir /tmp/cores
$ sudo chown root:root /tmp/cores
$ sudo chmod 1777 /tmp/cores
#设置unlimited core file dump
$ ulimit -c unlimited
#设置系统级别的core file
$ echo "/tmp/cores/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
#允许suid dumpable
$ sudo sysctl -w fs.suid_dumpable=2
$ sysctl -p
可以发送信号, 让nginx 直接生成coredump, 测试以上配置是否生效
比如kill -11 $work_process_pid