• 【工作】Proxy Server的优化


      在工作中,我在组里负责一个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,

     1 /___/outlook.office365.com/, 302
     2 /owa/, 302
     3 /__/login/login.srf, 200
     4 /owa/prefetch.aspx, 200
     5 /___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/preboot.js, 200
     6 /___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/boot.worldwide.0.mouse.js, 200
     7 /___/outlook.office365.com/GetUserRealm.srf, 200
     8 /___/r1.res.office365.com/owa/prem/16.801.12.1741001/scripts/boot.worldwide.1.mouse.js, 200
     9 /owa/ev.owa2, 200
    10 /owa/ev.owa2, 200
    11 /___/outlook.office365.com/, 302
    12 /owa/ev.owa2, 200
    13 /owa/, 302
    14 /__/login/login.srf, 200
    15 /owa/ev.owa2, 200
    16 /owa/service.svc, 200
    17 /owa/prefetch.aspx, 200
    18 /___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/preboot.js, 200
    19 /owa/service.svc, 200
    20 /___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/boot.worldwide.0.mouse.js, 200
    21 /owa/ev.owa2, 200
    22 /owa/ev.owa2, 200
    23 /owa/service.svc, 200
    24 /owa/service.svc, 200
    25 /___/outlook.office365.com/GetUserRealm.srf, 200
    26 /___/r1.res.office365.com/owa/prem/16.807.12.1742334/scripts/boot.worldwide.1.mouse.js, 200
    27 /__/login/ppsecure/post.srf, 200
    28 /owa/, 302

      每一行数据,前面是URL,后面是该请求收到的Response Status Code。

      

      同时我自己写了一个脚本来解析Log里的数据,因为数据是重复的,需要去重以及排序。

      脚本如下:

      1 var lineReader = require('line-reader');
      2 var fs         = require('fs');
      3 
      4 var fileReadData  = "URLs.log";
      5 var fileWriteData = "result.txt";
      6 
      7 var ignoreNormalStatusCode = false;
      8 if (process.argv && process.argv[2]) {
      9     ignoreNormalStatusCode = process.argv[2];                  // development to be passed as param
     10 }
     11 
     12 console.log("ignoreNormalStatusCode: " + ignoreNormalStatusCode);
     13 
     14 // create data object
     15 var createDataObjectFromLine = function (str) {
     16     var data = str.split(",");
     17 
     18     var obj = {
     19         url: data[0].trim(),
     20         statusCode: data[1].trim(),
     21         number: 1
     22     };
     23 
     24     return obj;
     25 };
     26 
     27 // get the index in the array
     28 var indexOfObjInArray = function (array, obj) {
     29     var pos = -1;
     30     
     31     for (var i=0; i<array.length; i++) {
     32         var e = array[i];
     33 
     34         if (e.url === obj.url && e.statusCode === obj.statusCode) {
     35             pos = i;
     36             break;
     37         }
     38     }
     39 
     40     return pos;
     41 };
     42 
     43 // compare number to sort
     44 var compare_number = function (a, b) {
     45     return b.number - a.number;
     46 };
     47 
     48 // write the array's data to file
     49 var writeResultToFile = function (result, number) {
     50     var string = "";
     51     string += "Here is this URL scan result blow, 
    ";
     52     string += "Orignial URL number: " + number + "
    ";
     53     string += "Unrepeat URL number: " + result.length + "
    ";
     54     string += "------------------------------------------
    
    ";
     55     string += "req url, this url's response status code (200 is ok), number statics
    ";
     56     fs.appendFileSync(fileWriteData, string);
     57 
     58     for (var i=0; i<result.length; i++) {
     59         fs.appendFileSync(fileWriteData, result[i].url + ", " + result[i].statusCode + ", " + result[i].number + "
    ");
     60     }
     61 };
     62 
     63 // create an array to save the urls
     64 var result = [];
     65 
     66 // count the orignial url number
     67 var number = 0;
     68 
     69 // main function
     70 lineReader.eachLine(fileReadData, function (line, last) {
     71     number++;
     72 
     73     // parse the data from every line
     74     var obj = createDataObjectFromLine(line);
     75     //console.log(obj);
     76     
     77     var pos = indexOfObjInArray(result, obj);
     78     if (pos != -1) {
     79         // this object already exists in result array
     80         result[pos].number++;
     81     }
     82     else {
     83         if (ignoreNormalStatusCode && obj.statusCode === '200') {
     84             // ...
     85         }
     86         else {
     87             // add this obj to result
     88             result.push(obj);
     89         }
     90     }
     91     
     92     if (last) {
     93         // sort the array by number
     94         result.sort(compare_number);
     95 
     96         // write the result to file
     97         writeResultToFile(result, number);
     98 
     99         // stop reading lines from the file
    100         return false;
    101     }
    102 });

      这里使用了一个Node.js Module Line-reader,来从文件中一行行的读取数据。

      这样运行之后就可以得到解析后的结果,

     1 Here is this URL scan result blow, 
     2 Orignial URL number: 142
     3 Unrepeat URL number: 6
     4 ------------------------------------------
     5 
     6 req url, this url's response status code (200 is ok), number statics
     7 /owa/, 302, 10
     8 /___/outlook.office365.com/, 302, 5
     9 /owa/auth/15.1.225/themes/resources/segoeui-regular.ttf, 404, 3
    10 /owa/auth/15.1.225/themes/resources/segoeui-semilight.ttf, 404, 1
    11 /___/outlook.office365.com/favicon.ico, 302, 1
    12 /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

  • 相关阅读:
    大作文-学以”成人”
    方案类--博物院整改意见
    归纳概括-我国中小学开展研学旅行活动的特点
    短文-网络新一代
    短评
    讲话稿-文明素养教育主题宣传
    检验用户单点登录方案解决
    Spring @Transactional注解
    RPC-局限于java的RMI
    Redis缓存雪崩、击穿、穿透的问题和解决方式
  • 原文地址:https://www.cnblogs.com/KevinSong/p/4668568.html
Copyright © 2020-2023  润新知