Django 网站开发工具实践

导语:

本文主要围绕django-debug-toolbar介绍提升Django网站后台开发工作效率的实践经验。前半部分主要介绍用toolbar优化网上性能问题的经验总结,后半部分介绍笔者基于toolbar开发的一个小工具,用于定位接口调用相关的问题(saas开发遇到最多的一类问题),最后提出笔者针对开发工具建设的一点思考。

背景:

首次注意到django-debug-toolbar这款工具,是因为笔者长期参与建设并维护的一款运维产品,经过两年多不断的修修补补,部门内运维同事用起来也越来越顺手了。然而产品中暴露出来慢的问题也日益突出,作为早期开发人员之一,有点心塞的感觉,跟组长沟通之后准备花点时间优化一下。刚开始着手优化的时候按照一贯的办法,找出响应慢的url,再在工程中加line-profile或cprofile来查看究竟哪些地方慢,这种方式效率特别低,加代码-测试-查看性能数据-定位问题原因-优化代码-重新测试,整个过程走下来,一个小小的优化就要花上半天时间。

晚上回家后就琢磨着怎么提升速度,就感觉这件事不能这么玩下去,如果有一款工具可以快速直观的定位出问题原因,那么这事就好办多了,团队内其他同事也可以参与进来一起优化。这就是本文要讲的django-debug-toolbar工具,为了简洁,本文后面统一简称为toolbar。

Django-debug-toolbar:

该说下toolbar是个什么东西了,简单说它就是一个django开发调试工具集,集成了许多相互独立的调试工具(panel),这些panel可以在前端直接展示调试信息。

关于panel更详细的说明可以参考官方文档django-debug-toolbar,笔者这里只打算介绍个人觉得最有用的两个panel。

一是SQLPanel,它能记录每个sql请求及耗时情况,并提供explain按钮给我们直接分析慢的原因,另外还可以统计出类似查询的次数(比如for循环中的查询)。另外一个是ProfilingPanel,它可以跟踪http响应的整个函数调用过程及时长,这样可以帮助我们快速定位出最耗时的函数。

DEBUG_TOOLBAR_PANELS = [

    # ...
    'debug_toolbar.panels.settings.SettingsPanel',  # settings配置,比如启动时陪在环境变量中的一些值 /yx
    'debug_toolbar.panels.sql.SQLPanel',  # sql查询时间、重复查询、explain
    'debug_toolbar.panels.profiling.ProfilingPanel',  # 性能分析
]

工作原理:

整个toolbar框架的核心就是中间件,toolbar通过中间件的方式加入到django工程中,toolbar中所有的panel也是类似中间件的形式被toolbar调用。

下面结合django请求处理过程来说明toolbar是如何工作,图Django请求响应处理过程

中黄色区域标记的是django中间件处理函数,toolbar中间件实现了Request中间件、View中间件和Response中间件,在Request中间件和View中间件中toolbar一次调用所有panel的中间件进行处理,最后toolbar在Response中间件中收集所有panel采集的debug信息,并以html的形式注入到response body中, 这就是debug-toolbar的大致工作流程。更具体一点,我们通过几个panel的例子进行说明:

(1)SettingsPanel: 这个panel很简单,仅仅在response中间件调用时读取django settings信息,并输出成页面片段 (2)SQLPanel:比如说描述的SQLPanel就是在该panel启用的时候对database connection进程patch,进行一个wrap操作,这样每次外层视图函数view内部进行db操作时,sqlpanel就可以记录起来,在response中间件调用时输出结果,同时进行unwrap操作。 (3)ProfilingPanel:又比如说ProfilingPanel模块是在调用View中间件的时候直接用cprofile调用视图函数,并收集profile数据。

使用总结:(重点部分)

下面是项目中的实践总结出来的一点经验,希望能给大家提供点有用的信息:

(1)ajax问题处理 前面讲django-debug-toolbar时提到, toolbar将调试信息以html的形式注入到返回的html内容中,由于ajax请求返回更多的是json数据,如果直接将debug信息插入返回内容会导致真实的返回内容被破坏。目前网上最为成熟的解决方案是Django-Debug-Panel,

(2)需要注意的页面冲突问题及解决办法 toolbar将调试信息以html的形式注入到返回的html内容中带来的另外一个问题就是容易引起页面bug,比较容易想到的jquery重复加载会导致两次加载之间初始化的第三方jQuery插件被清空。为了防止toolbar引起页面bug,比较保守的方式是采用(1)中提到的方案,我在附件中提供了一小段代码供参考。

(3)是否可以将django-debug-toolbar应用到现网? 我们在开发、维护过程中往往有一些直接在现网定位问题的需求,特别是开发环境往往系统的熵、数据量都不够,另外,现网发现问题往往要以最快的速速找到原因和解决方案,在开发环境重现问题效率特别低,如果能够直接在现网定位问题,很快情况下将会大大加快问题跟进处理周期,对开发人员本身也能一定程度提升工作效率。

将toolbar用于现网需要几个方面的问题:

a. 性能:其实开启toolbar对单次请求具有一定影响,特别是ProfilingPanel执行耗时非常大,它是toolbar默认不开启的唯一一个panel。由于toolbar只是调试工具,并不用于监控,可以仅在需要时打开。另外所有panel功能都处于关闭状态,toolbar对系统和单次请求的性能影响都非常小(只是几个逻辑判断),因此将toolbar用于现网性能方面是可行的。

b. 稳定性:这一块是最难确认的,为了简化问题分析,我们将服务进程生命周期按panel开启前后分成三个阶段。panel从未开启之前,panel的代码是没有执行到,对服务进程是没有影响的。由于panel开启时可能会向python代码中注入一部分代码,因此对于panel关闭之后对稳定性是否有影响要看注入的代码是否恢复,经过检查toolbar中panel代码,可以确定,panel关闭之后代码是恢复了的。比如前面工作原理

(2)提到的SQLPanel在response中间件调用时有unwrap操作。最后panel开启过程中,可以从Web服务模式进行考虑。如果Web服务工作在进程模式,由于进程必须处理完一个请求再处理另外的请求,因此进程模式下panel开启过程中只会对当前请求有影响。最后线程和协程的服务模式可能因为全局代码被patch而受到一定影响,因此对于ProfilingPanel这种开启会进行patch操作会对线程和协程模式有短暂影响,进程模式是安全的。

c. 安全:任何系统被任意查看系统内部信息都很危险,开启和查看都只能管理员才能进行操作。

总结:仅在Web服务是进程模式时toolbar部署到现网环境才是可信的。另外,所有panel应该是默认关闭的,只有管理员和开发人员才允许开启和查看toolbar的debug信息。

(4)是否可以应用于django1.3代码环境 目前官方的toolbar仅支持django1.6及以后的版本,1.3是不支持的,由于笔者实践的项目是基于django1.3开发的,笔者针对django1.3对toolbar进行了一个代码调整,除了StaticFilePanel,其它panel都可以用到1.3环境。附件中提供了修改后的代码供参考。

(5)应用到蓝鲸app开发环境

一个记录第三方接口调用的panel:

前面提到的SQLPanel和ProfilingPanel是toolbar中非常重要的两个功能,个人感觉toolbar中最重要的是它可以作为构建自己开发工具的脚手架,提供了很多开发工具构建思路的同时,还可以减轻构建开发工具的工作量。笔者的另外一个项目中应用了大量第三方http接口服务,前期接口对接和后面的运营过程中遇到了很多接口问题,定位和反馈问题很是耗费时间,最终笔者写了一个http-client-panel, 它可以在不用修改接口调用代码的情况下,记录第三方http接口调用的详细输入输出,欢迎大家试用。

展望:

我在使用toolbar的过程中也总结了一些痛点和可改进的地方,希望有兴趣的同学可以一起完善django开发工具。

  1. 性能分析工具不够完善,基于cprofile开发的,缺少line-profile更细致的性能分析,如果能结合cprofile的功能定位出大致慢的函数,然后可以方便的用line-profiler定位具体慢的行,这个性能分析工具将会更棒。
  2. 缺少一个好用的bug定位的panel。 a. 程序异常退出位置有时定位比较耗时,如果有一个panel能直接显示出http响应轨迹,那么定位异常位置会更直观更快速。 b. 程序异常的往往因为非预期的变量值,但是往往靠猜测然后确认,如果能直接显示感兴趣的变量值,可以节省不少时间。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美团技术团队

美团点评境外度假团队前端项目开发实践总结

前言 随着前端项目数量和规模越来越大,参与的人员也越来越多,如何在前端项目开发过程中保证优质的开发者体验和项目的可维护性,同时确保极致的用户体验将会是一个非常大...

3678
来自专栏张善友的专栏

使用 Visual Studio Agent 2010 进行负载压力测试的安装指南

在 Visual Studio 2010 Ultimate 里,其实不用特别安装 Visual Studio Agent 2010  就能进行负载压力测试,不过...

1756
来自专栏雪胖纸的玩蛇日常

Vue+Django2.0 restframework打造前后端分离的生鲜电商项目(2)

1.轻量,直接通过http,不需要额外的协议,post/get/put/delete操作

763
来自专栏七夜安全博客

go go go - beego

在上一篇文章What!!! so fast中,我介绍了golang这种语言,并使用golang开发了一个端口扫描工具。现在我的主要工作是做网络安全方面的开发与策...

1052
来自专栏吴伟祥

通信协议之Protocol buffer(高效的数据压缩编码方式之Java篇)

之前一直习惯用json进行数据的传输,觉得很方便。来到新公司后发现同事们用的更多的的协议都不是json,而是Protocol buffer。这个东西之前没有听说...

583
来自专栏企鹅号快讯

Android应用架构前世今生

前言 Android的开发生态系统发展迅速,在开发Android的几年的时间里,用来构建Android应用的架构与技术一直在不断进化。随着项目的不断更新迭代,应...

1896
来自专栏TechBox

模块化与解耦简述4. 解耦与通信5. 源码推荐

1243
来自专栏CSDN技术头条

Android应用架构前世今生

前言 Android的开发生态系统发展迅速,在开发Android的几年的时间里,用来构建Android应用的架构与技术一直在不断进化。随着项目的不断更新迭代,应...

1917
来自专栏全华班

一款免费、开源,使用sprinbboot快速开发管理系统

BootDo是在SpringBoot基础上搭建的一个Java基础开发平台,MyBatis为数据访问层,ApacheShiro为权限授权层,Ehcahe对常用数据...

711
来自专栏程序你好

如何为你的移动应用建立RESTful API

602

扫码关注云+社区