最近一直在做公司的应用软件服务架构的升级工作,里面涉及使用mod_proxy替换先前的mod_ajp,因为我们要用jetty7。
同时万恶的jetty 7对ajp协议支持不是很好, 具体可见我的另一篇博文: 纠结的mod_jk与jetty的组合。 在线下测试少量的请求没啥问题,一到线上跑个几分钟就开始抛异常了,查了jetty的mail list,也有人报类似的bug。
所以后续的工作重心还是回到mod_proxy_http上来,今天在调试mod_proxy配置时,出了一些小插曲,记录分享一下给大家,免得大家再走歧路。
大致url类型介绍:
目前公司的url基本是按模块进行划分,比如 http://域名/module/xxxx.html, 域名后多了一个module路径,用于区分不通的业务,比如home , admin , product等。
对mod_proxy的使用需求:
主要的资料还是来自于官方文档:http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
涉及的主要配置原语:
其他具体配置含义不多做介绍,大家可以看官方文档。
这个mod_proxy本身就支持worker池的概念,不过需要配置一下几个参数:
名称 | 默认值 | 描述 | 官网文档描述 |
min | 0 | 最小保持的连接数 | Minimum number of connections that will always be open to the backend server. |
max | 1...n | 所谓的硬性最大值 最大可保持的连接数,如果是prefork模式则值为1,如果是走worker模式,值等价于ThreadsPerChild配置
|
Hard Maximum number of connections that will be allowed to the backend server. Apache will never create more than the Hard Maximum connections to the backend server. |
smax | max | 所谓的软性最大值,如果连接数超过smax后,大于smax的链接就会进行ttl空闲连接管理 | Upto the Soft Maximum number of connections will be created on demand. Any connections above smax are subject to a time to live or ttl . |
connectiontimeout | timeout | 创建链接的超时时间,单位毫秒 | Connect timeout in seconds. The number of seconds Apache waits for the creation of a connection to the backend to complete. By adding a postfix of ms the timeout can be also set in milliseconds. |
timeout | ProxyTimeout | 等待后端的应用返回数据的超时时间,不可太长,也不可太短 | Connection timeout in seconds. The number of seconds Apache waits for data sent by / to the backend. |
ttl | - | 空闲连接的管理时间 | Time To Live for the inactive connections above the smax connections in seconds. Apache will close all connections that has not been used inside that time period. |
最后的配置:
min=5 smax=16 ttl=600 timeout=20
说明:
ProxyPass /image/ ! ProxyPass /ok.html !
ProxyPass / http://localhost:7001/
mod_proxy进行proxy匹配时,是按照配置文件的顺序进行查找匹配,具体可见官方文档描述,直接贴英文。
The configured ProxyPass and ProxyPassMatch rules are checked in the order of configuration. The first rule that matches wins. So usually you should sort conflicting ProxyPass rules starting with the longest URLs first. Otherwise later rules for longer URLS will be hidden by any earlier rule which uses a leading substring of the URL. Note that there is some relation with worker sharing. For the same reasons exclusions must come before the general ProxyPass directives
说明:
ProxyPassMatch ^/(home|admin|product|monitor)/(.*)$ http://localhost:7001
ProxyPass / !
官方文档针对ProxyPassMatch有这么一个例子:
ProxyPassMatch ^(home|admin|product|monitor)/(.*)$ http://localhost:7001/$1/$2
./ab -k -c 15 -n 50000 http://10.20.156.49:2100/member/signin.htm -k 指定保持keepalive -c 并发数 -n 请求数
tcpdump -s 0 -i lo port 2200 -nn 说明:port 2200为后端应用服务端口,-i 必须指定为loopback网络接口,因为apache和后端应用之间走的是loopback网络接口
ProxyPassMatch creates a worker like ProxyPass does,but it uses regex URI for a worker name. For example, your httpd.conf: ProxyPassMatch ^/test/(\d+)/foo.jpg http://backend.example.com/$1/foo.jpg then worker name is "http://backend.example.com/$1/foo.jpg", so URL never matches and the worker is no longer used.打开了apache的LogLevel为debug,看到了的确建立了以$1/$2为url的worker池
[Tue Nov 09 22:12:06 2010] [debug] proxy_util.c(1818): proxy: grabbed scoreboard slot 0 in child 7897 for worker http://localhost:2200/$1/$2 [Tue Nov 09 22:12:06 2010] [debug] proxy_util.c(1837): proxy: worker http://localhost:2200/$1/$2 already initialized
ProxyPassMatch ^/(home|admin|product|monitor)/(.*)$ http://localhost:7001