OpenResty 中的流式 HTTP 响应输出
在这个视频中,我将演示如何在 OpenResty 中进行流式 HTTP 响应体输出。
1 | cd ~/ |
我们一如既往地创建子目录结构。
1 | mkdir logs conf html |
我们快速写出模板配置。
1 | vim conf/nginx.conf |
并在此文件中进行以下编辑。
- 我们创建一个 HTTP 服务器,监听 8080 端口。
- 增加一个
/test
位置。 - 指定这个
application/octet-stream
MIME 类型是很重要的,这样才能让 Chrome 网络浏览器满意。 - 通过 content_by_lua_block 指令添加一些 Lua 代码。
- 我们每隔一秒输出一行输出。
- 我们需要显式调用 ngx.flush 方法来刷新 Nginx 的写缓冲区。这是一个 100% 非阻塞的调用。
- 而我们使用
ngx.sleep
在每次循环迭代中睡一秒钟。这也是非阻塞的。 - 然后我们为
html
目录创建一个根位置。
1 | worker_processes 1; |
我们现在就来检查一下整个目录树。
1 | tree . |
看起来不错。
现在启动这个 OpenResty 应用程序。
1 | openresty -p $PWD/ |
是时候用 curl
来查询我们的 HTTP 位置了。
1 | curl 'http://127.0.0.1:8080/test' |
酷,确实是每秒生成一行字!
为了验证一切是否真的是非阻塞的,我们可以用 weighttp
工具加载这个 HTTP API。请注意,这将需要一段时间,因为我们在这里故意放慢响应速度。
1 | weighttp -c 500 -k -n 500 127.0.0.1:8080/test |
因此,在 500 个并发请求的情况下,我们仍然可以实现每秒 120 个以上的请求!需要注意的是,每个请求需要 4 秒才能完成。而这里我们只使用了一个工作进程和一个操作系统线程。
我们仍然可以将并发量提高很多,但是我们需要对 Nginx 配置进行相应的调整。
1 | vim conf/nginx.conf |
比如把 worker_connections
调到一个较大的数值。
通过启用访问日志缓冲也可以获得更好的性能。我们还可以减少请求内存池的大小。
现在让我们创建一个 HTML 页面,在 Web 浏览器中进行测试。
1 | vim html/a.html |
我们在这个文件中进行以下编辑。
- 增加一个
DIV
标签,以保持输出。 - 添加一些 JavaScript 来发送 AJAX 请求到我们之前的 HTTP 位置。
- 我们取出
DIV
元素。 - 让我们添加一个 JavaScript 函数来进行流式响应接收。
- 确保有新的数据。
- 将我们的新数据追加到
DIV
元素中。在这里,我们是懒惰的。我们不需要对特殊的 HTML 字符进行转义。 - 而且我们每秒都会检查新的传入响应数据。
- 火狐支持更巧妙的方式,但我们也要支持 Chrome。
- 最后,我们处理响应体流的结束。
- 最后一次检查响应数据。
- 删除我们的定期计时器。
- 并将最终的输出结果追加到网页上。
- 为了简洁起见,我们在此省略错误处理。
1 |
|
我们再来检查一下整个目录树。
1 | tree . |
我们不需要重新加载或重新启动 OpenResty 服务器,因为它只是一个静态的 HTML 页面。
1 | ps aux|grep nginx|grep -v /tmp/ |
是时候用 Chrome 打开这个 HTML 页面了。
生效了!这就是我今天要讲的全部内容。 如果你喜欢这个教程,请订阅这个博客网站和我们的 YouTube 频道 或 B 站频道。谢谢!
关于本文和关联视频
本文和相关联的视频都是完全由我们的 OpenResty Demo 系统从一个极简单的剧本文件自动生成的。
关于作者
章亦春是开源项目 OpenResty® 的创始人,同时也是 OpenResty Inc. 公司的创始人和 CEO。他贡献了许多 Nginx 的第三方模块,相当多 Nginx 和 LuaJIT 核心补丁,并且设计了 OpenResty XRay 等产品。
关注我们
如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的博客网站 。也欢迎扫码关注我们的微信公众号:
翻译
我们提供了英文版原文和中译版(本文) 。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!