WEBrick在局域网内响应慢的解决方案

前言

WEBrick是Ruby标准库带的一个HTTP服务器程序库。WEBrick用来支撑小型的网络应用还是能胜任的。最近遇到了WEBrick在局域网内响应慢的问题,经过调查并解决了此问题。下面是详细过程。


运行环境

Ruby1.9.2-p0,WinXP(SP3)


现象

公司的同事最近用Rails开发了一个日报系统,由于使用人数不多且并发量并不大,打算直接用WEBRick就可以了。结果发现一个现象:WEBrick响应特别慢,一个请求从开始处理到结束,需要差不多30秒的时间,我无语!@#$%^& 。为了将问题简单化,我写了个相当简单的脚本来测试WEBrick:

require 'webrick'

server = WEBrick:: HTTPServer.new( { :Port => 3000, :DocumentRoot => 'C:/webroot'} )
server.start
运行脚本,然后用局域网的其他机器访问这个服务器,症状和上面是一样的。

分析

在分析过程中有2个现象:

  1. Ruby进程的CPU占用率并不高,说明并不是Ruby在进行大量的运算。
  2. 客户端的请求到达WEBRick服务器是很快的。

经过跟踪和分析源码,发现在“某些局域网环境” 中,套接字的peeraddr方法会相当耗时, 如同阻塞一样,大约15秒左右。WEBRick代码中调用 peeraddr 的有两处,这样看来,30秒的时间基本就花在这两次调用上了。再进一步分析发现:peeraddr 真正慢的地方是在内部获取客户端名称的时候。

WEBRick调用peeraddr方法的两处地方:

第一处:
文件:
server.rb 文件
方法:GenericServer#start_thread
代码:addr = sock.peeraddr

第二处:
文件:
httprequest.rb
方法:HTTPRequest#parse
代码:@peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []


解决方案

知道了原因,修改方法就简单了。其实,peeraddr是可以带参数的,如果传入:numeric ,则peeraddr 方法就不会去获取客户端名称,而是直接用客户端IP字符串来代替客户端名称 。在实际应用中,对服务器来说,客户端名称并不是十分重要,客户端IP才是重要的。具体修改如下:

第一处修改:
文件:
server.rb 文件
方法:GenericServer#start_thread
代码:
addr = sock.peeraddr 改为 addr = sock.peeraddr(:numeric )

第二处修改:
文件:
httprequest.rb
方法:HTTPRequest#parse
代码:
@peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr : []
改为
@peeraddr = socket.respond_to?(:peeraddr) ? socket.peeraddr(:numeric ) : []


结束

修改完之后,WEBrick在局域网内的响应速度立刻就提升上去了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值