最后更新于 .

在很早的时候,就听网上的文章说:

python有GIL,所以在单进程内,即使使用多线程也无法利用到多核的优势,同一时刻,python的字节码只会运行在一个cpu上。

以前也是奉为真理,直到今天在对自己的python server做性能测试的时候,发现一个python进程的cpu居然达到了120%。

当用c++编程的时候,如果使用多线程,那么确实进程cpu超过100%非常正常,但是对python来说,似乎这样就和网上的文章冲突了。

所以还是决定自己亲身试验一下,编写代码如下:

from thread import start_new_thread

def worker():
    while 1:
        #print 1
        pass

for it in range(0, 15):
    start_new_thread(worker, ())


raw_input()

 

运行环境为: centos6.4 64位, python 2.7.

得到的结果如下:

E588C2D7 1608 42CC B800 AD5338C87F47

可以清楚的看到,pid为31199的python进程cpu达到了787.9%,接近理论能达到的最大值 800%。

而上方的8个cpu也分别达到了近100 ...

最后更新于 .

最近在做游戏服务分层的时候,一直想把mysql的访问独立成一个单独的服务DBGate,原因如下:

  1. 请求收拢到DBGate,可以使DBGate变为无状态的,方便横向扩展
  2. 当请求量或者存储量变大时,mysql需要做分库分表,DBGate可以内部直接处理,外界无感知
  3. 通过restful限制对数据请求的形式,仅支持简单的get/post/patch/put 进行增删改查,并不支持复杂查询。这个也是和游戏业务的特性有关,如果网站等需要复杂查询的业务,对此并不适合
  4. DBGate使用多进程模式,方便控制与mysql之间的链接数,进行mysql访问量阀值保护
  5. 方便在DBGate上进行访问量统计,慢查询统计、权限控制等等一系列逻辑
  6. 目前是使用python,以后要使用其他语言进行mysql操作时,只要进行标准的http请求即可,不会出现不兼容的情况

当然坏处也是有的:

  1. 首当其冲就是单次请求的响应时间变长,毕竟中间加了一层服务,并且还是http格式
  2. 部署上比原来复杂了一些,很多对mysql直接操作的思维需要进行转变,一开始可能会有些不适

不过总的来说,还是利大于弊,所以最终还是决定搭建DBGate

当然,我们不可能去手工挨个写每个库表对应的restful服务,值得庆幸的是django和flask都提供了对应的解决方案,我们一个个介绍.

Flask

参考链接: flask-restless

flask-restless使用方法比较简单,我直接贴一下代码即可:

# -*- coding: utf-8 -*-

import datetime
from flask ...

最后更新于 .

最近在调整游戏的后台架构,之前因为需要快速出产品,所以整个代码都揉成一团,也基本没有做任何分层处理。现在服务器端的开发也开始逐渐招进来,所以打算打算换一套统一的架构,以后做新游戏只要做其中的业务逻辑即可。

其实之前在腾讯的时候,基本不会用到message queue这种,所有的分布式处理都是由自己写c++ server来互相通信的。这样的处理虽然开发量稍微大一点,但是性能和灵活性确实很高。

现在自己在外面做,虽然自己已经封装了一套server的框架出来,但是毕竟还有太多的轮子需要自己制造,所以就想到了之前一直有了解过celery,来看一下这种基于message queue的任务系统能达到什么性能。

RabbitMQ

celery首推的mq是rabbitmq,所以需要先安装一下:

在mac下用brew 安装:

brew install rabbitmq

安装成功之后,即可启动server了。

不过在这之前,我们先把后台管理的插件打开:

rabbitmq-plugins enable rabbitmq_management

之后执行如下命令,启动server:

rabbitmq-server

这个时候就可以通过 http://127.0.0.1:15672/ 来访问后台管理端了,默认的用户名和密码是guest guest,可以自己在页面上修改。截图如下:

NewImage

 

Redis

celery也支持redis作为broker和backend,所以redis也需要安装一下 ...

最后更新于 .

测了一下django、flask、bottle、tornado 框架本身最简单的性能。对django的性能完全无语了。

django、flask、bottle 均使用gunicorn+gevent启动,单进程,并且关闭DEBUG,请求均只返回一个字符串ok。

tornado直接自己启动,其他内容一致。

测试软件为 siege,测试os为cenos6 64位,测试命令为:

siege -c 100 -r 100 -b http://127.0.0.1:5000/

django测试结果为:

Transactions:		       10000 hits
Availability:		      100.00 %
Elapsed time:		       18.51 secs
Data transferred:	        0.02 MB
Response time:		        0.18 secs ...

最后更新于 .

上一篇文章聊了下数据存储和常用的传输协议,不过对于自定义传输协议这里留了个坑,正好有点时间,就抓紧填上:)

既然选择原生socket,那么有个基本的选择就是tcp/udp的问题.

这个其实还是看业务自己的选择,只是如果选择了udp的话,那么很多问题都可以不用考虑,比如粘包问题。但是udp有个限制是每次传输的数据大小不能超过64K,这个要注意。

为了考虑复杂的情况,我们还是主要说tcp的实现,这篇文章先说下socket使用相关的一些库和代码吧

Android端开发

对于android端,我们有两个主要选择:阻塞socket和非阻塞socket。

阻塞socket就是正常的socket,当调用recv的时候,会阻塞住直到返回数据。

非阻塞socket在android上可以直接使用nio,因为自己之前一直是做c++和python,所以其实一开始nio的时候真心有些不太使用,把几个要注意的点列一下:

1. 当网络断线的时候,有些手机如S4,会出现这个问题,channel.finishConnect()会一直等超时 60秒。之后会抛出一个 TimeoutException.

解决方法是:

channel.socket().setSoTimeout(5)

来设置成只等5秒。

比较诡异的是,明明是异步io了,为什么还是会有等待超时的情况。还要在研究下。

2. 当网络不在线的时候,启动connect,依然可以进入isConnectable的判断中,并且可以调用finishconnect。

解决方案:finishConnect之后 ...

最后更新于 .

经过这么久在android客户端和服务器端的开发,感觉还是积累了不少东西想要和大家分享一下,但是好想单独拎一个点出来又不太值得,所以就汇集到一起写成系列吧。

一. 关于用户数据存储

首先在注册的协议里,定义如下公共传输字段:

version: 这个其实是xml中配置的versionCode。versionName个人认为没有什么必要,所以就不传了。

channel:  用户渠道,这个和xml中的UMENG_CHANNEL 是共用的,因为一直在使用umeng,所以这样定义反而清楚一些。

device_id: 设备ID

os: 操作系统类型,这里默认传入android

os_version: 操作系统版本

对于小数据量,用户数据存储在mysql中是相对较好的选择,这里直接以django的model为例:

from django.db import models
class User(models.Model):
    device_id = models.CharField(max_length=255, null=True, blank=True)
    version = models.IntegerField()
    channel = models.CharField(max_length=64, null ...

最后更新于 .

12年的时候入了macbook pro,之后就一直用到现在,只是一直把机械硬盘当作ssd用,盖了盖子直接就带着到处跑,结果最近就给杯具了。

文章可能写的比较散,我就给分成几节吧

一. 发现问题

现象倒是比较常见,死机频繁,并且开chrome一直chrome内核的ide必然死机。一开始以为是10.9系统的问题,后来想来想估计是内存或者硬盘的问题。

在网上下了个神器:TechTool

大家如果对自己的硬盘不放心也可以去检测一下~ 检测的结果:

SMART检查失败 硬盘存在不可修复的硬件问题,请更换硬盘

得,这直接判了死刑了。

赶紧去网上买了块硬盘,以及一个硬盘盒。

又从朋友那边接了拆mac的专用螺丝刀盒。

为了保险起见,从朋友那里借了个移动硬盘,把所有数据备份了一下。

二. 制作系统

话说因为买mac的时候并没有赠送系统盘之类的东西,所以去网上淘了一下,比较庆幸已经有人做好了: Mac OS X 10.9 Mavericks U盘复刻版,将其导出为U盘即可。

导出为u盘的方法也简单说下:

  • 准备一个8G的U盘
  • 执行系统自带的磁盘工具,将下载的DMG恢复到准备的U盘上
  • 喝杯咖啡,等半个小时,搞定

三. 更换硬盘,安装系统

拆硬盘还是比较简单的 ...

最后更新于 .

终于把博客成功迁移到阿里云上了,怎么样,感觉速度快多了吧?

其实自己与阿里云结下缘分也近3年了,可以说看着阿里云一步步变好,所以也才最后决定把自己所有的服务都迁移到了阿里云服务器上,包括自己的应用服务器、游戏服务器、乃至最后自己的博客。

话说阿里云给每个老客户貌似都分配了专门的客户经理,这个感觉还是很爽的,哈哈。

好了,算是免费给阿里云打个广告,接下来说说迁移的事情。

wordpress的迁移对于程序员来说是很简单的,无非是搭建个php环境,迁移一下mysql的数据就可以了。

具体使用的各组件如下:

nginx
supervisor
php
mysql

 

nginx的配置很多网上写的都不太对,所以这里贴出来给大家:

    server {
        listen       80;
        server_name  vimer.cn *.vimer.cn;
    
        root         /data/release/vimer;
		
		# 客户端上传大小
        client_max_body_size 20m;
        
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
    
        location / {
            index index.php index.html;
            if (-f $request_filename ...

最后更新于 .

yunbk 是我前段时间用python写的一个备份插件,取中文谐音云备份的意思,你可以很方便的用这个插件来备份mysql、redis、mongodb、乃至各种media目录,等等。 安装可以直接用pip执行:

pip install yunbk

github地址如下:

https://github.com/dantezhu/yunbk

而用法也非常简单,比如要备份mysql,则代码如下:

from yunbk import YunBK
from yunbk.backend.local import LocalBackend

import sh

backend = LocalBackend('/data/backup')

with YunBK('mysql', [backend]) as ybk:
    sh.mysqldump(u='root',
                 all_databases=True,
                 _out="dump.sql")
    ybk.backup ...

最后更新于 .

之前的博客主题应该是自打博客成立就一直没换了,最近不知道怎么突然有心情,就把博客重新调整了一下。 主要有以下几个方面:

一. 将主题换成了zanblog,基于bootstrap3。

换之前特意让媳妇看了一下,在肯定了自己的审美观没有问题之后,就给换啦 之后可以在代码中使用bootstrap的标签实现一些特殊的效果,如:

这是成功背景框

引用的写法:

这是我引用的

当然,带来的影响就是不兼容ie8一下的浏览器了。不过想了下,搞技术还能忍受ie6、7那拖慢的速度的话,那也算太有耐心了。。

二. 将代码配色插件从WP-Syntax换成了 Crayon Syntax Highlighter

WP-Syntax虽然功能上没什么问题,但是展示的效果实在是太差了。所以这次果断换成了 Crayon Syntax Highlighter,效果如下

def show_name():
    print 'vimer.cn'

三. 重新启用了多说评论插件

关于这一点其实挺纠结的,因为之前用过一次,之后因为有些朋友不太喜欢社交登录而放弃了,所以这次特意把匿名留言也同样保留着。 而至于想要换成多说的最大原因,在于zanblog默认的配色是和多说非常搭配的。。而wordpress默认的评论展示奇丑无比。。

四. 修正了某些文章的图片404

之前某年做数据迁移的时候,被人搞丢了好多中文名字的图片,当时没有太在意,后来一直不停的有博友反馈,因为时间有限也就没有顾得上。 这次把很多图片找了回来 ...