sqlalchemy utf8 quickstart

先把mysql全都配成utf8,比较坑爹的是table charset貌似没法指定默认utf-8,必须create的时候指定

[client]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8

验证一下:

SHOW VARIABLES LIKE ‘character_set_%’;
SHOW VARIABLES LIKE ‘collation_%’;
# -*- coding: utf-8 -*-
import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, BigInteger,String,Text
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
class Node(Base):
    __tablename__ = 'node'
    __table_args__ = {'mysql_engine':'InnoDB','mysql_charset':'utf8'}
    id = Column(Integer, primary_key=True)
    path = Column(String(255), index=True)
    name = Column(String(255))
    data = Column(Text)
    datatype = Column(String(255))

if __name__ == '__main__':
    engine = sqlalchemy.create_engine('mysql+mysqldb://root:123456@127.0.0.1:3306/dbname?charset=utf8', echo=True)

    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine) 

    Session = sessionmaker()
    Session.configure(bind=engine)
    session = Session()
    session.commit()

    n = Node()
    n.path = "/"
    n.name = "汉字"

    session.add(n)
    session.commit()

__table_args__指定了表编码,这样就可以很好支持中文了⋯ 如果有能在mysql配置里指定编码的方法请留言⋯

nginx配置geoip

按照http://wiki.nginx.org/HttpGeoIPModule就可以了

有一个坑,就是

http {
geoip_country /path/to/GeoIP.dat; #这里一定要写绝对路径
geoip_city /path/to/GeoLiteCity.dat;

查了一下手册,好像没有$nginx_home这样的变量,所以需要写死?..

总结一下:
1.先安装依赖libgeoip-dev
2.去下载需要的ip库http://geolite.maxmind.com/download/geoip/database/
3.重新编译nginx
4.修改nginx配置

python读取arc文件的小脚本

import gzip,re

file = "/arcs/some.arc.gz"

ARC_PATTERN = re.compile("(^.*:[^ ]*)\\s([0-9.]+)\\s(\\d+)\\s(\\S+)\\s(\\d+)$")

def readchunk(fp):
    meta = ARC_PATTERN.match(fp.readline()).groups()
    page = fp.read(long(meta[4])+1)
    return (meta,page)

def main():
    f = gzip.open(file,'rb')
    print readchunk(f)
    print readchunk(f)

if __name__ == '__main__':
    main()

windows下注意加rb,不然会坑。

一个管理ssh tunnel的小脚本

首先在本机跟远程服务器建立信任关系,可以使用这个小脚本。

然后使用这个小脚本来管理ssh tunnel,都放在$HOME/bin下。

用法:

tunnel on
tunnel off

在mac下可以使用脚本来管理链接,这样就不用鼠标去点设置->无线..

alias sock='networksetup -setsocksfirewallproxystate Wi-Fi'
sock on
sock off

两个脚本配合起来使用还是很方便的。

中国特色之APNs connection reset

最近在捣鼓 iPhone Push Notification

基本上就是TLS连一下APNs,但是鉴于TLS连接会受到随机阻断(goo.gl/KCMR8),消息将很难确保一定成功发送。

当APNs收到一条它认为有误的信息时就会立即断开连接,并且放弃后续的所有消息,同时会返回一条消息告诉Povider哪条消息有误。因此我们需要有一个错误恢复机制。

但是在一个TLS连接随时可能被切断的情况下,我们还需要不断恢复TLS连接。如果这时恰好有错误发生,那么我们将无法从APNs获取错误信息,因此也无法进行错误恢复,一部分消息将丢失。实际测试中差不多发送几十到几百条消息时,就会被reset一次,频率还是很高的。

有趣的是我将代码部署到海外服务器的时候,完全没有影响,消息发送速度也要高很多。

解决办法?

如果有条件的话,使用海外服务器来进行你的消息推送, Amazon EC2就是一个不错的选择。结合ssh -D -N,你懂的。

如果没有条件,那么我建议将发送窗口调小点,比如发送100条消息就关闭当前连接,重新与APNs建立连接。这样消息丢失的损失就可以控制在100条以内。当然这么做苹果会很不高兴,苹果官方推荐在一个链接里面尽可能多发送消息以节省资源。

 

入度与出度

前几日QA同学给我们讲代码可测性,提到了一个很好的概念:代码的入度与出度。

入度就是说其他模块调用你的模块的次数,出度就是说你的当前模块调用其他模块的次数。

->  入度 ->  | Module |  -> 出度 ->

简单来说,就是可测性好的模块一定是入度更大,为别的模块提供了丰富的功能,而又很少依赖其他模块。

我们把模块级别拓展到服务级别,这个道理也是一样的。 好的服务一定是提供的丰富的功能及接口,而又没有太复杂的关联关系及服务依赖。

同理,上升到业务级别的时候,如果你的入度更大,很有可能就属于所谓 “核心业务” 那部分。就以amazon云服务为例,amazon把自己的“核心业务”做成公有服务拿出来卖:虚拟化、存储、计算、网络服务,更上层的有消息服务,支付服务等等。 看起来好像这些东西在一个大一点的公司应该都有,前几日的g+上的 “google 工程师大吐槽” 大致的意思就是amazon有的我们都有,为啥人家弄得那么好都可以拿出来卖了而我们却是一团团?

amazon把自己的“核心业务”拿出来晒,在整个业内增加自己的入度,google自然看了着急啊。

代码总是人写的,当具体到一个工程师的时候,这个法则似乎也适用。很多工程师都觉得每天忙到累到不行行,但是却感觉没什么收获,别人对自己的评价也不高呢?为什么只剩苦劳没有功劳呢?

回顾一下自己做的工作,是入度更大,还是出度更大?

那些出度更大的工程师,通常需要经常与各种人沟通,寻求各种帮助,约定各种接口,这通常是一个极消耗精力的过程 —- 比如面对各种异构系统解决自己的问题。

这时候就需要反思了,如何才能增加自己的入度,给别人提供服务?

或许从每一行代码就可以开始增加自己的入度吧:

我的代码是不是可以复用的?

我写的模块是不是可以作为公共库使用?

我目前的业务线是否可以做成公共服务供别人很方便地调用?

我的业务经验是不是可以share的,哪些是对别人有价值的?

….

顺着这个思路,我相信你一定能成为“高入度”的NB工程师。

php中操作大整数…

我又out了.

今天本来打算改写一个python版的tinyurl函数(出处忘了..原作者见谅…),2^32 base62编码以后需要占6个字符,考虑到42亿不是很够,于是改成了2^64占11个字符.

import hashlib
def baseN(num,b):
    return ((num == 0) and  "0" ) or ( baseN(num // b, b).lstrip("0") + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"[num % b])
def hash(url):
    m = hashlib.md5(url)
    s = m.hexdigest()
    num = long(s[:16],16)^long(s[16:32],16)
    return baseN(num,62)
if __name__ =="__main__":
    print hash("http://www.baidu.com/")

发现php里整型只有signed int32,木有long. 搜了一把(google “php long” 第一条结果是 php Integer, FML),官方文档说:

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that’s 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

搞不了,心想那php总得有bigint吧,一查果然有个叫GMP的东东,遂搞之:

function urlhash($url){
	$md5 = md5($url);
	$hmd5 = gmp_init(substr($md5, 0,16),16);
	$lmd5 = gmp_init(substr($md5, 16,32),16);
	return gmp_strval(gmp_xor($hmd5,$lmd5),62);
}
echo urlhash("http://www.baidu.com/");

搞定。以上俩代码均输出:

FFyeAlQajro

屁H屁还真简单啊,啥都有现成的… 挺好,舒心。

无题

咸阳机场都盖T3了

西宝高速也扩建了,路上俩事故,其中一个大货侧翻,横在路中间。

机场大巴涨到60块,汽车站也重建了。

小区老楼基本全都推倒重盖了。

没有一样东西像停留在记忆里的,就像回到了一个陌生的城市。

一段javascript

(function(){
    var aaa = bbb = 1;
})();
console.log(aaa);
console.log(bbb);

猜猜输出是什么?

Read more »

[Dev Tip] MAC修改hosts

在 /private/etc/hosts  .. .. ..