vlambda博客
学习文章列表

由负载均衡至django缓存,浅谈对架构设计的理解

        

This browser does not support music or audio playback. Please play it in Weixin or another browser.

       项目进入收尾阶段,所以也有更多的时间来做一些关于性能的研究。引用一句同事调侃的话,大佬目前都在大气层,而我还在地面游荡,哈哈哈,这篇文章主要记录一下我在遇见未涉及的问题时候是如何一步一步解决掉的,然后谈一下关于架构师以及架构设计的理解,纯手打,如有雷同,不用想了,是TA抄我的。

        

       关于性能这块,最早是在写上一个项目时候思考的。我记得上一个项目,写的代码有很多赘余,从查数据库的频率到循环的次数,以及有很多重复代码,这就导致了数据过大时,页面响应时间非常长。 当然,响应时间还包含硬件配置,网速等客观条件,但在这篇文章里不谈这些,只从代码及部署的层面来考虑。

        上一个项目,也是在收尾阶段自己测试发现的:我在表里加了几万条数据,然后尝试用orm查询和navicate查询,结果前者加上前端渲染时间一共花了一分多钟,后者只用了5秒,差了十多倍,这是我第一个关于性能的直观发现,然后当时很想解决这个问题,却因为太忙而耽搁了,但是一直记得。

        出现这个问题之后,因为对于整个查询底层实现原理不精通,所以很难从宏观、全局的角度来思考这个问题,这就导致了我解决的问题只是某一小块的问题,思路本身就偏离了,而且这个问题要是仔细研究,肯定要花几个月时间,所以这里先记录一下,后面随着学习的深入再来解决。

        

        上面的描述,就是我对于性能的初体验。现在再来谈谈今天的两个主题:负载均衡和缓存。


        先来说负载均衡。 从字面意思就可以理解了,是为了分担服务器压力,而将请求根据一定的策略分发给不同的服务器去处理。所以这里需要有一个掌管分发任务的服务器,目前我因为自己只有两台服务器,所以把其中一台作为了分发枢纽,这样就会有一个问题:那就是这台分发枢纽挂了之后,另一台即便没挂也白搭,所以我自己测试的负载均衡,应对的场景就是只能另一台服务器挂掉才行。 如果有两台机器做负载均衡,那建议还是用第三台做分发。

        我理解的负载均衡,就是一种网络设计方案,而使用nginx只是其中一种方法里主流的工具罢了(当然,这只是25岁的我理解的,有可能随着年龄的增长,想法又会变了),详细可以查看维基百科关于负载均衡的解释(https://zh.wikipedia.org/wiki/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1)。

        所以问题又来了,既然转发的目的地确定了,那应该怎么转发呢?这里就要用到了均衡的策略,默认情况下是轮询(由于好奇怎么轮询的,我就开了十多个窗口,然后一直刷新,模拟并发,发现请求密集的情况下,真的会分担到其他的服务器上)。具体的均衡策略,可以去官方文档看一下,我使用的就是轮询,应该还可以配置权重,有知道的小伙伴可以在留言区补充一下。

        上面三段讲的是负载枢纽的部署,对于前后台服务的部署也是比较麻烦的,因为两台服务器都要部署,环境要搭建两套,改动了代码,也要乘以2. 不过这个好像有解决办法,目前还没有这个需求,后面遇到了再说。

        (听首歌休息一下)

        

This browser does not support music or audio playback. Please play it in Weixin or another browser.

            好,继续谈第二部分:缓存。这块实际运用起来,并没有花多久,查文档,写代码,测试就好了,但是考虑用缓存这个想法,却花了几天的时间。

       首先,我有这样一个需求:就是有一个存有字典的列表需要维护,然后这个列表每天都会变,因为存有登录的token,token生成规则里有当天的日期。并且用户在新增、删除的时候,也要更新这个列表。所以一开始考虑是查数据库,但是因为每次都查,虽然现在效率还好,也比较稳定,但是为了防止客户压测后不至于太难看,还是把不查数据库的方法确定了一下。

        一开始也是花很多成本在解决的是用django的全局变量存,方法就是在配置文件中先定义,然后再重启时候拉取数据,再在新增和删除时更新这个全局变量。但是出现一个现象就是,用新增或删除的用户请求同一个页面,有的时候会正常,有的时候会出现用户不存在的情况。

        这里有几点需要注意: 

       1.线上服务是用uwsgi启动的,而不用用runserver,所以需要在wsgi.py里application前把django的环境变量加载进来,然后django.setup(),否则会报一个环境变量找不到的错。

        2.全局变量只能取,在setting里配置了,就不能修改了,所以不建议有修改的需求时使用它。


        后面就是用缓存了,关于缓存,我差点和操作系统里的缓存搞混了,这个缓存其实应该叫网络缓存,大部分是放到内存里的;而操作系统的缓存是在cpu里的,目的是为了缓解内存和cpu之间速度不匹配的问题(好像是这样....)

        django使用缓存有很多种方法,文档里有写,而且都比较方便,基本上是配置好了就可以用了。我目前使用的是memcached,当然也打算用redis试一下。步骤都差不多,下载好包后,配置一下就可以了,和database的配置类似。用memcached的一个原因是,支持多服务器同步,根据配置不同ip:port,修改一处,其他的也会同步修改,尤其适合集群部署。


       最后来说一下我对架构设计的理解以及架构师的职责:

       架构设计,其实应该是根据业务需求,设计出包括前端、后端、服务器部署在内的一整套工程,该工程不仅要满足所有的业务需要,而且还需要考虑可扩展性、可移植性、鲁棒性等等,这些特点也不仅限于业务,更要体现在技术层面,谈到这,我觉得不是考虑python好还是go好的问题了,而是什么更适合的问题。语言,技术其实都是工具,解决需求的思路是最重要的。 

        所以我觉得架构师必须懂至少2门语言,包括1门编译语言,1门解释语言,而且还必须要有短时间内掌握一门语言的能力,其实从宏观层面来讲,代码最终都是通过汇编给计算机翻译成机器码然后执行的,所以所有的高级语言理论上都是一样的,只不过各有特色。此外,架构师还必须懂前端设计,就我目前的发现,想搞好web,前端一定很精通,框架会用几个,与后端的交互设计要清楚。最重要的当然是部署,各个服务搭建和设计,比如用到哪些设计模式,然后根据这些设计原则选择是用kafka,用es,用k8s之类的。另外,还需要懂一些测试,我发现一个大项目,绝对不是简单的用postman这种办法来测,当然测试也分性能测试,功能测试等等。我觉得都要懂一些。

This browser does not support music or audio playback. Please play it in Weixin or another browser.