Nginx(engine x)是一个高性能的HTTP服务器,也是一款轻量级的Web服务器,反向代理服务器及电子邮件IMAP/POP3/SMTP代理服务器。Nginx是由伊戈尔·赛索耶夫为站点Rambler.ru开发的。第一个公开版本发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示列配置文件和低系统资源的消耗而闻名。其特色是占用内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现比较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。html
Nginx是一种轻量级,高性能,多进程的Web服务器,很是适合做为静态资源服务器使用,而动态的访问操做能够是用稳定的Apache,Tomcat及IIS等来实现。这里就以Nginx做为代理服务器的同时,也使用其做为静态资源服务器。
静态资源服务器经过绝对路径去访问,放在nginx服务器当中。
动态资源经过url拼接字符串的方式去访问例如tomcat服务器node
1).轮询(默认)
每一个请求按实际顺序逐一分配到不一样的后端服务器,若是后端服务器dump掉,能自动剔除。
2) weight(权重)
为后台服务器指定轮询概率,weight和访问量成正比,让性能高的服务器承担更多的访问量。
3).ip_hash
每一个请求按访问ip的hash结构分配,这样每一个访客固定访问一个后端服务器,能够解决session的问题。
4).fair(第三方)
按后端服务器的响应时间来分配请求,响应时间快短的优先分配。
5).url_hash(第三方)
按访问url的hash结果来分配请求,使每一个url定向到同一个后端服务器,后端服务器为缓存时比较有效。nginx
当咱们肯定一系列负载的服务器后,若是你先访问到A服务器,下一次请求忽然转到B服务器。这时候与A服务器创建的Session,传到B服务器确定是没法响应的。下面咱们来看一下解决方案:
1).Session或凭据缓存到独立的服务器上
将seesion保存到独立的服务器,缓存效率会比较高,但若是同时访问的服务器过多的话,可能致使session服务器没法负荷而宕机。
2).Session或凭据保存数据库中
保存到数据中,除了要控制Session的有效期,同时也加剧了数据库的负担,因此最终转变为SQL Server负载均衡,涉及读,写,过时同步,处理起来会很复杂。
3).nginx ip_hash保持同一IP的请求都是指定到固定的一台服务器
经过nginx ip_hash负载保持对同一服务器的会话,这种方式最方便,最轻量。git
若是实现了均衡负载,除了Session问题,咱们还会碰到文件的上传下载问题。文件不可能上传不一样的服务器上,这样会致使下载不到对应文件的问题。下面来看一下解决方案:
1).独立文件服务器
2).文件压缩数据库
两种方案都是经常使用的,咱们来讲一下文件压缩数据库,之前的方式都是将文件二进制压缩相当系型数据库,而如今NOSQL的流行,加上MongoDB处理文件又比较方便,因此文件压库又多了一种选择。毕竟文件服务器的效率和管理以及安全都不及数据库。github
反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的链接请求,而后将请求转发给内部网络上的服务器;并将从服务器上获得的结果返回给Internet上请求链接的客户端,此时代理服务器对外就表现为一个服务器。
反向代理服务器:
一般的代理服务器,只用于代理内部网络对Internet的链接请求,客户机必须指定代理服务器,并将原本要直接发送到Web服务器上的http请求发送到代理服务器中。当一个代理服务器可以代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务器。web
某台节点服务器挂了,可是Nginx仍然会可能选中这个出故障的机器,而后就一直链接着是由于超时时间很长,具体多长不清楚,因此为了不一直链接着,咱们须要设置超时时间。
用Keepalived搭建双Nginx server集群,防止单点故障正则表达式
worker_processes auto; worker_rlimit_nofile 100000; worker_cpu_affinity 0001 0010 0100 1000 0001 0010 0100 1000;
worker_processes:
定义了nginx对外提供web服务时的worker进程数。最优值取决于许多因素,包括(但不限于)CPU核的数量、存储数据的硬盘数量及负载模式。不能肯定的时候,将其设置为可用的CPU内核数将是一个好的开始(设置为“auto”将尝试自动检测它)。shell
worker_rlimit_nofile:
更改worker进程的最大打开文件数限制。若是没设置的话,这个值为操做系统的限制。设置后你的操做系统和Nginx能够处理比“ulimit -a”更多的文件,因此把这个值设高,这样nginx就不会有“too many open files”问题了。数据库
worker_cpu_affinity:
CPU亲和力配置,让不一样的进程绑定不一样的CPU,能够减小因为线程切换时CPU切换带来的缓存拷贝致使下降效率。后端
events模块中包含Nginx中全部处理链接的设置。
events { worker_connections 2048; multi_accept on; use epoll; }
worker_connections:
设置可由一个worker进程同时打开的最大链接数。若是设置了上面提到的worker_rlimit_nofile,咱们能够将这个值设得很高。可是不能超过系统的可用socket链接数限制(~ 64K)。
multi_accept:
告诉nginx收到一个新链接通知后接受尽量多的链接。
use 设置用于复用客户端线程的轮询方法。若是你使用Linux 2.6+,你应该使用epoll。若是你使用FreeBSD,你应该使用kqueue。
(值得注意的是若是你不知道Nginx该使用哪一种轮询方法的话,它会选择一个最适合你操做系统的)
HTTP模块控制着Nginx http处理的全部核心特性。
http { server_tokens off; sendfile on; tcp_nopush on; tcp_nodelay on; ... }
server_tokens:
并不会让nginx执行的速度更快,但它能够关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
sendfile:
可让sendfile()发挥做用。sendfile()能够在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据以前在用户空间申请数据缓冲区。
以后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是当即将数据从磁盘读到OS缓存。
由于这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)。
tcp_nopush:
告诉nginx在一个数据包里发送全部头文件,而不一个接一个的发送。
tcp_nodelay:
告诉nginx不要缓存数据,而是一段一段的发送--当须要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能当即获得返回值。
access_log off; error_log /var/log/nginx/error.log crit;
access_log:
设置nginx是否将存储访问日志。关闭这个选项可让读取磁盘IO操做更快(aka,YOLO)
error_log:
告诉nginx只能记录严重的错误:
nginx依赖于pcre, openssl, zlib, nginx-rtmp-module。故在编译nginx以前必须下载先编译这些库。
pcre是一个Perl库,包括perl兼容的正则表达式库。
zlib提供数据压缩用的函式库。
nginx-rtmp-module是nginx的rtmp流媒体服务拓展库,实现了rtmp,hls,dash的流媒体服务功能。下面是本人编写的nginx一键下载编译脚本,运行该脚步便可下载编译nginx:
#!/bin/bash #indicate that this script execute by /bin/bash # 本脚本用于自动下载nginx已经依赖库pcre, openssl, zlib, nginx-rtmp-module,并编译安装,安装时须要输入管理员帐号权限 #zipexts=(".tar.gz" ".tar.bz2" ".tar.Z" ".tgz" ".tar" ".gz" ".bz2" ".Z" ".rar" ".zip") #zipexts=(".tar.gz" ".tar.bz2" ".tar.Z" ".tgz" ".tar" ".gz" ".bz2" ".Z" ".rar" ".zip") # 因为shell脚本的函数不能返回字符串,故设置全局变量以便记录dezip产生的返回值以及下downloazanddezip函数下载解压后的文件夹名称 extname="" outputname="" # 解压压缩包,并返回解压后的文件夹或文件名称 # param1:压缩包名称,必填项 # param2:解压到指定文件夹,可为空 # 返回值:无, 注,shell返回值只能为整形,不能为字符串 dezip(){ outputname=$2 extname="" exename="tar" unzipflag="" echo "param1:"$1 # 检测压缩包类型,并使用对应的解压方式 if expr match $1 ".*.tar.gz" != 0; then extname=".tar.gz" exename="tar" unzipflag="-zxvf" #echo $extname elif expr match $1 ".*.tar.bz2" != 0; then extname=".tar.bz2" exename="tar" unzipflag="-xjf" #echo $extname elif expr match $1 ".*.tar" != 0; then extname=".tar" exename="tar" unzipflag="-xvf" elif expr match $1 ".*.tgz" != 0; then extname=".tgz" exename="tar" unzipflag="-xvf" elif expr match $1 ".*.gz" != 0; then extname=".gz" exename="gzip" # 或gunzip unzipflag="-d" elif expr match $1 ".*.bz2" != 0; then extname=".bz2" exename="bzip2" # 或bunzip2 unzipflag="-d" elif expr match $1 ".*.tar.Z" != 0; then extname=".tar.Z" exename="tar" unzipflag="-xZf" elif expr match $1 "*.Z" != 0; then extname=".Z" exename="uncompress" unzipflag="" elif expr match $1 ".*.rar" != 0; then extname=".rar" exename="unrar" unzipflag="e" elif expr match $1 ".*.zip" != 0; then extname=".zip" exename="unzip" unzipflag="-o" fi if [ ! -d $outputname ]; then outputname=${1%$extname} echo "outputname" $outputname fi #if [ ! -d $outputname ]; then #mkdir $outputname #echo $outputname #fi echo "$exename $unzipflag $1" # 解压文件 $exename $unzipflag $1 #return $extname } # 下载压缩包并解压 # param1:url # param2:zip # return: dezip filename downloazanddezip() { if [ -d $1 ]; then echo "Invalid url, please input url while you run downloazanddezip" fi downloadurl=$1 # 截取?前面的字符串 downloadurl=${downloadurl%\?*} echo $downloadurl # 截取最后一个/后面的字符串,即压缩包名称 zipname=${downloadurl##*/} echo $zipname if [ ! -f $zipname ]; then curl -o $zipname $1 echo 'curl -o $zipname $1' fi echo "dezip:"$zipname dezip $zipname #extname=$? echo $extname'=dezip' $zipname if expr match $zipname $extname == 0; then zipname=${zipname%$extname} echo "zipname:"$zipname fi outputname=$zipname } # 下载nginx源码,若是连接有误,直接替换连接便可 curdir=$PWD downloazanddezip http://117.128.6.28/cache/nginx.org/download/nginx-1.14.2.tar.gz?ich_args2=468-23103716018527_5b6f2632bf91b3cdae35405cfb43338b_10001002_9c89612cdfcbf8d59538518939a83798_ff478ef610d500dd7f20fe13dd251d7b # 记录nginx库源码文件夹目录名称 nginxname=$outputname cd $outputname if [ ! -d "./thirdpart/" ];then mkdir thirdpart fi cd ./thirdpart # 下载pcre库 downloazanddezip https://ftp.pcre.org/pub/pcre/pcre-8.42.zip # 记录pcre库源码文件夹目录名称 pcrename=$outputname # 下载openssl downloazanddezip https://www.openssl.org/source/openssl-1.0.2q.tar.gz # 记录openssl库源码文件夹目录名称 opensslname=$outputname # 下载zlib库 downloazanddezip http://117.128.6.17/cache/www.zlib.net/zlib-1.2.11.tar.gz?ich_args2=531-22232503018317_67f53fed3443a8995b0d31f74b74bce1_10001002_9c89612cdfc7f8d09639518939a83798_9b3b5eb8fa2f98e0b42e37f3838be97f # 记录zlib库源码文件夹目录名称 zlibname=$outputname # 从github下载nginx-rtmp-module源码 if [ ! -d "./nginx-rtmp-module/" ];then git clone https://github.com/arut/nginx-rtmp-module.git fi cd ../ make clean ./configure --prefix=$curdir/$nginxname/build --with-openssl=$curdir/$nginxname/thirdpart/$opensslname --with-pcre=$curdir/$nginxname/thirdpart/$pcrename --with-zlib=$curdir/$nginxname/thirdpart/$zlibname --add-module=$curdir/$nginxname/thirdpart/nginx-rtmp-module --with-http_ssl_module make make install
打开build目录下conf文件夹下的nginx.conf文件:
http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; # add stat page location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root $nginxpath/thirdpart/nginx-rtmp-module; } # add stat page end location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 支持flv、mp4文件点播 location ~* \.flv$ {#flv 支持 root $flvpath;#flv点播文件目录 } location ~* \.mp4$ {#MP4 支持 root $mp4path;#mp4点播文件目录 } }
运行nginx:
$sudo ./nginx -c $buildpath/conf/nginx.conf
而后打开浏览器访问:
http://127.0.0.1/test.mp4 若是可以正常播放,说明点播服务配置成功。
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"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root $nginxpath/third/nginx-rtmp-module; } location / { root html; index index.html index.htm; } location /live { #这里也是须要添加的字段。 types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } alias /opt/video/hls; expires -1; add_header Cache-Control no-cache; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # 支持flv、mp4文件点播 location ~* \.flv$ {#flv 支持 root $flvpath;#flv点播文件目录 } location ~* \.mp4$ {#MP4 支持 root $mp4path;#mp4点播文件目录 } } } # 增长rtmp服务 rtmp { server { listen 1935; chunk_size 4096; # rtmp点播 application vod { play $rtmpvodpath;#rtmp点播文件存放路径 } # rtmp直播 application live { live on; hls on; #这个参数把直播服务器改形成实时回放服务器。 wait_key on; #对视频切片进行保护,这样就不会产生马赛克了。 hls_path $hls_save_path; #切片视频文件存放位置。 hls_fragment 10s; #每一个视频切片的时长。 hls_playlist_length 60s; #总共能够回看的事件,这里设置的是1分钟。 hls_continuous on; #连续模式。 hls_cleanup on; #对多余的切片进行删除。 hls_nested on; #嵌套模式。 } } }
安装ffmpeg,并使用ffmpeg进行rtmp推流
$ sudo apt-get install ffmpeg $ ffmpeg -re -I $mp4path/test.mp4 -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/live $ ffplay -I rtmp://localhost:1935/live
若能正常播放rtmp流,则rtmp直播服务发布成功。