Nginx模块之echo

选择nginx

Nginx性能为王:

  • 支持epoll,大规模高并发
  • 支持Linux的sendfile系统调用,可以高效地把硬盘中数据发送到网络上。

选择Nginx的原因:

  • 更快:要理解它怎么做到更快的
  • 高扩展性:不同模块,大量的第三方模块,并且模块之间具有很好的隔离性;
  • 高可靠性:来自于核心框架代码的优秀设计、模块设计的简单性。master-worker模式很稳定;
  • 低内存消耗:10000个非活跃的http keep-alive连接至消耗2.5MB内存!精细的数据结构控制,c语言精华的体现;
  • 单机支持10万以上的并发连接:上限只取决于内存
  • 热部署,从没见过这么顺滑的reload
  • BSD许可协议的自由性

echo模块 - debug利器

背景

github开源,openresty作者推荐
https://github.com/openresty/echo-nginx-module

实例

Location测试:

1
2
3
location /test {
echo "test here";
}

curl "http://testecho.qidian.com/test"

计算后端请求时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
location /timed_hello {
# 计时器重置
echo_reset_timer;
echo hello world;
# 休眠2.5s
echo_sleep 2.5;
# 打印最终耗时
echo "'hello world' takes about $echo_timer_elapsed sec.";
echo_reset_timer;
echo hiya igor;
echo_sleep 1;
echo "'hiya igor' takes about $echo_timer_elapsed sec.";
}

curl "http://testecho.qidian.com/timed_hello"

请求代理:

1
2
3
4
5
6
7
8
9
10
location /echo_proxy {
# 修改向下游请求的body
echo_before_body hello;
echo_before_body world;
# 进行proxy pass的请求
proxy_pass $scheme://10.247.165.120:10090/monitor/monitor.html;
# 修改返回到client端的body
echo_after_body hiya;
echo_after_body igor;
}

curl "http://testecho.qidian.com/echo_proxy"

发起子请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 子请求1,充分利用epoll的优势
location /main1 {
echo_reset_timer;
echo "start takes about $echo_timer_elapsed sec.";
# subrequests in parallel,并发子请求
echo_location_async /sub1;
echo_location_async /sub2;
# 打印结果为0s 请求耗时为2s
echo "took $echo_timer_elapsed sec for total.";
}
# 子请求2,并未发挥子请求优势
location /main2 {
echo_reset_timer;
echo "start takes about $echo_timer_elapsed sec.";
# 同步的进行请求
echo_location /sub1;
echo_location /sub2;
# 打印结果为3s 最终耗时3s
echo "took $echo_timer_elapsed sec for total.";
}
# 子请求1
location /sub1 {
echo_sleep 2;
echo hello;
}
# 子请求2
location /sub2 {
echo_sleep 1;
echo world;
}

curl "http://testecho.qidian.com/main1" curl "http://testecho.qidian.com/main2"

同时发起多个子请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
location /multi {
# 指定请求方式 参数等
echo_subrequest_async POST '/tools' -q 'foo=Foo' -b 'hi';
echo_subrequest_async PUT '/tools' -q 'bar=Bar' -b 'hello';
}
location /tools {
# 支持打印打印多个nginx的内建变量
echo "querystring: $query_string";
echo "method: $echo_request_method";
echo "body: $echo_request_body";
echo "content length: $http_content_length";
echo '///';
}

curl "http://testecho.qidian.com/multi"

静态资源合并:

1
2
3
4
5
6
7
8
9
# 不多说,和combo扩展非常的类似
location /merge {
default_type 'text/javascript';
echo_foreach_split '&' $query_string;
echo "/* JS File $echo_it */";
echo_location_async $echo_it;
echo;
echo_end;
}

curl "http://testecho.qidian.com/merge?/foo.js&/test.js"

if: 由于nginx的if语法支持的太差,因此debug在配置的时候还是非常有必要的

1
2
3
4
5
6
7
8
location ^~ /if {
set $res miss;
if ($arg_val ~* '^a') {
set $res hit;
echo $res;
}
echo $res;
}

curl "http://testecho.qidian.com/if?val=abc"
curl "http://testecho.qidian.com/if?val=ddd"

其中涉及的一些nginx模块的开发概念

subrequest与upstream

upstream:
提供了一种访问后端服务的能力。更加基础,同时充分利用了nginx优秀设计中的epoll模型,从而做到了异步和无阻塞. 通信方式不限,通信协议不限。常见的就是udp和tcp,同时再配合二进制的一些高校打包协议,这时候你就可以让nginx和后端服务无缝的衔接在一起了。

subrequest: 子请求
针对的是第三方的服务,举个例子,你的网站导航服务依赖于第三方服务比如新浪天气的返回结果,那么可以使用子请求的方式。
但是第三方的服务协议局限于http,同时它的底层也是由upstream实现的。但是相比之下概念和出发点有所不同。

epoll

几个名词:IO多路复用、高性能网络模型、同步异步、阻塞非阻塞、协程与并发。
推荐篇文章:http://blog.csdn.net/tianmohust/article/details/6677985

热评文章