2016-01-01
站点的制作到达尾声,需要考虑部署的问题了。
所以想趁前段时间很火的docker还热手,熟悉一下练练手,也方便后面实际环境部署用,避免又像之前一样apache在一台server上怎么都跑不起来的尴尬。
但是,就在啥都部署好了,站点也都能正常运行和访问之后,发现一个让我崩溃的问题。
pyodbc会产生一个并发的异常错误。
现象是pyodbc报出来的,但是具体是不是pyodbc的错误,还不清楚。
情况如下:
站点使用Django作为框架,前端是Jquery+Bootstrap,大量采用异步获取数据库数据,避免网页阻塞。
调用方式:
1. Jquery $.getJson 访问一个页面异步获取数据;
2. 获取的页面是用 Django 产生的 HttpResponse View,里面没有任何html内容,只有dumps出来的 json 数据,形如:[{}.{},{}];{key:{},key2:[]};
3. 因为采用了异步,所以不知道啥时候数据会提取完毕,所以用setInterval设置定时器捕获数据,一旦获取到数据就清除定时器,加载页面数据。
就是这三个步骤了,具体的代码后面贴出。
----------------------------------------
2016-01-02 更新
说了这么多,其实都可以忽略,上面的内容总结一句话:同一时间多次调用pyodbc,会产生异常的抛出情况。
('IM001', '[IM001] [unixODBC][Driver Manager]Driver does not support this function (0) (SQLRowCount)')
昨晚对这个问题百思不得其解,今天终于解决了。
这个问题并非docker或者pyodbc产生的,而是由于Microsoft® SQL Server® ODBC Driver 1.0 for Linux优化不足产生的。
请让我细细道来。
1月1日的时候,想用使用pyodbc通过FreeTDS连接SQLServer数据库,奈何FreeTDS是连接上了,但是pyodbc无论如何都报错:
Traceback (most recent call last):
File "
pyodbc.Error: ('08001', '[08001] [unixODBC][FreeTDS][SQL Server]Unable to connect to data source (0) (SQLDriverConnect)')
所以当时就产生了放弃FreeTDS的念头,转向其它方式连接SQLServer。
按照文章(Linux上使用MSSQL Server作为Django的Database Backend)中的描述,到微软的download center下载了Microsoft® SQL Server® ODBC Driver 1.0 for Linux,按照软件提供的说明文档进行安装之后,确实能通过pyodbc连接数据库。
当时非常高兴,终于能用了。
但是,当Django站点放在docker上面之后,用runserver方式运行,访问第一个页面没有问题。
访问第二个页面的时候就崩溃了。
提示如下:
看名字就知道了,这个Json页面是菜单的公共页面。
既然A页面能打开,那么B页面也应该能打开,因为都需要用到这个页面的数据的呀。
于是停掉runserver
再启动,这次先访问B页面,发现居然没有报错……
在打开C页面,又报错了,而且通过console log,发现所有的Json页面都报错了,并非只有这个页面。
重启runserver,再单独一个个Json页面打开,悲剧的娃啊,二十几个Json页面啊,全部打开了一遍,都没有报错……
然后我就猜,是不是并发产生的问题了。
果然。
通过runserver日志,发现在获取多个Json页面的时候,当稍微靠前的一条请求获取的数据比较多的时候(理解为耗时比较长),就会产生500报错。
而且这个报错会直接把整个站点崩溃掉,不重启还不行。
然后我就郁闷到了。
我在windows下面可是怎么折腾都可以的啊,一个页面频繁刷新都没事,怎么到了linux环境下面就不行了呢。
就在这种郁闷的状态下过了两晚。
想想,可能问题不在pyodbc上面。
毕竟windows下的和linux下的都是同一套源码编译出来的,发生这种情况的概率应该不高。
那么,有可能是啥呢?
目光回到了微软的ODBC驱动上面了。
好吧,那我还是回归FreeTDS的怀抱吧。
折腾了很久之后,终于pyodbc通过FreeTDS连上了Sql server。相关文章:CentOS6使用unixODBC+FreeTDS+pyodbc连接Sql Server2008
开香槟!
然后兴奋地修改站点配置后启动runserver。
打开页面
B页面~
C页面~
刷新刷新再刷新~~~
没事儿。
好吧,微软老儿,老子太认真,输给你了。