首页 > 代码库 > "个性化空间"性能优化方案设计初步

"个性化空间"性能优化方案设计初步

一、问题的提出

     在九月中开始,我们要打造个性化空间,领导要求的是只进行原型的设计,逻辑的设计,不进行技术开发。其实是严重不正确的,因为个性化空间其特点与现有的技术模型完全不同,现有的技术方案未必能适应开发工作,会造成看起来工作正常,但一旦大规模压力测试将性能一塌糊涂.....

    所以,我们当然要听从领导安排,但私下准备好个性化空间的技术方案也是势在必行。

 

二、初步技术方案

     根据以往的性能优化方案,我们一般采用REDIS进行一级缓存,特殊场景应对大并发,采用二级缓存办法。如果按以前的方式,那么方案是这样的:

    1、在REDIS中记录此空间ID,比如ID:5,有几个模块,都是什么模块ID,比如:模块3,模块9,模块10,模块20,等。

    2、每个模块的内容都单独保存到REDIS中。

    3、每个模块单独记录最后的UPDATE时间,比如如果某个模块的内容删除了,更新了等,都需要在缓存中更新一下此模块的最后UPDATE时间为当前时间戳。

    4、当用户初次来访问时,由LUA查询到此个性化空间有哪些模块, 然后根据每个模块的REDIS缓存,组装成一个JSON串,同时在REDIS中记录一个HASH,

      包含如下信息:哪个空间ID(在KEY里体现),都有哪些模块,这些模块都是最后的更新时间是啥?

    5、JSON数据经NGINX的GZIP压缩后返回。

    6、当用户再次访问时,LUA查询此个性化空间有哪些模块,是不是在模块个数(或个数相同,同容变成其它模块了),模块的最后更新时间有区别,如果没有,则不重复组装,直接拿现成的JSON数据返回即可。

    7、当某个模块的数据变化时,要求JAVA修改模块的最后修改时间,这样,LUA再次查询时,将不再读取保存好的JSON数据,而是重新组装返回,并再次缓存JSON数据。

 

三、技术方案进化

     上面的方案应对一般的需求是很好的,在资源库列表的压力测试中取得了很好的成绩,由1000并发上升到3000并发应该不是问题,但应对这个需求就怕是要有问题了:

     个性化空间具有可扩展性,比如,现在只开发了十个模块,用户最多可以启用十个模块,每个模块的数据量在10K左右,那么最多是100K,数据量不大,后期随着项目的进展,很可能空间出现大规模模块增加,我们以短期内可以接受的50个为上限计算,那么就在500K左右。大家知道,NGINX我们是启用了GZIP压缩的,本来GZIP压缩的效率很高,对于简单的JSON数据我们可以放心的使用GZIP压缩提高传输效率,但对于一个500K的流量,每请求一次就要实时压缩一下,效率可想而知。而此请求是一个动态请求,还不能使用效率更好的STATIC_GZIP方式,那么如果在这样的场景下,CPU的疲劳是可想而知的。因为小的JSON它压缩起来不费力,但大的呢?它也是十分吃力的,这一点我们以前在看JQUERY.MIN.JS每次让它压缩就看的出来,JQUERY.MIN.JS才只有120K左右,它就疲于奔命了,所以,这个方案存在先天的问题。

    为此,黄海提出了一个新的设计思路:JSON数据的压缩不由GZIP实时进行,而是一次性在服务器端生成,然后直接发给JAVASCRIPT,由JS去解压解码后再运行。

   (当然,为什么这种数据能不经过NGINX压缩呢?可能需要一些测试,比如:

              gzip_types       text/plain application/x-javascript text/css text/html application/xml; 将这种传输修改为一种不常用的mime,应该可以让NGINX不进行压缩,直接传输)。

  

     核心思路:

               1、由JAVA进行第一次的组装,一旦组装完成,将JSON数据先BASE64后,然后经JAVA进行Deflater压缩,得到的数据保存到REDIS中,LUA发现数据无变化 ,直接读取缓存数据并返回。

     2、JAVASCRIPT得到数据后,先进行字符串解压,然后将BASE64字符串还原为普通字符串,进行渲染即可。

 

              3、其它策略与上面的方式基本一致。

 

              4、此优化的方案最核心的是JAVA生成Deflater压缩,BASE64化,然后在JAVASCRIPT中找到办法可以解压,并反BASE64化。

             附: JAVA与JAVASCRIPT通用的字符串压缩,BASE64加解方法                  


JS通用加密解密方法.rar

JAVA通用加密解密方法.rar

  

四、不尽人意的地方

            第一次请求需要JAVA进行处理,LUA的ZLIB库黄海没有安装起来,是不是能与JAVA,JAVASRIPT的压缩,解压保持一致还不知道,需要进一步测试。

           LUA在检查到没有生成过时,需要转发ACTION给JAVA,那么如何转发,这里存在一个测试的内容。现在黄海只知道可以使用ngx.redirect,那么其它参数如何传递?用cookie可以吧?

          

"个性化空间"性能优化方案设计初步