最近发现有个问题,一个自制的webserver在应答前端请求时,总是要处理1s以上,似乎是由于哪里等待了1秒。研究了下发现:Expect: 100-continue这个东东。

    100-continue这个状态码之前是很少遇到的。这个是http1.1协议为了提高效率设置的。当客户端要POST较大数据给webserver时,可以在发送http头时带上Expect: 100-continue,服务器如果接受这个请求,应答一个HTTP/1.1 100 Continue,那么客户端就继续传输正文,否则应答417,客户端就放弃传送剩余的数据了。这样就避免客户端吭哧吭哧传了一大堆数据上去,结果服务端发现不需要的情况。

    libcurl在不同版本里逻辑不同,有的版本libcurl会在POST数据大于1024字节的时候发送100-continue请求,有的版本则不会。我们用到的libcurl版本会发送,而自制webserver不会应答这个请求,客户端等待1s钟没有收到肯定或否定的应答,还是继续传输了正文,虽然逻辑上并没有问题,但速度上就慢了下来。

    加了下逻辑,对100-continue进行应答,速度马上提高很多。



Tags: ,
    很久之前就有一个问题在困扰,就是明显感觉svn操作完后要顿一顿才结束。一直以为是svn机器性能问题,后来上了ssd也没效果。

   最近抽时间看了下。

   先strace一下看看时间,发现在操作末尾两个gettimeofday之间夹了个select操作。会阻塞几百ms到1s不等,然后超时。

   第一感觉是最后处理完了可能给服务器发回个什么数据之类的,服务器那里哪个规则配的不对,客户端连不上然后超时了。

   看svn源码,看不出来末尾做了啥网络操作,封装了好多层,不确定是不是哪一层注册了什么奇奇怪怪的回调函数,在最后析构时搞一把。

   用gdb单步跑了一下。

   发现svn_io_sleep_for_timestamps函数很可疑。

   查看代码,发现这是个延时函数。svn通过mtime获取文件修改信息,所以每次svn co操作末尾,svn会等待一小段时间再返回,svn客户端判断apr_stat返回的文件mtime是不是1000000整倍数(stat看到的mtime小数点后面是否全是0),如果是0,那么svn认为该文件系统不支持毫秒级粒度的mtime记录,就会等待系统时间秒的跳变,即等待平均0.5s,最长1s。如果不是0,那么只等待1ms。
  
   由于svn使用的apr_sleep为了实现较高精度的sleep延时,使用了select来做延时。这就是strace中select系统调用的由来。


   这里还有一个问题,就是如果文件mtime恰好是整数,那么svn就会判断失误,进而等待较长的时间。作者认为总比每次都等较长的时间好。

   之前用的文件系统是ext2,它只支持秒级精度的mtime,而ext4支持更高精度。

   找了一台机器,划了两个同样大小的分区,一个格式化为ext2,一个格式化为ext4,使用svn co向两个分区中checkout代码,前者耗时0.3到1s不等,后者稳定在100ms。性能提升非常明显。





Tags:
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]