原文链接:Nginx & Comet: Low Latency Server Push
服务器推送(Server Push)是高效的、延迟低的数据交换方式。如果数据发送端与接收端都在互联网中公开可见,可以使用PubSubHubbub 或simpler Webhook 等方法完成任务。但是如果数据接收方在防火墙内、在内网或它只是一个浏览器(只可以向外发送数据请求,无法处理传入的数据),则实现服务器推送就更难了。如果你有冒险精神,你可以建立一个反向HTTP服务器 。如果你寻求可靠的解决方案,也许你要等待HTML5的WebSocket’s API 特性了。但如果你需要即刻可以实现的解决方案,你可以妥协一下,使用异步推送模式来代替,你可以使用Comet ,也被称为反向Ajax、HTTP服务器推送或HTTP流。
早在2006年Alex Russel 提出了一个不坏的技术思路,那就是长连接(Comet)概念:从客户端发起并保持一个连接直到数据出现并传送(long polling ),或者永远保持一个连接,通过它推送数据到客户端(streaming )。这两种方法的好处是数据传送非常及时。因此长连接技术广泛用于聊天应用(Facebook, Google, Meebo等)以及实现即时触发的机制。
将 Nginx 变成一个长连接服务器
实现长连接服务比较大的问题是特殊的隐形需求以及事件驱动web服务器能否高效处理众多的长连接。Friendfeed的Tornado 服务器是一个标准应用级服务器的好例子。另外,感谢Leo Ponomarev的努力,你现在可以用nginx_http_push_module 插件使你的Nginx服务器变身成为一台完全功能的长连接服务器。
使用自定义的一套框架结构,Leo的插件只提供两个对外的接口:一个是订阅者,一个是发布者。客户端连接Nginx服务器,创建针对一个频道的long- polling长连接并等待数据。同时,发布者只是简单的将数据使用POST方法提交给Nginx,插件收到数据后将它一个个发给等待的客户端。这表明发 布者不需要直接传递数据,它只是一个简单的事件产生器!
还有更强大的功能是,客户端和发布端可以建立任意的channel,插件提供消息队列功能,也就是说Nginx服务器会在客户端断线的情况下临时保存消息。队列消息可以按照时间、等待列表长度或内存限制大小来失效释放。
Nginx 和 Ruby 配置例子
首先,你需要从源代码编译一个Nginx。解压源代码包,从GitHub获取插件的源码并放入Nginx的源码目录,然后使用下面的参数编译(./configure –add-module=/path/to/plugin && make && make install )。下一步,参考readme 文件和协议 文件,了解所有的参数选项。一个多客户端接收信息的配置例子如下:
# internal publish endpoint (keep it private / protected) # 内部发布点(保证私有或不对外公开) location /publish { set $push_channel_id $arg_id; #/?id=239aff3 or somesuch push_publisher; push_store_messages on; # enable message queueing # 打开消息队列 push_message_timeout 2h; # expire buffered messages after 2 hours # 2小时后消息失效 push_max_message_buffer_length 10; # store 10 messages # 保存10条消息 push_min_message_recipients 0; # minimum recipients before purge # 清除前面接收人数目 } # public long-polling endpoint # 公开的长连接接收点 location /activity { push_subscriber; # how multiple listener requests to the same channel id are handled # 每个channel id能有多少客户端同时连接 # - last: only the most recent listener request is kept, 409 for others. # – last: 只有最频繁请求的客户端能保持,其它连接返回409 # - first: only the oldest listener request is kept, 409 for others. # – first: 只有最早连接的那个客户端可以保持,其它连接返回409 # - broadcast: any number of listener requests may be long-polling. # – broadcast: 所有的客户端连接都会是长连接 push_subscriber_concurrency broadcast; set $push_channel_id $arg_id; default_type text/plain; }
编译配置好Nginx,并且启动它,我们可以建立一个简单的广播场景,一个数据发送广播方,几个订阅信息接收方来测试我们的长连接服务器。
require 'rubygems' require 'em-http' def subscribe(opts) listener = EventMachine::HttpRequest.new('http://127.0.0.1/activity?id='+ opts[:channel]).get :head => opts[:head] listener.callback { # print recieved message, re-subscribe to channel with # 输出所获取的内容,并重新订阅这个频道 # the last-modified header to avoid duplicate messages # 使用header last-modified去忽略之前已经获取的数据 puts "Listener recieved: " + listener.response + "\\n" modified = listener.response_header['LAST_MODIFIED'] subscribe({:channel => opts[:channel], :head => {'If-Modified-Since' => modified}}) } end EventMachine.run { channel = "pub" # Publish new message every 5 seconds # 每5秒钟发布一个新的消息 EM.add_periodic_timer(5) do time = Time.now publisher = EventMachine::HttpRequest.new('http://127.0.0.1/publish?id='+channel).post :body => "Hello @ #{time}" publisher.callback { puts "Published message @ #{time}" puts "Response code: " + publisher.response_header.status.to_s puts "Headers: " + publisher.response_header.inspect puts "Body: \\n" + publisher.response puts "\\n" } end # open two listeners (aka broadcast/pubsub distribution) # 打开两个客户端 subscribe(:channel => channel) subscribe(:channel => channel) }
nginx-push.zip (Full Nginx Config + Ruby client)Downloads: 270 File Size: 2.7 KB |
在上面的代码中,每5秒钟数据发布端向Nginx发出新的事件,nginx将数据通过长连接转发给两个订阅的客户端。当消息发送到客户端,服务器会断开 他们的连接,客户端会立即重连并等待下一次数据的到来。这样,就实现了Nginx将一个数据发布端到客户端的实时消息推送机制!
Long Polling, Streaming, and Comet in Production
Leo的模块还在开发 期,还需要时间来稳定下来,但它是一个需要关注的项目 。最近的更新计划都着重于bug修复,未来的计划里有描述要加入流的模式:代替现在每次数据获取后都要重连的情况(long polling),Nginx会保持连接,将数据一段段的实时传送给客户端。拥有这个功能后你能很方便的部署你自己的信息触发式API(例如:Twitter流 )。
相关推荐
在Linux环境中,Nginx是一个广泛应用的开源Web服务器,以其高性能、稳定性以及模块化设计而著名。本篇文章将详细介绍如何在Linux系统下通过源码编译的方式安装Nginx,这个过程包括解压源码包、配置、编译以及安装等...
搭建ffmpeg+nginx+yasm流媒体服务器低延迟 一、流媒体服务器概念 流媒体服务器是指能够实时地传输和处理视频流的服务器,通常用于直播、监控、在线视频等应用场景中。搭建流媒体服务器需要选择合适的软件和硬件...
决战Nginx技术卷:高性能Web服务器部署与运维.pdf决战Nginx技术卷:高性能Web服务器部署与运维.pdf
《决战Nginx技术卷:高性能Web服务器部署与运维(基于php、Java、ASP.NET等)》详细讲述了Nginx服务器与动态语言应用的结合,动态语言包括PHP、Python、Perl、Java、Ruby及ASP.NET架构。对于PHP部分,我们使用了...
决战Nginx 技术卷:高性能Web服务器部署与运维.讲解Nginx的优化配置,以及运维部署
《决战Nginx系统卷:高性能Web服务器详解与运维》第一部分首先讲述了Nginx服务器的功能、模块管理和进程管理,然后讲述Nginx如何处理请求,在这个基础之上再认识Nginx提供的服务器的名字,Nginx服务器最大的焦点在于...
第27章 Nginx与访问者的地理信息 第28章 Nginx的图像处理 第29章 location中随机显示文件 第30章 后台Nginx服务器记录原始客户端的IP地址 第31章 解决防盗链 第32章 Nginx提供HTTPS服务 第33章 监控Nginx的...
nginx&动态分离&负载均衡.md
访问`http://your_server_ip/info.php`,如果看到PHP信息页面,则表示Nginx与PHP已经成功集成。 10. **安全考虑**: 为了安全,建议关闭默认的Nginx欢迎页面,编辑`/etc/nginx/nginx.conf`,删除或注释掉`index....
Nginx 问题 之 nginx: [emerg] unknown directive "echo" in /weblogic/nginx/conf/nginx.conf:43-附件资源
Restarting nginx daemon: nginxcat: /usr/local/nginx/logs/nginx.pid: No such file or directorykill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec … or kill -l [sigspec]nginx not ...
### Nginx常见错误及其解决方法 #### 一、启动错误:`sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory` **问题描述**: 在尝试启动...
在推流过程中,nginx主要用来作为流媒体服务器,负责推送流媒体内容到客户端。nginx可以与FFmpeg结合,使用FFmpeg将视频文件转换为流媒体格式,然后将其推送到客户端。 RTMP RTMP(Real-Time Messaging Protocol)...
如果Nginx已成功启动,你可以看到响应信息。 ``` curl 127.0.0.1:80 ``` 接下来,我们将配置Nginx在系统启动时自动启动: 1. **创建systemd服务文件**:首先,创建一个名为`nginx.service`的服务文件,该文件...
Windows 下使用 RunHiddenConsole 启动 nginx、php-fpm, https://www.nginx.com/resources/wiki/start/topics/examples/phpfastcgionwindows/
3. Nginx 运行问题:可以查看 Nginx 的错误日志,查看错误信息。 Nginx 的一些高级主题: 1. Nginx 的高级配置:可以使用 Nginx 的高级配置directive,例如使用 Geo module 实现基于地理位置的内容分发。 2. Nginx...
Nginx入门&进阶.pdf
nginx版本:1.22.1 当前最新稳定版本 平台架构:x86_64 nginx rpm二进制包 适合centos 7 redhat 7 系列的操作系统安装使用 开启了ipv6支持
Windows 下使用 RunHiddenConsole 启动 nginx、php-fpm, https://www.nginx.com/resources/wiki/start/topics/examples/phpfastcgionwindows/