星期六, 十月 27, 2007

[Django]Windows下Django配置Apache示范设置

[Django]Windows下Django配置Apache示范设置
Version
Date
Creator
Description
1.0.0.1
2006-11-20
郑昀
草稿

继续阅读之前,我们假设您熟悉以下知识:
n Python
n Django
n Apache
如果不熟悉这些知识点,可以看本文最后资源列表中的文章。
本文讨论了在Windows环境下,将Django配置到Apache Web Server时所遇到的问题,以及最终解决的示范步骤。

您可以遵循后文描述的配置步骤,在此之前,我们先描述两个常见的错误现象。
[常见错误现象1]
关键词: client denied by server configuration。
表象: 访问了http://localhost/mysite/ 后,假如发现图片没有加载,或者css没有应用上,并且httpd.conf文件中Location的配置绝对路径肯定没错。

解释:
第一, 首先检查httpd.conf配置Alias的配置,
看看Alias设置的路径是否正确,
Alias /site_media c:/django/myproject/media
请保证您附加的这个路径肯定是你的图片或者css存放的路径。
其次,请检查您的django项目myproject目录下的settings.py,保证MEDIA_ROOT、STATIC_PATH、TEMPLATE_DIRS这三个参数指向的绝对路径正确无误。
最后,如果上面的参数都没错,却还是不行。那么请您检查Apache的日志文件
Apache2.2\logs\error.log
如果您发现有这样的错误提示:
错误日志
[Mon Nov 20 17:27:08 2006] [notice] Child 4172: Starting thread to listen on port 80.
[Mon Nov 20 17:27:08 2006] [error] [client 127.0.0.1] client denied by server configuration: c:/Django/myproject/media/css/global.css, referer: http://localhost:80/mysite/
那么说明是因为对这些资源文件的访问被拒绝了。
此时,请您浏览 http://localhost/site_media/css/global.css ,如果遇到了HTTP 403错误,就说明是权限问题。
此时,请到httpd.conf,增加如下配置来允许静态资源文件夹被访问:
增加的配置行
# 对需要访问的区域,可以增加正确的Directory块
# 否则会得到这样的错误:client denied by server configuration: c:/Django/myproject/media/css/global.css, referer: http:/ /localhost:80/mysite/

Order Deny,Allow
Allow from all

重启Apache服务。

[常见错误现象2]
关键词: EnvironmentError: Could not import settings。
表象: 访问了http://localhost/mysite/ 后,直接页面报告如下错误:
页面错误输出
1. Mod_python error: “PythonHandler django.core.handlers.modpython”
Traceback (most recent call last):
File “C:\Python24\Lib\site-packages\mod_python\apache.py”, line 299, in HandlerDispatchresult = object(req)
File “c:\django_src\django\core\handlers\modpython.py”, line 163, in handlerreturn ModPythonHandler()(req)
File “c:\django_src\django\core\handlers\modpython.py”, line 125, in __call__if settings.ENABLE_PSYCO:
File “c:\django_src\django\conf\__init__.py”, line 27, in __getattr__self._import_settings()
File “c:\django_src\django\conf\__init__.py”, line 54, in _import_settingsself._target = Settings(settings_module)
File “c:\django_src\django\conf\__init__.py”, line 82, in __init__raise EnvironmentError, “Could not import settings ‘%s’ (Is it on sys.path? Does it have syntax errors?): %s” % (self.SETTINGS_MODULE, e)
EnvironmentError: Could not import settings ‘myproject.settings’ (Is it on sys.path? Does it have syntax errors?): No module named myproject.settings

这是开始配置django+apache最容易遇到的问题,:D。

解释:
这是因为apache在系统目录下找不到myproject/settings.py文件。
首先检查PythonPath设置的路径是否正确:
PythonPath "sys.path+['c:/django']"
注意,这个'c:/django'路径实际是我们的项目路径c:/django/myproject的上一级目录!不要写错了。
增加的配置行
# mysite目录路径: c:/django/myproject,
# 但是对于PythonPath,必须设置成这个目录的上一级目录!
# this site url:http://localhost:80/mysite/

SetHandler python-program
PythonPath "sys.path+['c:/django']"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE myproject.settings
PythonInterpreter mysite
PythonDebug On


配置Django到Apache的步骤:
如何在Windows环境下安装Apache和mod_Python, 这篇Blog解释得很明白,我下面的这些步骤得到了验证。1:从 http://httpd.apache.org/来获取apache_2.2.3-win32-x86-no_ssl.msi这个安装文件;运行这个msi即可顺利安装Apache。
2:
网络上有很多说可以利用Apache和mod_python源代码来编译安装mod_python的,但是如果你仅仅想快速安装,那么请从
http://www.apache.org/dist/httpd/modpython/win/3.2.10/
直接下载
mod_python-3.2.10.win32-py2.4-apache2.2.exe
文件,运行这个exe即可顺利把mod_python安装到Python2.4以及Apache2.2;
由于GFW的封锁,可能您无法访问apache网站,那么可以从这里下载:
http://www.cnblogs.com/Files/zhengyun_ustc/mod_python-3.2.10.win32-py2.4-apache2.2.rar
3:
我们用
Python django-admin.py startproject myproject
命令,在C盘的django目录下创建了一个Django项目myproject。我们把它引用的图片文件和css文件等静态资源都放在myproject文件夹下的media目录中。
此时,将myproject目录下的settings.py文件中的这三个参数修改一下,主要是为了从相对路径变成绝对路径:
修改的配置行
# Django settings for myproject project.
'''
将相对路径改为绝对路径。主要有:
MEDIA_ROOT
TEMPLATE_DIRS
STATIC_PATH
'''
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = 'c:/django/myproject'
STATIC_PATH = 'c:/django/myproject/media'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates".
# Always use forward slashes, even on Windows.
'c:/django/myproject/templates',
)
切记切记,一定要保证这三个参数是绝对路径。
4:
配置Apache的httpd.conf配置文件:
首先,在“Dynamic Shared Object (DSO) Support”的配置下增加一行
LoadModule python_module modules/mod_python.so
这个必须手动添加。
5:
我们列出此时Apache所需要的参数分别为:
项目名:myporject
试图访问的URL为:http://localhost/mysite/
静态资源文件的存放目录:c:/django/myproject/media
项目文件夹路径:c:/django/myproject
好了,此时你就应该在httpd.conf文件的最后附加这段配置,以便让Apache知道到哪里去定位myproject/settings.py文件:
增加的配置行
# mysite目录路径: c:/django/myproject,
# 但是对于PythonPath,必须设置成这个目录的上一级目录!
# this site url:http://localhost:80/mysite/

SetHandler python-program
PythonPath "sys.path+['c:/django']"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE myproject.settings
PythonInterpreter mysite
PythonDebug On

对于上面的配置,Limodou注释道:“上面 PythonPath 主要是将 myproject的目录加入到 sys.path ,以便 Django 可以找到。需要使用绝对路径。
SetEvn 中设置的 DJANGO_SETTINGS_MODULE 就对应于你的 项目名.配置文件。因此为了能导入 项目名.配置文件,就需要前面的 PythonPath 的设置。
PythonDebug 和 PythonAutoReload 建议在生产时设为 Off 。”
为了让图片、css、script能够被Apache成功加载,还需要在httpd.conf最后附加这段配置:
增加的配置行
#Alias /site_media 是用来将 myproject的静态文件设置一个 URL 访问的别名。
Alias /site_media c:/django/myproject/media

SetHandler None


#Alias /media 是将 Django Admin 的静态文件设置一个 URL 的访问别名。
Alias /media c:/Django-0.95/django/contrib/admin/media

SetHandler None


# file types we want to serve statically
# case insensative match

SetHandler None


Limodou在Step by step中特地说“同时可以注意到 settings 我改为了 settings_apache 了。一方面将要把其中的内容有关相对路径的东西改为绝对路径,另一方面我还想保持现在的 settings.py 。”这也是一个很好的做法。
最后,修改MaxRequestsPerChild为1,这是一个可选项。Limodou是这么说的“同时如果你不想每次重启Apache 来进行测试,可以将: MaxRequestsPerChild 0. 改为: MaxRequestsPerChild 1

重启Apache服务。
6:
浏览 http://localhost/mysite/ 即可。

[参考资料]
1:《How to use Django with mod_python》Django官方文档
2:《HOWTO: Django on Windows》这篇blog给了我很大的帮助
3:《Django Step by Step (十二)》limodou的帮助文档4:《如何安装 Django

星期二, 十月 23, 2007

情爱的,你终于回来了,等你等得好辛苦!

情爱的,你终于回来了,等你等得好辛苦!
可你的兄弟 page 什么时候回来啊!

星期二, 七月 24, 2007

MySQL忘记超级用户口令怎么办

  如果MySQL正在运行,首先杀之: killall -TERM mysqld。
  启动MySQL:bin/safe_mysqld --skip-grant-tables &
  就可以不需要密码就进入MySQL了。
  然后就是
  >use mysql
  >update user set password=password("new_pass") where user="root";
  >flush privileges;
  重新杀MySQL,用正常方法启动MySQL 。

星期三, 七月 11, 2007

C++ 类构造
好久没用C++了,今天正好碰到一个函数返回对象的的问题,解决并顺便复习一下!
函数返回值是一个类,而这个类没有拷贝构造函数,而导致程序运行失败!缺省的赋值是没有办法解决那些在构造函数中的内存或文件等资源的!

class String {
private: char *data;

public:
String()
{
data = new char [10];
};
String(const String &);
String &operator = (const String &); };
String::String(const String &rs)
{
if(this != &rs) {
data = new char[10];
strcpy(this->data, rs.data);
}
}

String &String::operator=(const String & rs)
{
if(this != &rs)
{
delete[]data;
data = new char[10];
strcpy(this->data, rs.data);
}
return *this;
}

int main(int argc, char* argv[])
{
String s1; String s2(s1); //调用拷贝构造
String s3 = s1; //还是调用拷贝构造,为什么不调用赋值=
return 0;
}

String s2(s1);
String s3 = s1;
只是语法形式的不同,意义是一样的,都是定义加初始化,都调用拷贝构造函数。C++语言支持两种语法形式的初始化,就是上面的两种。
注意, String s3 = s1;
跟 String s3;
s3 = s1;
不同。这里则是首先调用默认构造函数初始化s3,然后使用拷贝赋值从s1那里进行拷贝。
而例子中s2和s3的构造过程都没有执行国默认构造函数。
至于为什么不同,不为什么,这就是语法,就好比循环要使用while和for,分支要使用if和switch一样,不能混用。

String c = b; //也是调用拷贝构造函数 而
String c; c = b;//这才是调用operator =
String s3 = s1; //还是调用拷贝构造,为什么不调用赋值= 这是因为这里的“=”不是运算符。它只是一种形式上规定的分隔符。

星期五, 七月 06, 2007

MySQL数据库插入性能的改进

最近,重新开始了对3年前一个项目的改进,该项目采用JDBC+MySQL的方式完成一些数据库操作,记得当时是每秒中可以插入70条左右的数据,由于可以满足当时的需要就没有太在意!

抱着软件质量就是持续不断的改进的态度,想把当初的JDBC+MySQL改为C API实现的方式,所以今天写了一个C程序客户端,测试中发现美妙中可以插入50条记录,感到可能时在什么地方用错了,到Google一些资料后,基本可以判断是采用了AOTOCOMMIT一引起的问题,所以对操作方式做了一些修改
SET AOTOCOMMIT=0
然后每插入1000条,就COMMIT一次,发现这个时候每秒可以插入2000条数据,比较满足。

可以看出,COMMIT是一个比较费时的过程
50*(COMMIT_COST + INSERT_COST) 基本等于 2000*INSERT_COST + 2*COMMIT_COST,此时客户端花的CPU比服务器要多。

继续改进,采用Prepare Statemode来降低INSERT语句的分析花费,每秒可以插入5000条
2000*INSERT_COST(SQL_PARSE+REAL_INSERT) + 2*COMMIT_COST基本等于5000*REAL_INSER + 5*COMMIT_COST
这个时候,客户端已经比服务器端花的时间少了,且服务器端出现了花费了更多的系统CPU,应该时磁盘IO操做便多的缘故!

星期二, 六月 26, 2007

Symbian系统

Symbian是一个实时性、多任务的纯32位操作系统,具有功耗低、内存占用少等特点,非常适合手机等移动设备使用,经过不断完善,可以支持GPRS、蓝芽、SyncML、以及3G技术。最重要的是它是一个标准化的开放式平台,任何人都可以为支持Symbian的设备开发软件。与微软产品不同的是,Symbian将移动设备的通用技术,也就是操作系统的内核,与图形用户界面技术分开,能很好的适应不同方式输入的平台,也可以使厂商可以为自己的产品制作更加友好的操作界面,符合个性化的潮流,这也是用户能见到不同样子的symbian系统的主要原因。现在为这个平台开发的java程序已经开始在互联网上盛行。用户可以通过安装这些软件,扩展手机功能。
在Symbian发展阶段,出现了三个分支:分别是Crystal、Pearl和Quarz。前两个主要针对通讯器市场,也是出现在手机上最多的,是今后智能手机操作系统的主力军。第一款基于Symabian系统的手机是2000年上市的某款爱立信手机。而真正较为成熟的同时引起人们注意的则是2001年上市的诺基亚9210,它采用了Crystal分支的系统。而2002年推出的诺基亚7650与3650则是Symbian Pearl分系的机型,其中7650是第一款基于2.5G网的智能手机产品,他们都属于Symbian的6.0版本。索尼爱立信推出的一款机型也使用了Symbian的Pearl分支,版本已经发展到7.0,是专为3G网络而开发的,可以说代表了当今最强大的手机操作系统。此外,Symbian从6.0版本就开始支持外接存储设备,如MMC,CF卡等,这让它强大的扩展能力得以充分发挥,使存放更多的软件以及各种大容量的多媒体文件成为了可能。
Symbian按版本来分,继2005年二月Symbian推出一款新的手机操作系统软件OSv9.0,到目前为止已先后有了6.0、6.1、7.0、7.0s、8.0、9.0几种版本。1999年3月Symbian推出了Symbian5.0操作系统,它的主要内核集合了网络,无线文字,电子邮件,名片薄以及个人信息助理,同时还具有支持标准网络页面的浏览器,配合java语言的支持,使得Symbian可以运行小型的应用程序。不过这个版本采用的机型甚少,基本上与EPOC没有太多的差别。
Symbian 6.0则在5.0的基础上增加了,GPRS、WAP1.2浏览器以及蓝牙技术的支持,用户可以运行第三方基于C++和J2ME开发的程序。而Symbian 6.1则是和Symbian 6.0相比主要增加了对USB的支持。Symbian 6.0的主要特点是: 支持语音通话和数据通信 ,支持Bluetooth和WAP ,配备安全性功能(SSL,HTTPS,WTLS) ,采用16bit Unicode,支持多语言显示 ,采用“PersonalJava 3.0”和“JavaPhone 1.0” 。
Symbian 7.0则支持多模式和3G手机(专区),可以让制造商们可以面向全世界推出可以运行于所有网络之上的Symbian OS手机,而且可以不对代码进行重大改动的情况下就可以重新使用许多目前已有的软件应用。7.0包含一些新的通讯、消息、联网和应用开发技术,并对一些与安全和认证相关的功能进行了改进。Symbian OS 7.0的其他功能包括:支持灵活的用户界面,例如Nokia的Series 60;支持几种音频/图像格式和许多面向游戏开发人员的API;全力的加密和认证管理,基于安全通讯协议(包括HTTPS、WTLS和SSL)及认证的应用安装;和Over-the-air(OTA)SyncML同步支持。
2004年2月,Symbian在授权LG等公司的时候,发布了Symbian8 .0版本。该版本改善了实时系统性能,提高了原有操作系统的兼容能力。此外,Symbian OS 8.0的软件工具改进了远程接入控制系统功能,运用调节装置消除手机用户使用增值服务时会受到的干扰。这个系统包含了绝对现代化的多媒体和Java设备,支持多种标准,其中包括JSR118, CLDC1.1 (JSR139),MobileMedia (JSR135),3D图像数据(JSR184), JTWI 1.0 c(JSR185)。最后,新版OS还支持SDIO。
2005年二月,英国著名手机软件制造商Symbian推出一款新的手机操作系统软件OSv9.0,它支持更高像素数码相机与三维游戏动画。该操作系统软件对运行环境要求较高,目前运行在由英国芯片开发商ARM提供的快速处理器芯片,并且需要相关设计与其它工具的支持来帮助手机生产商在开发其它版本时能够节约时间和降低成本。该软件可以处理200万像素的数字图片,甚至能够向无线耳机传送立体声音乐,更可喜的是,它不需要同步软件就能够从PC上导出MP3文件。
Series60是智能手机中应用最广泛的系统版本。Series60系统还分为6.0 OS、7.0 OS和8.0 OS三个版本。区别Series60的最直观因素在于屏幕的分辨率,Series60支持的分辨率为176*208像素,但以后S60还会支持240*320像素、352*416像素等。S60是拥有最多第三方软件或游戏的界面。
识别Series80界面最简单的办法就是看手机是否支持全键盘,例如诺基亚高端系列的9210、9300甚至9500,都采用全键盘的。识别Series90的最简便方法是:会采用触摸屏幕,分辨率也高达640*320像素。Series90应该是手机游戏、娱乐的最强平台,但因为采用Series90界面的手机型号太少,第三方软件的支持很少,所以S60依旧是玩家首选。
S40或S60是指诺基亚手机的上层平台。S60都是智能手机,所用底层操作系统是Symbian。诺基亚128*128屏幕都是S40 1.0。而128*160是S40 2.0。
另外S40中,3100支持java MIDP 1.0,所以最大支持64KB的java;6230支持java MIDP 2.0,所以最大支持128KB的java40和60,包括90,还有以前的30,都是针对与nokia不同的操作系统而言40,是nokia自行研制的手机操作系统,面对于中低端客户,支持kjava的开发,其处理器效率不高,内存偏低,屏幕大小128*128。
S60,是基于Symbian 操作系统,也就是以前的epoc,其处理器为arm9,处理效率很高,内存颇大,屏幕大小为208*176同时支持kjava和C++的开发90,属于手持式设备,也是Symbian 操作系统但是功能强劲,等同于一个PDA了。
其实技术来上说,S40跟S60是区别在系统平台上,就好像WIN98跟WIN2000,但手机不像PC,屏幕大小的确是个关口,以致于平台不容易做到向下兼容,但有的游戏也同样做出不同版本来的。
当然啦,S40比S60不单单是屏幕上的差距,更大的是性能上的差距,一般来说,S60开发出来的游戏质量都比S40高好多,但可惜,S60比S40的机子又贵上了很多啊。

星期日, 六月 03, 2007

Apache运行时库中的进程锁 -- apr_proc_mutex 命名所的扩展

Apache运行时库中的进程锁 得到一个明确的事实,那就是apr实现的进程锁其实时无名锁,只能在fork出的父子进程中互锁。


然而,通过直接进行系统调用实现命名锁的有2个比较显著的问题,1,代码移植性不够好,posix或sysv,fcntl或flock等实现在不同的系统上接口会有所不同。2,代码封装与风格问题,到现在,越来越不惜欢没有经过分装的直接操作了!

所以,将apr_proc_mutex做了几个扩展操作函数,为apr提供了命名的进程锁。

APR_LOCK_PROC_PTHREAD机制的锁没有实现完毕,会出现SIGBUS错误,其他的模式在fedora core 6上测试都是没问题的啦!
扩展的procx_mutex可以去我的网站下载了,必须需要apr库,仅仅添加了一个头文件。

#include "apr_pools.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_errno.h"
#include "apr_file_io.h"

#include "apr.h"
#include "apr_shm.h"
#include "apr_file_io.h"
#include "apr_proc_mutex.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_getopt.h"
#include "errno.h"
#include "assert.h"
#include "stdlib.h"


#define MAX_ITER 200
#define CHILDREN 6
#define MAX_COUNTER (MAX_ITER * CHILDREN)

void errlog(apr_status_t s, const char*log)
{
char errbuff[PATH_MAX];

if(log)
printf(log);
if(s!=APR_SUCCESS)
{
printf(apr_strerror(s,errbuff ,PATH_MAX));
abort();
}
}

int main(int argc, char* argv[])
{
apr_pool_t *pool;
apr_status_t rv;
const char* lockname = "/tmp/lock";
apr_lockmech_e mech = APR_LOCK_DEFAULT;
/*
APR_LOCK_FCNTL, fcntl()
APR_LOCK_FLOCK, flock()
APR_LOCK_SYSVSEM, System V Semaphores
APR_LOCK_PROC_PTHREAD, POSIX pthread process-based locking //Test failed
APR_LOCK_POSIXSEM, POSIX semaphore process-based locking
APR_LOCK_DEFAULT Use the default process lock
*/

if (mech==APR_LOCK_POSIXSEM)
lockname = "/posixlock";

static apr_proc_mutex_t *proc_lock;

apr_initialize();
apr_proc_mutex_unix_setup_lock_ex();

rv = apr_pool_create(&pool, NULL);
errlog(rv,"apr_pool_create\n");


#if USE_FORK
if(fork()!=0) {
#endif
if(argc==2 && strcmp(argv[1],"init")==0)
{
rv = apr_proc_mutex_create_ex(&proc_lock, lockname, mech, pool);
errlog(rv,"apr_proc_mutex_create_ex\n");

printf("Init OK\ndefulat=%s\nmutex=%s\nlocalfile=%s\n",apr_proc_mutex_defname(),apr_proc_mutex_name(proc_lock),apr_proc_mutex_ex_lockfile(proc_lock));

do{
errlog(0, "P Enter to lock\n");
getchar();
rv = apr_proc_mutex_lock(proc_lock);
errlog(rv, "P apr_proc_mutex_lock\n");
printf("P Enter to unlock\n");
getchar();

rv = apr_proc_mutex_unlock(proc_lock);
errlog(rv, "P apr_proc_mutex_unlock\n");
}while(1);
exit(0);
}
#if USE_FORK
}else {
#endif
printf("Child Mode\n");
// if (apr_proc_mutex_create_ex(&proc_lock, lockname, mech, pool))
rv=apr_proc_mutex_child_init_ex(&proc_lock, lockname, mech, pool);
errlog(rv,"C failed apr_proc_mutex_child_init\n");

printf("Init OK\ndefulat=%s\nmutex=%s\nlocalfile=%s\n",apr_proc_mutex_defname(),apr_proc_mutex_name(proc_lock),apr_proc_mutex_ex_lockfile(proc_lock));

do{
printf("C Enter to lock\n");
getchar();
rv = apr_proc_mutex_lock(proc_lock);
errlog(rv, "C apr_proc_mutex_lock\n");
printf("C Enter to unlock\n");
getchar();
rv = apr_proc_mutex_unlock(proc_lock);
errlog(rv, "apr_proc_mutex_unlock\n");
}while(1);

#if USE_FORK
}
#endif

exit(0);
return 0;
}