在工作中,我在组里负责一个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变化的更多相关文章

  1. SQL Server 性能优化详解

    故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...

  2. proxy server 代理服务器

    有时候,我觉得自己需要去搞明白.搞清楚一个概念,帮我打通一下自己的知识体系,或者说,尝试联络起来. 1. 简介 突破自身IP限制,访问国外站点. 访问单位或者团体内部资源. 突破中国电信的IP封锁. ...

  3. Proxy Server代理服务器(轉載)

    宽带IP城域网开通以来,单位连上了宽带网,10M的带宽让我们感受到了宽带的魅力.电信只提供7个IP地址,对任何一个单位来说都太少了,常用的解决办法是使用代理服务器.微软的MS Proxy Server ...

  4. web性能优化系列之网站瓶颈识别

    最近,公司网站的的访问量日益增大,PV马上过百万了.前期网站一到访问高峰,马上会变得很卡甚至打不开,后来做了很多优化后现在访问比较顺畅了.经过此事明白了一个道理,在遇到这类问题要做到两点,第一要相信自 ...

  5. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互

    java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...

  6. SQL Server 性能优化之——系统化方法提高性能

    SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...

  7. 转:Jmeter 用户思考时间(User think time),定时器,和代理服务器(proxy server)

    在负载测试中需要考虑的的一个重要要素是思考时间(think time), 也就是在两次成功的访问请求之间的暂停时间. 有多种情形挥发导致延迟的发生: 用户需要时间阅读文字内容,或者填表,或者查找正确的 ...

  8. SQL SERVER全面优化-------索引有多重要?

    想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...

  9. 不修改代码就能优化ASP.NET网站性能的一些方法

    阅读目录 开始 配置OutputCache 启用内容过期 解决资源文件升级问题 启用压缩 删除无用的HttpModule 其它优化选项 本文将介绍一些方法用于优化ASP.NET网站性能,这些方法都是不 ...

随机推荐

  1. javascript拖拽事件

    <!DOCTYPE html> <html> <head> <title></title> <style type="tex ...

  2. CF1101B Accordion 模拟

    前后扫一遍: #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib ...

  3. BestCoder Round #80 待填坑

    Lucky Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  4. 基础线程机制--Executor线程池框架

    基础线程机制 Executor线程池框架 1.引入Executor的原因 (1)new Thread()的缺点 ​  每次new Thread()耗费性能 ​  调用new Thread()创建的线程 ...

  5. 牛客Professional Manager(并查集)

    t’s universally acknowledged that there’re innumerable trees in the campus of HUST.  Thus a professi ...

  6. linux中firewall与iptables防火墙服务

    火墙firewall-cmd --state 查看火墙的状态firewall-cmd --get-active-zones 目前所处的域firewall-cmd --get-default-zone ...

  7. my09_mysql指定时间点恢复之binlog start-position

    场景描述 ********************************************* 在远程服务器做的全备并已经恢复,同时使用binlog server备份binlog 之后,删除了库 ...

  8. MapReduce 详解

    MapReduce的整个运行分为两个阶段: Map和Reduce Map阶段由一定数量的Map Task组成 输入格式的数据格式化:InputFormat 数日数据的处理:Mapper 数据分组:Pa ...

  9. error creating bean with name 'defaultvalidator' defined in class path resource

    场景: 1.直接用eclipse 运行没问题(本地用的tomcat是7.0.70): 2.打包发布到服务器运行也没问题(服务器tomcat是8.5.30): 3.将打包发布的放到本地tomcat(7. ...

  10. 【C】一个读取文件记录器

    分享一下!!! #include<stdio.h> #include<windows.h> #define N 70000 //定义行数!!用空间换取时间 struct stu ...