现在基本上都是采用前后端分离的方式开发,跨域问题是我们最常遇到的问题之一。
什么是跨域?
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
当一个请求url的协议、域名(主域名、子域名)、端口三个之中任一个与页面的url不同,即可认为是跨域。
解决跨域的方法有很多,这里就不一一的举例了,其中有两种常见的解决跨域的方式,nginx
代理和 http-proxy
,这两种方式的原理都差不多,都是将不同端口的内容转发到同一个端口下。这篇文章的主题就是这两种方式谁的效率更高。
如何使用
nginx 基本使用
- 下载 http://nginx.org
- 解压
- 关键配置【/conf/nginx.conf】
将本地的前端项目放在3013端口下,并将本地的3006端口也放到3013端口下。
server {listen 3013; server_name localhost; location / {root /project/web;index index.html index.htm index.php;try_files $uri $uri/ /index.html; }location /api {proxy_pass http://127.0.0.1:3006;}}
- 启动
nginx start
http-proxy
1. 安装
npm install http-proxy --save
2. 配置
http-proxy.js
const http = require('http');const httpProxy = require('http-proxy');//创建一个代理服务const proxy = httpProxy.createProxyServer();//创建http服务器并监听4000端口let server = http.createServer(function (req, res) {//将用户的请求转发到本地3000端口上 proxy.web(req, res, {target: 'http://localhost:3000' });//监听代理服务错误 proxy.on('error', function (err) {console.log(err); });});server.listen(4000, '0.0.0.0');
3. 启动
node ./http-proxy.js
性能测试
测试工具
ab,即Apache Benchmark,是一种用于测试Apache超文本传输协议(HTTP)服务器的工具。
ab命令会创建很多的并发访问线程,模拟多个访问者同时对某一URL地址进行访问。它的测试目标是基于URL的,因此,既可以用来测试Apache的负载压力,也可以测试nginx、lighthttp、tomcat、IIS等其它Web服务器的压力。
ab命令对发出负载的计算机要求很低,既不会占用很高CPU,也不会占用很多内存,但却会给目标服务器造成巨大的负载,其原理类似CC攻击。自己测试使用也须注意,否则一次上太多的负载,可能造成目标服务器因资源耗完,严重时甚至导致死机。
安装
yum -y install httpd-tools
测试方法
ab [options] [http[s]://]hostname[:port]/path
options:
-n requests #执行的请求数,即一共发起多少请求。-c concurrency #请求并发数。-t timelimit #测试所进行的最大秒数。其内部隐含值是-n 50000,它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。-s timeout #指定每个请求的超时时间,默认是30秒。-b windowsize #指定tcp窗口的大小,单位是字节。-B address #指定在发起连接时绑定的ip地址是什么。-p postfile #指定要POST的文件,同时要设置-T参数。-u putfile #指定要PUT的文件,同时要设置-T参数。-T content-type #指定使用POST或PUT上传文本时的文本类型,默认是'text/plain'。-v verbosity #设置详细模式等级。-w #将结果输出到html的表中。-i #使用HEAD方式代替GET发起请求。-y attributes #以表格方式输出时,设置html表格tr属性。-z attributes #以表格方式输出时,设置html表格th或td属性。-C attribute #添加cookie,比如'Apache=1234'。(可重复)-H attribute #为请求追加一个额外的头部,比如'Accept-Encoding: gzip'。(可重复)-A attribute #对服务器提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即,是否发送了401认证需求代码),此字符串都会被发送。-P attribute #对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。-X proxy:port #指定代理服务器的IP和端口。-V #打印版本信息。-k #启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能。-d #不显示"percentage served within XX [ms] table"的消息(为以前的版本提供支持)。-q #如果处理的请求数大于150,ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此-q标记可以抑制这些信息。-g filename #把所有测试结果写入一个'gnuplot'或者TSV(以Tab分隔的)文件。此文件可以方便地导入到Gnuplot,IDL,Mathematica,Igor甚至Excel中。其中的第一行为标题。-e filename #产生一个以逗号分隔的(CSV)文件,其中包含了处理每个相应百分比的请求所需要(从1%到100%)的相应百分比的(以微妙为单位)时间。由于这种格式已经“二进制化”,所以比'gnuplot'格式更有用。-r #当收到错误时不要退出。-h #输出帮助信息-Z ciphersuite 指定SSL/TLS密码套件-f protocol 指定SSL/TLS协议(SSL3, TLS1, TLS1.1, TLS1.2 or ALL)
ab -n 50 -c 10 http://www.dengzhanyong.com:3013/proxyTest
上述语句表示总共向http://www.dengzhanyong.com:3013/proxyTest发送50次请求,并发量为10
测试
为了更好的对比两种方式的性能,分别使用两种方式代理一个相同的请求。后端接口的端口为3006,使用 nginx
代理到3013端口,使用 http-proxy
代理到3012端口。
http-proxy
[root@cdfcf ~]# ab -n 10000 -c 100 http://www.dengzhanyong.com:3012/This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.dengzhanyong.com (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software: Server Hostname: www.dengzhanyong.comServer Port: 3012Document Path: /Document Length: 12 bytesConcurrency Level: 100Time taken for tests: 34.206 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 5556618 bytesHTML transferred: 120000 bytesRequests per second: 292.35 [#/sec] (mean)Time per request: 342.055 [ms] (mean)Time per request: 3.421 [ms] (mean, across all concurrent requests)Transfer rate: 158.64 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median maxConnect: 1 9 27.3 8 1010Processing: 23 332 81.3 310 864Waiting: 22 253 85.3 250 826Total: 25 341 87.0 317 1399Percentage of the requests served within a certain time (ms)50% 31766% 33475% 36380% 38190% 43995% 47898% 56999% 730100% 1399 (longest request)
nginx
[root@cdfcf ~]# ab -n 10000 -c 100 http://www.dengzhanyong.com:3013/This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.dengzhanyong.com (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software: nginx/1.13.7Server Hostname: www.dengzhanyong.comServer Port: 3013Document Path: /Document Length: 12 bytesConcurrency Level: 100Time taken for tests: 24.610 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 5776562 bytesHTML transferred: 120000 bytesRequests per second: 406.35 [#/sec] (mean)Time per request: 246.096 [ms] (mean)Time per request: 2.461 [ms] (mean, across all concurrent requests)Transfer rate: 229.23 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median maxConnect: 1 5 2.5 5 20Processing: 8 240 57.6 231 821Waiting: 6 240 57.5 230 820Total: 9 245 57.9 236 827Percentage of the requests served within a certain time (ms)50% 23666% 24575% 25480% 26090% 28795% 33098% 39699% 593100% 827 (longest request)
在测试结果中可以通过一些关键数据进行比较:
- 测试所需时间
- 每秒请求数
- 每次请求的时间
- 每次请求的时间(所有并发请求)
- 转移率
通过上面的结果可以看出,nginx
的表现更好,请求10000次,并发量100,nginx
的总用时 24.610 秒,而 http-proxy
需要 34.206 秒。
为了避免结果的果然性,通过改变请求内容大小,请求数量,并发量的数据进行多次测试,测试结果如下:
通过测试结果可以看出,随着请求内容的变大,他们之间的差距越来越小,这个原因应该是受服务器限制了,我的服务器配置很低,只有1核2g,因此对于大内容请求时基本上无差距。
但从整体来看,每轮测试 nginx
都比 http-proxy
的效率更高。如果服务器性能条件好的话,可以通过配置 nginx
进一步提升效率,到这里我们可以得出结论:nginx
比 http-proxy
更高效。不过在 http-proxy
中可以对一些不同的业务场景,通过代码的方式做一些需求处理,这一点是 nginx
无法做到的。