用Python解决数据结构与算法问题
Mar 14 2017发现一本Python的好书被翻译了,利用下班时间学习了一下,把相关代码都实现了一遍,包括:
- 栈,队列,双端队列
- 无序链表,有序链表
- 二叉树,堆,二叉搜索树,AVL树
- 图
以及一些算法
发现一本Python的好书被翻译了,利用下班时间学习了一下,把相关代码都实现了一遍,包括:
以及一些算法
董明伟基于自己实践讲的知乎live为Python新人提供了很多实用建议,他推荐的罗子雄:如何成为一名优秀设计师的演讲讲的非常好,总结了设计师从入门到提高的优秀实践。
罗子雄的演讲我看了三遍,再结合自己的程序员生涯,我想我也可以为Python新人提供一些建议,开了如何成为一名优秀的程序员一题,讲讲我的Python工程师之路。
Django db模块本身不支持MySQL连接池,只有一个配置CONN_MAX_AGE
连接最大存活时间,如果WSGI服务器使用了线程池技术,会达到连接复用的效果。但是如果WSGI服务如果是每个请求都创建新的线程,那么这个配置没有任何效果,因为连接保存在Thread.local()
名称空间中,在不同的线程中不能复用。
在上一篇greentor MySQL连接池实现中已经实现了MySQL连接池,只需要重写Django MySQL backend以支持连接池,就能达到连接复用的目的,减少socket 3次握手的开销,提高性能。
https://github.com/zhu327/greentor/blob/master/demo/core/base.py
通过greentor实现了pymysql在Tornado上异步调用的过程后发现,每次建立数据库连接都会经过socket 3次握手,而每一次socket读写都会伴随着greenlet的切换,以及ioloop的callback过程,虽然是异步了,但是IO性能并没有提升,所以在研究了TorMySQL连接池的实现后,实现了greentor自己的连接池。
https://github.com/zhu327/greentor/blob/master/greentor/green.py
经过2周的学习开发,Tornado + Django ORM的环境搭好了,这阶段的学习告一段落,虽然这个环境是一个玩具环境,没有经过生产的检验,但是在搭环境的过程中学习了Tornado,greenlet,Django数据库相关的姿势,感觉还是有不少提升。
在这2天的调试中,暴露出了2个比较严重的问题,记录下填坑过程。
WSGI服务器在接受到新的http请求时会开一个新线程来调用application进行处理,Django ORM在有数据库查询的时候,会在当前线程中创建一个新的数据库连接并保存到线程local空间中,在同一个线程中的连接是可以被复用的。不同的线程持有不同的连接,这样就保证Django ORM是线程安全的。
Tornado是单线程的,在Tornado中使用Django ORM无论处理多少请求,都会用同一个保存在当前local()中的连接,这样就必然会产生连接使用的冲突。比如同时并发的2个请求,第一个请求关闭了连接,第二个请求还在继续使用这个连接就会抛出异常。
在greentor的配合下,Tornado涉及数据库连接的请求都运行在greenlet中,如果有一个greenlet local来对每个请求的数据库连接进行隔离,就能避免线程安全问题,在这里的greenlet协程完全可以类比为线程。然而greenlet并没有local,那我们就造一个local出来。