解决SAE SVN部署代码时速度过慢的问题

问题分析

新浪有多个SVN服务器,连接其中速度最快的那一个即可。

解决方法

找到最快的SVN服务器

使用“多个地点ping工具”:

http://ping.chinaz.com/

输入域名:

svn.sinaapp.com

从本地ping响应时间最短的几个IP中,找出反应速度最快的。

修改本地域名解析

$ sudo gvim /etc/hosts

220.181.136.231 svn.sinaapp.com

参考资料

新浪sae(Sina App Engine)SVN上传代码缓慢的解决办法

国内极客必备装备指南

* 日期:2012-05-28

注:持续更新中,欢迎大家通过我的新浪微博或文章评论反馈意见。

## 简介

极客也就是Geek,即不作恶的黑客。极客不仅是一个群体的称谓,更代表了一种精神。极客不仅强调自身所具有的能力,也相当重视完成一项工作的效率。为此,一些趁手的工具是必不可少的。这些工具就像是战士的武器,就像是科学家的仪器,是极客身体的延伸。那么极客到底需要哪些工具呢?《国内极客必备装备指南》将和你一起尝试回答这个问题。

## PC

ThinkPad W530 1920*1080 8GB内存 160GB SSD 500GB 7200rpm + MacBook Air 13.3″ + Dell 23″ IPS + Orico 硬盘座

## 操作系统

Ubuntu 64bit/Deepin Linux + VirtualBox + WindowsXP

## 手机

小米手机 + Sandisk class6 16GB

## 云存储

Dropbox + 金山快盘

## 在线办公

Google Docs + Evernote

## 文本编辑器

Vim + gedit/Notepad++ + MarkItUp

## 办公软件

LibreOffice/WPS Office + XMind + GIMP

## Web浏览器

Firefox + Chromium/360极速浏览器 + QQ浏览器/UCWeb + Opera手机浏览器

## 阅读工具

Google Reader/网易阅读 + 当当读书/多看阅读 + 网易新闻

## 编程语言

HTML5 + JavaScript + CSS3 + Python + Markdown + 正则表达式

## 开发框架

Blueprint + BootStrap + jQuery + web2py + Bottle

## 版本控制

Mercurial + Git

## 项目管理

Redmine + Google Code + GitHub + 明道系统

## Web服务器(云计算)

SAE + 盛大云主机 + Linode VPS + nginx

## 域名管理

HostMonster + DNSPod

## 社区分享

WordPress + 新浪微博 + Gmail + QQ + Google Groups

盛大云主机使用体验和资费揭秘

说明

原有的基于Ubuntu 10.04.4的超微主机突然无法访问,ssh连接不上,控制台连接不上,其上的网站也无法访问。重启,包括关机后再开机,反复数次仍无法解决。在微博上在盛大云计算留言也没有得到回复。

斗争了一段时间后,决定删除重建。

配置

  • 超微主机
    • 1 CPU
    • 512MB 内存
    • 8GB 硬盘
  • 2Mbps 带宽
  • CentOS 6.2 64位 操作系统

使用成本

  • 超微主机:0.05元/小时
  • 2Mbps 带宽:0.13元/小时

  • 日成本:0.05*24+0.13*24,4.32元/天

  • 月成本:4.32*30,129.6元/月 (一个月按30天计算)

注:从上面的计算可以看到,对于个人来说,盛大云主机的使用门槛比虚拟主机要高得多。

访问方式

$ ssh root@IP
输入密码

$ ssh root@DOMAIN
输入密码

注意事项

  1. 指向盛大云主机的域名必须备案,否则盛大将强制停止云主机的服务。
  2. 不能随意升级操作系统内核(kernel),否则系统可能无法启动。(我遇到的是这种情况吗?)

在Ubuntu 12.04下使用Google Drive

通过grive使用Google Drive

添加PPA

$ sudo add-apt-repository ppa:nilarimogard/webupd8

安装grive

$ sudo apt-get update
$ sudo apt-get install grive

创建GDrive目录

$ cd ~
$ mkdir GDrive
$ cd GDrive
$ grive -a
按照提示获得并输入验证码

手动同步数据

$ cd ~/GDrive
$ grive

注:同步时会忽略Google文档。

通过googld-docs-fs使用Google Drive

注:google-docs-fs目前还不支持Ubuntu 12.04。

添加PPA

$ sudo add-apt-repository ppa:invernizzi/google-docs-fs

安装google-docs-fs

$ sudo apt-get update
$ sudo apt-get install google-docs-fs

创建GDrive目录

$ cd ~
$ mkdir GDrive
$ gmount GDrive username@gmail.com
输入密码

参考资料

Ubuntu 12.04下创建共享无线网络热点的方法

在Windows下创建共享无线网络热点需要安装Connectify,在Ubuntu下什么也不需要装。

具体的方法是:

网络管理器(Network Manager) -> 创建新的无线网络:

* 连接:新建 (默认)
* 网络名称:chinakr
* 无线网络安全性:WEP 40/128位密钥(十六进制或ASCII)
* 密钥:xxxxx

这样,在手机上就可以直接添加“chinakr”这个SSID,安全性选择“WEP”,输入密钥“xxxxx”。

参考资料:

[用ubuntu做软路由太方便了](http://forum.ubuntu.org.cn/viewtopic.php?f=73&t=278678)

车百科SAE升级Bottle.v0.11手记

为什么要升级到Bottle v0.11

说明:事实上Bottle官方发布的最新版本是发布于2012-02-11的v0.10.9,开发中的Bottle版本的称呼是dev,并不存在v0.11这个概念。本文中我借用v0.11来称呼当前的dev,只是因为个人认为v0.11可能很快会发布,不是为了抢沙发进行的SEO,特此澄清。

为什么要使用Bottle

在回答“为什么要升级到Bottle v0.11”之前先回答为什么要使用Bottle。

web2py是我最常使用的Python Web开发框架,它具有开发、部署简单、高效的特点。web2py+SQLite的组合应该是最适合个人站长的解决方案,一个Web应用或网站,包括数据在内,用几分钟就可以完全从一个服务器迁移到另一个服务器上。有了web2py,习惯于“租房”的草根站长们,再也没有“搬家”的烦恼了。

然而由于SAE本身具有的一些限制,目前的web2py还不能直接部署在SAE上,经过SAE工程师和网友们一段时间的努力之后也只能实现最简单的web2py应用在SAE上的部署,还不具备实用价值。

但是对于草根开发者而言,SAE的吸引力可以说是致命的。在云计算和移动互联网时代,一个不需要维护、速度快、高负载、低成本的服务器环境,对于一个Web应用或网站的快速成长具有重要的意义。SAE的出现使开发者将可以把主要精力放在产品设计、程序开发、产品运营和优化升级上,解决了开发者的后顾之忧。更何况,存储、邮件、短信、地理信息、中文分词等服务的使用,可以让Web应用或网站的能力大大提高,却几乎没有增加什么成本。

Bottle是一个单文件的Python Web开发框架,简洁、上手快、应用广泛,SAE支持Bottle是情理之中的事情。Bottle同样内置了一个轻量级Web服务器,本地的开发调试和web2py一样轻松。因此在SAE上进行开发,Bottle是一个不错的选择。

为什么要升级到v0.11

在明白了为什么要使用Bottle之后,接下来回答“为什么要升级到Bottle v0.11”。

Bottle v0.11目前还是开发版,但不久之后就会成为稳定版。SAE目前内置的Bottle是v0.9,这个版本至少有一个重要的不足,那就是URL映射的灵活性不够。

受web2py的影响,我习惯于把CSS文件、JS文件和图片分别放在static/css/、static/js/和static/img/目录下。

在Bottle v0.9中,为了实现对这些静态文件的应用,我需要这样写:

@app.route('/static/css/:filename')
def serve_css(filename):
    return static_file(filename , root='static/css')
@app.route('/static/js/:filename')
def serve_js(filename):
    return static_file(filename , root='static/js')
@app.route('/static/img/:filename')
def serve_img(filename):
    return static_file(filename , root='static/img')
@app.route('/static/doc/:filename')
def serve_doc(filename):
    return static_file(filename , root='static/doc')

而在Bottle 0.11中(事实上从0.10开始就是这样),我只需要这样写:

@app.route('/static/')
def serve_static(filename):
    return static_file(filename , root='static')

可以看到v0.11相对于v0.9的改进具有很大的实用价值,因此需要升级到Bottle v0.11。

此外,因为不想很快又写重写本文,因此选择了开发中的v0.11而不是当前的稳定版v0.10。

让Bottle v0.11在SAE上运行

由于SAE对目录读写的限制,Bottle v0.11无法直接在SAE上运行,为了解决这个问题才有了这篇手记。

把车百科从Bottle v0.9升级到v0.11

准备工作

车百科是一个基于SAE和Bottle的简单应用,提供了汽车标志的和相关信息的快速查询,开发过程可以参考“车百科开发手记”。

在升级车百科之前,先备份源代码。我个人通常使用7z这种压缩格式,因为7z的压缩包中文件名都是以Unicode编码保存的,在Windows和Linux环境下切换时,中文文件名不会出现乱码。

升级开发期间,为了不影响现有应用的正常运行,需要新建SAE应用版本4:

$ git branch newbottle
$ git checkout newbottle
$ gvim config.yaml &
version: 4

Bottle Web开发框架的下载:

$ cd ~src/sae/che123
$ wget https://github.com/defnull/bottle/raw/master/bottle.py
$ git add .
$ git commit -m 'Upgrade Bottle to v0.11 which actually means 2012-04-03 dev.'
$ saecloud deploy
Deploying http://4.che123.sinaapp.com

发现问题,解决问题

升级到Bottle v0.11后,我们的应用会报错:

$ lynx http://4.che123.sinaapp.com
Traceback (most recent call last):
  File "/data1/www/htdocs/790/che123/4/index.wsgi" , line 2 , in 
    from index import app
  File "/data1/www/htdocs/790/che123/4/index.py" , line 1 , in 
    from bottle import Bottle , template , static_file , run
  File "/data1/www/htdocs/790/che123/4/bottle.py" , line 38 , in 
    import base64 , cgi , email.utils , functools , hmac , imp , itertools , mimetypes ,\
  File "/usr/local/sae/python/lib/python2.6/subprocess.py" , line 416 , in 
    import fcntl
ImportError: No module named fcntl

错误出在bottle.py文件的38行和39行的import subprocess上,因为subprocess需要fcntl这个模块,而SAE不支持。

Python官方文档中对fcntl模块的说明是:

This module performs file control and I/O control on file descriptors. It is an interface to the fcntl() and ioctl() Unix routines.

Python官方文档中对subprocess模块的说明是:

The subprocess module allows you to spawn new processes , connect to their input/output/error pipes , and obtain their return codes. This module intends to replace several other , older modules and functions , such as: os.system , os.popen.

而在bottle.py中实际使用subprocess的只有第2596行:

p = subprocess.Popen(args , env=environ)

注释掉下列行,并加上新的sys.exit():

sys.exit(0)
#p = subprocess.Popen(args , env=environ)
#while p.poll() is None: # Busy wait...
#    os.utime(lockfile , None) # I am alive!
#    time.sleep(interval)
#if p.poll() != 3:
#    if os.path.exists(lockfile): os.unlink(lockfile)
#    sys.exit(p.poll())

同时别忘了注释掉import subprocess。

$ git commit -am 'Modify bottle.py to comment subprocess.'
$ saecloud deploy
$ lynx http://4.che123.sinaapp.com/

访问正常,问题解决了。

web2py 1.99.7中无法通过DAL连接MySQL数据库的问题

问题描述

根据在Ubuntu 10.04下配置MySQL数据库(完整版)一文的介绍,完成了MySQL数据库的配置,在客户端访问正常。

然后在web2py应用中通过DAL访问这个MySQL数据库时却碰到了问题:

Traceback (most recent call last): File “/home/www-data/web2py/gluon/restricted.py”, line 205, in restricted exec ccode in environment File “/home/www-data/web2py/applications/mianshi/models/db.py”, line 11, in db = DAL(‘mysql://chinakr:temp_pwd@localhost:3366/saedb’) File “/home/www-data/web2py/gluon/dal.py”, line 5968, in init raise RuntimeError, “Failure to connect, tried %d times:\n%s” % (attempts, tb) RuntimeError: Failure to connect, tried 5 times: Traceback (most recent call last): File “/home/www-data/web2py/gluon/dal.py”, line 5955, in init self._adapter = ADAPTERSself._dbname File “/home/www-data/web2py/gluon/dal.py”, line 1886, in initself.pool_connection(connect) File “/home/www-data/web2py/gluon/dal.py”, line 465, in pool_connection self.connection = f() File “/home/www-data/web2py/gluon/dal.py”, line 1885, in connect return self.driver.connect(**driver_args) File “/home/www-data/web2py/gluon/contrib/pymysql/init.py”, line 93, in Connect return Connection(*args, **kwargs) File “/home/www-data/web2py/gluon/contrib/pymysql/connections.py”, line 513, ininit self._connect() File “/home/www-data/web2py/gluon/contrib/pymysql/connections.py”, line 669, in _connect raise OperationalError(2003, “Can’t connect to MySQL server on %r (%d)” % (self.host, e.args[0])) OperationalError: (2003, “Can’t connect to MySQL server on ‘localhost’ (111)”)

也就是在web2py中通过DAL连接MySQL数据库失败。

问题分析

直接Google错误提示没有发现相关资料。

跟踪报错的web2py源代码:

$ vim /home/www-data/web2py/gluon/contrib/pymysql/connetctions.py 

第668和669行:

 except socket.error, e: raise OperationalError(2003, "Can't connect to MySQL server on %r (%d)" % (self.host, e.args[0])) 

也就是说,这个数据库无法连接的错误实际上是MySQL的Socket错误引起的。

解决问题

第一次尝试失败

在MySQL数据库服务器上:

$ sudo vim /etc/mysql/my.cnf [mysqld] socket = /tmp/mysql.sock 

重启MySQL服务器:

$ sudo service mysql restart 

注:根据后文叙述,这一步应该不是必须的。

问题终于解决了

根据Can’t connect to MySQL server on ‘localhost’中Kevin Ivarsen的描述:

MySQL can communicate over either TCP or a named pipe. It’s possible that your MySQL server is only listening on the named pipe. I could imagine that the mysql command line client would connect successfully over this channel, but Python would try to connect to the TCP socket and fail.

Try telnetting to the local mysql port and see what happens:

telnet localhost 3306

If you get an error like “connection refused”, then this is almost certainly the problem. Take a look at your mysql config file (/etc/mysql/my.cnf or similar) and look for the bind-address or skip-networking settings.

修改MySQL的端口绑定:

$ sudo vim /etc/mysql/my.cnf 

有两种修改方式:

  1. 只允许本地访问

“`

[mysqld] bind-address = 127.0.0.1 #bind-address = 211.147.217.171 

“`

  1. 允许本地和远程访问

“`

[mysqld] #bind-address = 127.0.0.1 #bind-address = 211.147.217.171 

“`

重启MySQL服务器:

$ sudo service mysql restart 

问题解决!

参考资料

在Ubuntu 10.04下配置MySQL数据库(完整版)

目标设定

在服务器上创建指定端口和用户权限的MySQL数据库。

这里,我们设定:

  • 数据库服务器IP:211.147.217.171
  • 数据库访问端口:3366
  • 数据库名称:saedb
  • 用户名:chinakr
  • 密码:temp_pwd
  • 权限:saedb数据库的全部权限,不限制IP

安装MySQL数据库

$ sudo aptitude install mysql-server mysql-client phpmyadmin 

注:安装过程中会提示输入MySQL数据库的root用户的密码。

如果需要重新设置root用户的密码:

$ sudo dpkg-reconfigure mysql-server-5.1 

注:重设密码后会重启MySQL数据库,重启的时间可能会比较长。

测试MySQL数据库连接

$ mysql -u root -p mysql> exit 

注:这里会提示数据MySQL数据库的root用户的密码。

修改MySQL数据库的默认端口

把端口由默认的3306改为3366:

$ sudo vim /etc/mysql/my.cnf [mysqld] port = 3366 

重启MySQL数据库:

$ sudo service mysql restart 

注:数据库重启的时间可能会比较长。

创建数据库、用户,配置权限

创建数据库saedb:

$ mysql -u root -p mysql> CREATE DATABASE saedb; 

创建用户chinakr:

mysql> CREATE USER 'chinakr'@'%' IDENTIFIED BY 'temp_pwd'; 

赋予用户数据库的全部权限:

mysql> GRANT ALL PRIVILEGES ON saedb.* TO 'chinakr'@'%'; mysql> exit 

测试刚才创建的数据库和用户:

mysql> mysql -u chinakr -p mysql> USE saedb; mysql> CREATE TABLE helloword (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20), content TEXT); mysql> INSERT INTO helloword (name, content) VALUE ('chinakr', 'Hi, everyone!'); mysql> SELECT * FROM helloword; 

在客户端访问远程MySQL数据库

现在我们从MySQL数据库所在的服务器退出,返回本地桌面。

$ mysql -u chinakr -p -h 211.147.217.171 -P 3366 saedb 

到这里,整个配置工作就完成了。 接下来,我们可以在Web应用中访问MySQL数据库了!

参考资料