【工作】Proxy Server的优化 - 检测目标网站URL变化
在工作中,我在组里负责一个Proxy(代理)的Module,这个Module是针对微软的Office 365的邮件门户OWA实现,工作起来后,用户访问Office 365 OWA,无需再输入Office 365的网址,只需输入我们Proxy的地址,然后我们会将请求转送到Office 365 OWA,达到用户访问的目的,并使用户的体验如同实际访问Office 365 OWA一样。
其实我们Proxy的原理是,使用Node.js构建一个http Server,拿到client端(实际是Browser)的请求后,再将请求转给Office 365,将Office 365的返回内容Response再送给Client端,这样实现Proxy的功能。
当然实际实现过程中还有很多细节的事情,包括cookie的处理,URL的转换等,这里不细讲。
但在工作中开发并维护此Module时,我发现一个问题,那就是虽然我们是将请求转发,但还是有很多请求我们需要特殊处理,而且有很多复杂的请求需要研究去支持,因此做为Proxy我必须知道Office 365,即目标网站都有哪些请求的类型,其实就是哪些不同的URL,不同的URL其实Path不同。
因此我做了一个优化,因为Proxy本质是一个Http Server,因此我将客户端发来的所有请求URL打印在Log中,这样我可以在Log中收集到所有的URL,同时将该URL发送出去后收到的结果(Response Status Code)也打印在一起,这样就能知道这个URL是否处理有问题,如果返回值200,则说明OK。
于是打印在Log中后,得到如下的Log,
/___/outlook.office365.com/, 302
/owa/, 302
/__/login/login.srf, 200
/owa/prefetch.aspx, 200
/___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/preboot.js, 200
/___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/boot.worldwide.0.mouse.js, 200
/___/outlook.office365.com/GetUserRealm.srf, 200
/___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/boot.worldwide.1.mouse.js, 200
/owa/ev.owa2, 200
/owa/ev.owa2, 200
/___/outlook.office365.com/, 302
/owa/ev.owa2, 200
/owa/, 302
/__/login/login.srf, 200
/owa/ev.owa2, 200
/owa/service.svc, 200
/owa/prefetch.aspx, 200
/___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/preboot.js, 200
/owa/service.svc, 200
/___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/boot.worldwide.0.mouse.js, 200
/owa/ev.owa2, 200
/owa/ev.owa2, 200
/owa/service.svc, 200
/owa/service.svc, 200
/___/outlook.office365.com/GetUserRealm.srf, 200
/___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/boot.worldwide.1.mouse.js, 200
/__/login/ppsecure/post.srf, 200
/owa/, 302
每一行数据,前面是URL,后面是该请求收到的Response Status Code。
同时我自己写了一个脚本来解析Log里的数据,因为数据是重复的,需要去重以及排序。
脚本如下:
var lineReader = require('line-reader');
var fs = require('fs'); var fileReadData = "URLs.log";
var fileWriteData = "result.txt"; var ignoreNormalStatusCode = false;
if (process.argv && process.argv[2]) {
ignoreNormalStatusCode = process.argv[2]; // development to be passed as param
} console.log("ignoreNormalStatusCode: " + ignoreNormalStatusCode); // create data object
var createDataObjectFromLine = function (str) {
var data = str.split(","); var obj = {
url: data[0].trim(),
statusCode: data[1].trim(),
number: 1
}; return obj;
}; // get the index in the array
var indexOfObjInArray = function (array, obj) {
var pos = -1; for (var i=0; i<array.length; i++) {
var e = array[i]; if (e.url === obj.url && e.statusCode === obj.statusCode) {
pos = i;
break;
}
} return pos;
}; // compare number to sort
var compare_number = function (a, b) {
return b.number - a.number;
}; // write the array's data to file
var writeResultToFile = function (result, number) {
var string = "";
string += "Here is this URL scan result blow, \n";
string += "Orignial URL number: " + number + "\n";
string += "Unrepeat URL number: " + result.length + "\n";
string += "------------------------------------------\n\n";
string += "req url, this url's response status code (200 is ok), number statics\n";
fs.appendFileSync(fileWriteData, string); for (var i=0; i<result.length; i++) {
fs.appendFileSync(fileWriteData, result[i].url + ", " + result[i].statusCode + ", " + result[i].number + "\n");
}
}; // create an array to save the urls
var result = []; // count the orignial url number
var number = 0; // main function
lineReader.eachLine(fileReadData, function (line, last) {
number++; // parse the data from every line
var obj = createDataObjectFromLine(line);
//console.log(obj); var pos = indexOfObjInArray(result, obj);
if (pos != -1) {
// this object already exists in result array
result[pos].number++;
}
else {
if (ignoreNormalStatusCode && obj.statusCode === '200') {
// ...
}
else {
// add this obj to result
result.push(obj);
}
} if (last) {
// sort the array by number
result.sort(compare_number); // write the result to file
writeResultToFile(result, number); // stop reading lines from the file
return false;
}
});
这里使用了一个Node.js Module Line-reader,来从文件中一行行的读取数据。
这样运行之后就可以得到解析后的结果,
Here is this URL scan result blow,
Orignial URL number: 142
Unrepeat URL number: 6
------------------------------------------ req url, this url's response status code (200 is ok), number statics
/owa/, 302, 10
/___/outlook.office365.com/, 302, 5
/owa/auth/15.1.225/themes/resources/segoeui-regular.ttf, 404, 3
/owa/auth/15.1.225/themes/resources/segoeui-semilight.ttf, 404, 1
/___/outlook.office365.com/favicon.ico, 302, 1
/owa/auth/15.1.219/themes/resources/segoeui-semilight.ttf, 404, 1
当然以上结果是没有显示Status Code为200的URL,原因是这是Proxy处理正常的URL,暂时没必要统计与分析。
得到结果后,显而易见,有很多404的URL,我们的Proxy并没有正确的处理,需要进一步的分析,在代码中支持。由此完成此次对产品Module的优化。
个人小感慨,工作中很多小事情,如果自己认为正确,就应坚持去做。小的优化,只要有意义,都会有大用处:-)
Kevin Song
2015-7-22
【工作】Proxy Server的优化 - 检测目标网站URL变化的更多相关文章
- SQL Server 性能优化详解
故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...
- proxy server 代理服务器
有时候,我觉得自己需要去搞明白.搞清楚一个概念,帮我打通一下自己的知识体系,或者说,尝试联络起来. 1. 简介 突破自身IP限制,访问国外站点. 访问单位或者团体内部资源. 突破中国电信的IP封锁. ...
- Proxy Server代理服务器(轉載)
宽带IP城域网开通以来,单位连上了宽带网,10M的带宽让我们感受到了宽带的魅力.电信只提供7个IP地址,对任何一个单位来说都太少了,常用的解决办法是使用代理服务器.微软的MS Proxy Server ...
- web性能优化系列之网站瓶颈识别
最近,公司网站的的访问量日益增大,PV马上过百万了.前期网站一到访问高峰,马上会变得很卡甚至打不开,后来做了很多优化后现在访问比较顺畅了.经过此事明白了一个道理,在遇到这类问题要做到两点,第一要相信自 ...
- java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...
- SQL Server 性能优化之——系统化方法提高性能
SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...
- 转:Jmeter 用户思考时间(User think time),定时器,和代理服务器(proxy server)
在负载测试中需要考虑的的一个重要要素是思考时间(think time), 也就是在两次成功的访问请求之间的暂停时间. 有多种情形挥发导致延迟的发生: 用户需要时间阅读文字内容,或者填表,或者查找正确的 ...
- SQL SERVER全面优化-------索引有多重要?
想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...
- 不修改代码就能优化ASP.NET网站性能的一些方法
阅读目录 开始 配置OutputCache 启用内容过期 解决资源文件升级问题 启用压缩 删除无用的HttpModule 其它优化选项 本文将介绍一些方法用于优化ASP.NET网站性能,这些方法都是不 ...
随机推荐
- centos操作---搭建环境 安装python
1.安装python3.6.2 安装依赖 yum -y groupinstall "Development tools" yum -y install zlib-devel bzi ...
- Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path 树上dp
D. The Fair Nut and the Best Path 题意:给出一张图 点有权值 边也要权值 从任意点出发到任意点结束 到每个点的时候都可以获得每个点的权值,而从边走的时候都要消耗改边的 ...
- Vscode 配置 maven debug
# maven.cmd 上方设置此变量 set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address= ...
- ubuntu下用apt-get安装lamp缺少mcrypt , curl
用apt-get安装的LAMP环境,但安装magento报没有mcrypt和curl, 解决方法如下: curl安装: sudo apt-get install curl libcurl3 lib ...
- mybatis CDATA引起的查询失败
<![CDATA[ ]]> 在被CDATA包围的所有字符串不会被mybatis解析, 直接写入sql了 CDATA应该只用在特殊字符前后,不能用在<if> <foreac ...
- oracle 12.1.0.2的mgmt 导致的ORA-01017 bug
两节点12c RAC,在两节点上export ORACLE_SID再sqlplus / as sysdba都正常登录,然而Commvault通过service_name方式(sqlplus sys/p ...
- SpringBoot中通过实现WebMvcConfigurer完成参数校验
在Spring5.0和SpringBoot2.0中废弃了WebMvcConfigurerAdapter类. 现有两种解决方案 1 直接实现WebMvcConfigurer (官方推荐)2 直接继承We ...
- leetcode 925. 长按键入
题目描述: 你的朋友正在使用键盘输入他的名字 name.偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次. 你将会检查键盘输入的字符 typed.如果它对应的可能是你的朋友的 ...
- Mybatis学习笔记5 - 参数处理
1.单个参数:mybatis不会做特殊处理,#{参数名}:取出参数值. 2.多个参数:mybatis会做特殊处理. 多个参数会被封装成 一个map, key:param1...paramN,或者参数的 ...
- Murano Weekly Meeting 2015.09.01
Meeting time: 2015.September.1st 1:00~2:00 Chairperson: Nikolay Starodubtsev, from Mirantis Meeting ...