今天手欠本来想 rm -rf _* 结果敲成了 rm -rf _[空格]* 小半天的代码没有了。。。
以后必须
sudo apt-get install trash-cli
alias rm=’trash’
啊啊啊啊啊啊
首先安装twisted 跟 thrift ,这个官方都有文档,注意先装依赖关系就行了
奇怪的是我的thrift-ruby 死活编译不通过,还好我不用ruby,直接–without-ruby就好了
报这个错,不懂ruby,也google不到,烦请大侠们指点迷津:
Making all in rb make[3]: Entering directory `/home/zyanlu/soft/thrift-0.8.0/lib/rb' /usr/local/bin/rake rake aborted! no such file to load -- spec/rake/spectask
装完以后还需要给语言装扩展,我这里是php做客户端 跟py.twisted通信,所以需要编译一下php扩展跟python扩展
php:
cd thrift-0.8.0/lib/php/src/ext/thrift_protocol phpize ./configure --enable-thrift_protocol make make install
然后配置一下extension=thrift_protocol.so 就可以了
注意要使扩展起作用的话必须使用TBinaryProtocolAccelerated,这个官方tutorial例子里没有
python 装就比较简单了,直接就好使
cd thrift-0.8.0/lib/py py setup.py build py setup.py install
现在我们来跑一个demo来看看,python的官网tutorial里直接可以跑通
cd thrift-0.8.0/tutorial thrift -r --gen py tutorial.thrift thrift -r --gen py:twisted tutorial.thrift thrift -r --gen php tutorial.thrift
turial里的PhpClient.php 不能直接运行成功,是include的路径不对(看一下源码跟生成的代码就行了)
把php-gen/* 拷贝到 thrift-0.8.0/lib/php/src/packages
帖一下我的PhpClient.php
$GLOBALS['THRIFT_ROOT'] = '../../lib/php/src';
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';
#require_once $GLOBALS['THRIFT_ROOT'].'/transport/THttpClient.php';
#require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'].'/transport/TFramedTransport.php';
/**
* Suppress errors in here, which happen because we have not installed into
* $GLOBALS['THRIFT_ROOT'].'/packages/tutorial' like we are supposed to!
*
* Normally we would only have to include Calculator.php which would properly
* include the other files from their packages/ folder locations, but we
* include everything here due to the bogus path setup.
*/
// error_reporting(0);
$GEN_DIR = $GLOBALS['THRIFT_ROOT'].'/packages';
require_once $GEN_DIR.'/shared/SharedService.php';
require_once $GEN_DIR.'/shared/shared_types.php';
require_once $GEN_DIR.'/tutorial/Calculator.php';
require_once $GEN_DIR.'/tutorial/tutorial_types.php';
error_reporting(E_ALL);
//try {
if (array_search('--http', $argv)) {
$socket = new THttpClient('localhost', 8080, '/php/PhpServer.php');
} else {
$socket = new TSocket('localhost', 9090);
$socket->setRecvTimeout(2000);
}
$transport = new TFramedTransport($socket);
$protocol = new TBinaryProtocolAccelerated($transport);
$client = new tutorial_CalculatorClient($protocol);
$transport->open();
$client->ping();
print "ping()\n";
$sum = $client->add(1,1);
print "1+1=$sum\n";
$work = new tutorial_Work();
$work->op = Operation::DIVIDE;
$work->num1 = 1;
$work->num2 = 0;
try {
$client->calculate(1, $work);
print "Whoa! We can divide by zero?\n";
} catch (tutorial_InvalidOperation $io) {
print "InvalidOperation: $io->why\n";
}
$work->op = Operation::SUBTRACT;
$work->num1 = 15;
$work->num2 = 10;
$diff = $client->calculate(1, $work);
print "15-10=$diff\n";
$log = $client->getStruct(1);
print "Log: $log->value\n";
$transport->close();
大功告成,后续测试一下性能是不是有宣传的那么给力
ubuntu server的好处是体积小,很快就能下好装上,但是开发常用的包都木有。(我是os x里弄了个linux vm来开发⋯ air的硬盘太小了…)
以下列表,不断更新中⋯⋯
apt-get install zlib1g-dev apt-get install gcc apt-get install dpkg-dev apt-get install libssl-dev apt-get install libxml2-dev apt-get install libxslt-dev apt-get install ntp apt-get install libpcre3 libpcre3-dev apt-get install libreadline5-dev apt-get install exuberant-ctags apt-get install mysql-client libmysqlclient-dev apt-get install libbz2-dev apt-get install zlib1g-dev apt-get install libjpeg62-dev apt-get install libfreetype6-dev apt-get install liblcms1-dev apt-get install libcurl3-dev
下面这段小程序是否输出true呢?
public long countRectangles(int width, int height){
long x = (width*(width+1)/2)
* (height*(height+1)/2);
long a1 = (width*(width+1)/2);
long a2 = (height*(height+1)/2);
System.out.println(x == (a1*a2));
}
public static void main(String[] args) {
new RectangularGrid().countRectangles(592, 964);
}
结果坑爹了,打印出来x只有38960016,一看就是溢出了⋯
问题就在于 long = int*int的效果等同于long = (long)(int*int)
int*int返回值仍旧是int,所以修改成为long = (long)int*(long)int 就可以了。
这个其实是个很基础的问题,但是有时候敲代码一不留神还是很容易写错。
先把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配置里指定编码的方法请留言⋯
按照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配置
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,不然会坑。
最近在捣鼓 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工程师。