HTTPx相关
第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]

Webbench MAC下安装

[不指定 2017/06/10 16:57 | by 刘新修 ]

Webbench是有名的网站压力测试工具,它是由 Lionbridge公司开发。

Webbech能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况。webBech的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每秒钟传输数据量。webbench不但能具有便准静态页面的测试能力,还能对动态页面(ASP,PHP,Java,CGI)进 行测试的能力。还有就是他支持对含有SSL的安全网站例如电子商务网站进行静态或动态的性能测试。

安装: Make install 需 sudo 权限, 需要写入 /usr/local/bin

C#代码
  1. brew install ctags # 依赖安装  
  2. curl -o webbench.tar.gz http://blog.zyan.cc/soft/linux/webbench/webbench-1.5.tar.gz  
  3. tar -zxvf webbench-1.5.tar.gz  
  4. cd webbench-1.5/  
  5. mkdir -pv /usr/local/man/man1 # 关键  
  6. sudo make && sudo make install # sudo 权限因为需要创建文件夹  

Mac下自带apache压力测试:

C#代码
  1. localhost:webbench-1.5 jesse$ webbench -c 500 -t 120 http://localhost/  
  2. Webbench - Simple Web Benchmark 1.5  
  3. Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.  
  4.   
  5. Benchmarking: GET http://localhost/  
  6. 500 clients, running 120 sec.  
  7.   
  8. Speed=33001 pages/min, 696314 bytes/sec.  
  9. Requests: 64078 susceed, 1924 failed.  
  10. localhost:webbench-1.5 jesse$   

 

在讨论这个问题之前先了解一下浏览器的缓存机制。浏览器的缓存机制有两种,一种是“Freshness(新鲜度,过期机制)”,另一种是“Validation(校验值,验证机制)”。

 
“Freshness(新鲜度,过期机制)”:缓存副本有效期。若一个缓存副本是有效的、足够新的,则在这段有效期,浏览器直接从缓存中返回数据,无需再次发出实际请求。于是就有了“http 200 from cache”。
 
“Validation(校验值,验证机制)”:http设定了一套校验规则,用来校验当前客户端所缓存的资源是否仍然是新鲜的。当缓存失效时(Freshness优先级高于Validation),浏览器会在请求头中包含前置条件头,再次向服务器发送请求。当校验失效时,说明资源已经被修改或过期,浏览器需求重新获取资源内容。当校验未失效时,会返回“304 not modified”。
 
与缓存有关的http消息报头
 
1.Freshness(新鲜度,过期机制)有关的http消息报头有Cache-Control、Expires、Pragma等。
 
Cache-Control与Expires作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
 
2.Validation(校验值,验证机制)有关的http消息报头有ETag、Last-Modified、If-Modified-Since、If-None-Match、If-Range、Cache-Control等。
 
Last-modified 和 If-Modefied-Since 一起工作。Last-modfied(在request头内) 指的是本地文件的修改时间。 If-Modefied-Since(在response头内)指的是服务器文件的修改时间。当Last-modefied与If-modefied-since一致时,说明文件没有被修改过,返回304,浏览器直接读取缓存中的文件。若不一致,则说明文件被修改过,返回200,浏览器重新从服务器换取文件。
 
If-None-Match 和 ETag 一起工作。 如果If-None-Match 和 ETag 一致,说明文件没有修改,返回304,使用缓存。否则重新从服务器获取文件。
 
既然已经有了 Last-Modified 已经能够知道本地缓存是否是最新的了,为什么还需要 Etag 呢?
 
主要是基于以下几个原因:
 
Last-Modified 标注的最后修改时间只能精确到秒,如果有些资源在一秒之内被多次修改的话,他就不能准确标注文件的新鲜度了
如果某些资源会被定期生成,当内容没有变化,但 Last-Modified 却改变了,导致文件没使用缓存
有可能存在服务器没有准确获取资源修改时间,或者与代理服务器时间不一致的情形。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304
=============================================================
1,Last-Modified
设置 header("Last-Modified: ".gmdate("D, d M Y H:i:s", time() )." GMT"); 
Last-Modified虽然使用了缓存,但是每次打开页面依然需要向服务器发起http请求,浏览器根据用户的$_SERVER['HTTP_IF_MODIFIED_SINCE']来判断浏览器的内容是否过期,没过期的话返回304状态,浏览器内容从缓存中读取
 
2,Expires
设置 header("Expires: ".gmdate("D, d M Y H:i:s", time()+$cache_time )." GMT"); 
状态码依然是200,时间依然是旧的时间,Size栏目显示为from cache,表示内容是直接从浏览器读取,浏览器根本就没有向服务器发起http请求
 
Expires比Last-Modified缓存效果更好是吧,因为本地有缓存数据时,不需要向服务器发起http请求,服务器的并发数会明显的减少,可以少处理很多http请求

 

 CORS是一个W3C标准,全称是"跨域资源共享" (Cross-origin resource sharing)

CORS,是一种服务器端的跨域解决方案,这种方案对于跨域的解决代码均在服务器端设置完成。在服务器端接收到客户端的请求后,通过获取到请求的来源站点Origin,如果愿意将资源共享给该站点,则通过设置“Access-Control-Allow-Origin”报头的值为请求的来源站点。浏览器接收到包含资源的响应后,会提取“Access-Control-Allow-Origin”响应报头的值,如果此值为*或者包含的源列表包含请求的源站点,则浏览器会允许JavaScript操作获取的资源;否则,不会操作获取的资源。
 
跨域资源共享(CORS )是一种网络浏览器的技术规范,CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。
 
简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。

以往的解决方案

        以前要实现跨域访问,可以通过JSONP、Flash或者服务器中转的方式来实现,但是现在我们有了CORS。

        CORS与JSONP相比,无疑更为先进、方便和可靠。

        1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

        2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

        3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS(这部分会在后文浏览器支持部分介绍)。

详细内容

        要使用CORS,我们需要了解前端和服务器端的使用方法。

        1、  前端

        以前我们使用Ajax,代码类似于如下的方式:

  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "/hfahe", true);  
  3. xhr.send();  

        这里的“/hfahe”是本域的相对路径。

        如果我们要使用CORS,相关Ajax代码可能如下所示:

  1. var xhr = new XMLHttpRequest();  
  2. xhr.open("GET", "http://www.liuxinxiu.com/hfahe", true);  
  3. xhr.send();  

        请注意,代码与之前的区别就在于相对路径换成了其他域的绝对路径,也就是你要跨域访问的接口地址。

        我们还必须提供浏览器回退功能检测和支持,避免浏览器不支持的情况。

  1. function createCORSRequest(method, url) {  
  2.   var xhr = new XMLHttpRequest();  
  3.   if ("withCredentials" in xhr) {  
  4.     // 此时即支持CORS的情况  
  5.     // 检查XMLHttpRequest对象是否有“withCredentials”属性  
  6.     // “withCredentials”仅存在于XMLHTTPRequest2对象里  
  7.     xhr.open(method, url, true);  
  8.    
  9.   } else if (typeof!= "undefined") {  
  10.    
  11.     // 否则检查是否支持XDomainRequest,IE8和IE9支持  
  12.     // XDomainRequest仅存在于IE中,是IE用于支持CORS请求的方式  
  13.     xhr = new XDomainRequest();  
  14.     xhr.open(method, url);  
  15.    
  16.   } else {  
  17.    
  18.     // 否则,浏览器不支持CORS  
  19.     xhr = null;  
  20.    
  21.   }  
  22.   return xhr;  
  23. }  
  24.    
  25. var xhr = createCORSRequest('GET', url);  
  26. if (!xhr) {  
  27.   throw new Error('CORS not supported');  
  28. }  

        现在如果直接使用上面的脚本进行请求,会看到浏览器里控制台的报错如下:

        错误显示的很明显,这是因为我们还未设置Access-Control-Allow-Origin头。

        2、  服务器

        服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

        HTTP 头的设置方法有很多,http://enable-cors.org/这篇文章里对各种服务器和语言的设置都有详细的介绍,下面我们主要介绍Apache和PHP里的设置方法。

        Apache:Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可:

  1. Header set Access-Control-Allow-Origin *  

        PHP:只需要使用如下的代码设置即可。

  1. <?php  
  2.  header("Access-Control-Allow-Origin:*");  

        以上的配置的含义是允许任何域发起的请求都可以获取当前服务器的数据。当然,这样有很大的危险性,恶意站点可能通过XSS攻击我们的服务器。所以我们应该尽量有针对性的对限制安全的来源,例如下面的设置使得只有http://www.liuxinxiu.com 这个域才能跨域访问服务器的API。

  1. Access-Control-Allow-Origin: http://www.liuxinxiu.com  

浏览器支持情况

Tags:

  首先来了解什么是multipart/form-data请求:

根据http/1.1 rfc 2616的协议规定,我们的请求方式只有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE等,那为为何我们还会有multipart/form-data请求之说呢?这就要从头来说了。

http协议大家都知道是规定了以ASCII码传输,建立在tcp、ip协议之上的应用层规范,规范内容把http请求分为3个部门:状态行,请求头,请求体。所有的方法、实现都是围绕如何运用和组织这三部分来完成的。换句话来说就是万变不离其中,只要我们了解了http请求的组成部分后,自然就可以应变任何实际工作中的需求和问题了。

关于状态行,请求头,请求体等三部分的具体内容,大家可以参考官方的协议文档http://www.faqs.org/rfcs/rfc2616.html,这里主要分析multipart/form-data请求具体是怎么一回事。

既然http协议本身的原始方法不支持multipart/form-data请求,那这个请求自然就是由这些原始的方法演变而来的,具体如何演变且看下文:

1、multipart/form-data的基础方法是post,也就是说是由post方法来组合实现的

2、multipart/form-data与post方法的不同之处:请求头,请求体。

3、multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。具体的头信息如下:

JavaScript代码
  1. Content-Type: multipart/form-data; boundary=${bound}  

//其中${bound} 是一个占位符,代表我们规定的分割符,可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容。如:--------------------56423498738365
4、multipart/form-data的请求体也是一个字符串,不过和post的请求体不同的是它的构造方式,post是简单的name=value值连接,而multipart/form-data则是添加了分隔符等内容的构造体。具体格式如下:

JavaScript代码
  1. --${bound}    
  2. Content-Disposition: form-data; name="Filename"    
  3.     
  4. HTTP.pdf    
  5. --${bound}    
  6. Content-Disposition: form-data; name="file000"; filename="HTTP协议详解.pdf"    
  7. Content-Type: application/octet-stream    
  8.     
  9. %PDF-1.5    
  10. file content    
  11. %%EOF    
  12.     
  13. --${bound}    
  14. Content-Disposition: form-data; name="Upload"    
  15.     
  16. Submit Query    
  17. --${bound}--    

其中${bound}为之前头信息中的分割符,如果头信息中规定为123,那么这里也要为123,;可以很容易看出,这个请求体是多个相同的部分组成的:每一个部分都是以--加分隔符开始的,然后是该部分内容的描述信息,然后一个回车,然后是描述信息的具体内容;如果传送的内容是一个文件的话,那么还会包含文件名信息,以及文件内容的类型。上面的第二个小部分其实是一个文件体的结构,最后会以--分割符--结尾,表示请求体结束。

综上,可以知道要发送一个multipart/form-data的请求,其实任何支持post请求的工具或语言都可以支持,只是自己要稍微包装一下便可。

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