归档 2014

最后更新于 .

这几天的心情非常好,主要原因是我们把服务器端的架构升级到了 2.0,这样最大的一个好处就是:

Server重启完全不会影响外网服务

所以,也是想趁此机会,服务器端整个发展的历程,跟大家分享一下,干货比较多,框架代码也会全部开源:)

 

一. 农业时代

创业最重要的就是一个“快”字,所以最开始的时候,所有的架构都以快速出模型为前提。

而常看我博客的朋友应该知道我对python情有独钟,所以自然的,python成为了我开发服务端框架的语言。

python自带的多线程tcp服务器框架非常简单:ThreadingTCPServer,即每个链接一个线程的模式:

import SocketServer

class RequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        f = self.request.makefile('r')

        while True:
            message = f.readline()
            if not message:
                print 'client closed'
                break
            print "message, len: %s, content ...

最后更新于 .

还是继续聊创业的话题,发现关于创业,的确可以聊的东西太多了。

今天主要聊聊招人和培养的事情。

一.一分钱一分货

之前一直在招聘上蛮控制成本的,招进来的人能力都比较差,甚至很多都是毕业生。导致团队内无论是开发进度、质量都十分的差,而由于员工的心理成熟度和职业化程度不够的原因,从而导致一系列管理成本的提升,如离职、负能量传递、情绪不稳、责任感不强等。

所以最后算下来,我发现,看起来在省钱的事情,其实最后都是在赔钱。

其实解决这个问题的方法很简单,简单到和个人处事的方式一样:不要妄想占便宜。

一分钱一分货,不要指望物美价廉,更多的时候,必要的付出是完全值得的。

所以后来,客户端这边我们招了一个能力蛮强的人进来,结果发现客户端这边的架构搭建、任务分配跟踪等,我都不用像以前那么操心了,而且开发进度和质量也比之前好了几个数量级。

二. 对应的人,对应的事,对应的钱

前面提到了牛人在团队里的作用,那是不是就该尽量多的招牛人呢?

未必,毕竟创业除了理想,还是得脚踏实地现实点,而这个现实就是你有多少钱?

遇到一个牛人,愿意接受创业公司那点薪水,又能和你志同道合一起为渺茫的理想拼搏,这本身已经是一件可遇不求的事情了。

所以如果一旦出现一个就该牢牢抓住,别让他跑了。

但是大多数情况下,我们只能在简历库里搜索一份份平淡无奇的简历,从中筛选出你想要的那些人。

所以,更多时候 ...

最后更新于 .

敲上了这个标题,还是理不清自己想写下什么。
其实我只是想真实记录下自己创业路上的感受,前面三篇可能更系统些,毕竟带有总结的性质。而这篇可能就更随性一些。

公司从成立开始就不停的有人离职,自己也已经开掉两个人了。
无论是被员工炒还是炒掉员工,感受都不是那么好。

一开始收到辞职申请的时候,自己还是蛮难受的,尤其是那个人可能还是你想培养的人的时候。
但是慢慢的,也就习惯了。

本来就表现不好的,当天提了离职,当天就让他交接完事情,第二天就走。表现好一些的,示程度一起聊聊天,挽留一下。

但是挽留基本也都是没啥用的,反正目前在我这还没有成功过一个。

其实我始终认为离职,就跟男女分手一样:分手的原因一点都不重要,重要的是结果。

所以基本上离职我都会问一下,对公司有什么看法,也许离职唯一的用处就是可以让我能够清晰的听到他们对公司真实的看法,来杜绝之后类似事情的发生。

这几天连续处理了几个离职的事情,乃至于今天又听到离职申请的时候,我都已经不想再谈理想,谈职业规划,谈收益。
但接下来我还是和他聊了两三个小时,因为这个就属于我认为重要的那部分员工。

员工和老板也许真的很难站在对方的角度上思考。
就像我不能理解:
为什么我允许你上班迟到15分钟,中午有两个小时午休,醒的却还是晚半个小时,但晚上让你加班到10点之后几分钟,就有人吵着说要回去?

员工的角度上只能看到自己的利益,全盘的利益是看不到的。
员工看到那个被我辞掉的员工,会自动把那个人替换成自己,从而同情那名员工,而认为我做的很残忍;但是却看不到因为一块短板的存在,导致整体的进度收到影响,从而影响了他自己最终的收益 ...

最后更新于 .

发现自己经常会一篇文章写了(一)之后,很久都不写(二),搞得最后自己都快要忘记了,所以这次赶紧把统一支付的文章给补上。

上次的文章中将统一支付的v1版本已经讲解ok了,但是还剩下两个问题:

  • 服务器端没有办法做分布式
  • 客户端对支付sdk进行插件式管理十分困难

 

我们一个个来说

一. 解决服务器端分布式的问题

解决这个问题的核心思路比较简单:

之前我们是把event的通知放在进程内存中,现在我们做成网络通信

由于支付的请求量本身不属于高并发,所以就放弃了打算直接写通知server的想法,转而看一下有没有什么简单的解决方案。

而由于自己之前redis的使用经历,恰好知道redis有一个pubsub模式,很适合做这种监听和通知的工作。

python的实现示例代码如下:

import time
import config
from share.vals import rds
from share.utils import safe_str
from gevent.timeout import Timeout
from urllib import quote, unquote

class RedisPubSub(object):
    """
    用redis订阅/发布消息
    """
    # 订阅频道
    sub_key ...

最后更新于 .

其实想跟大家分享这套支付系统的架构已经很久了,今天总算有时间写出来了。

先说说这套系统的需求由来吧:

  1. 笔者公司的游戏产品已经有几款了,每次上各种渠道都是要搭配不同的计费方式,并且每开发游戏都要重复一遍痛苦的接入sdk流程
  2. 游戏的支付需要出各种报表以及统计,每个游戏单独去做对人力的消耗巨大

基于以上几点,我这边设计了统一支付系统。

这个系列一共会分两篇文章,分别对应系统的v1版和v2版,我们这一篇先从v1起介绍。

在仔细分析了国内的大多数支付sdk之后,我们梳理出游戏的支付流程大体可以实现为两类:

  • 第三方sdk服务器进行支付结果通知
  • 第三方sdk客户端直接返回支付结果通知,没有服务器支付结果通知。

对于调用方而言,这两种方式各有好处。

  • 第一种方式更加安全,但是支付调用的时间相对较长
  • 第二种方式速度更快,但是很容易被不怀好意的人破解。参见之前的文章:google支付接口被刷以及解决方案

接下来,我们来看一下我这边设计的统一支付流程。

客户端:

1

服务器端:

2

简单解释一下:

  • 每次支付开始,都要让服务器生成一个订单作为此次支付的记录,订单的id即为 bill_id。订单有4中状态:订单生成,支付失败,支付成功,发货成功。
  • pay_server即为统一支付系统的服务器端,考虑到调用量和方便调试,使用了简单的http协议+json+sign的方式

对于服务器内部,唯一麻烦的一点是,《等待pay_server支付结果通知》这个接口。因为这个http请求需要支持挂起,在第三方支付服务器通知了pay_server之后,pay_server 根据通知里面透传的bill_id 将订单状态修改后,再给客户端结果 ...

最后更新于 .

接着上一篇继续,前面两篇算是把从创业开始发展到今天的整个过程大体说了一遍,但是接下来的文字才是真正我想要和大家分享和探讨的。

这个话题就是:作为一个技术合伙人,职责到底应该是什么?

其实随着公司的发展,我就一直在思考这个问题:一方面是来自于担心公司技术进度失控的不安全感,一方面是来自于自己不再有太多时间编码,而带来的对自身技术能力落伍的担心。

还是按照创业的阶段来说吧。

一、创业第二阶段-队长

这个时候,公司可能就3、4个人,一个产品、一个前端、一个后端。什么技术合伙人、技术总监之类的,没必要在意这个名字,这个时候,唯一的要求就是做出产品。

而这个能力,又分两块:

1. 自己编码的能力

2. 设计架构,主导技术开发的能力

这个时候,更像一个队长。你要带领几个队员,但你自己也要冲锋。

你要能够将产品解构为代码实现,你要熟悉整个产品的研发,无论前端还是后端。

这个阶段,是非常关键的为团队打基础的时间。

在产品的实现过程中,要逐渐规划出自己的技术框架,将底层、公共逻辑拆分出来,为下一个阶段做准备。

而队长,就是要将这些东西,在这个阶段尽快沉淀、积累下来。

举个例子,服务器端语言用什么?python。web框架用什么?django ...

最后更新于 .

接着上一篇文章说吧。

在这之后,差不多快到年底吧,经过朋友的介绍认识了现在的合伙人,做产品策划和运营。之前也只是打电话聊了一下,不能说一见如故吧,但是聊下来之后也是仔细考虑了好几天,才决定是不是要进行这样的合作。
后来当面聊了一次,决定先以比较浅的合作方式试一下,就开发现有产品的某个模块,互相也都彼此磨合一下,如果感觉不错的话就再往下走。

这样差不多搞到年后,终于决定了以技术合伙人的身份进入团队,基本形成了目前创始人团队铁三角的关系。

之后开始招人,当时还在小黑屋内,而且还在烧自己的钱,所以招人的成本和质量控制的都很严格。不过现在想起来,当时的严格对现在的我们还是有很大的好处,当时招的同事承担了当时基本所有客户端的开发,他后来又介绍了一位朋友,也是客户端开发,也很不错,现在两人都是公司的骨干。

当然,说是以技术合伙人身份加入,其实说白了还是写代码,然而现在的自己还是很怀念那时候可以酣畅淋漓写代码的日子的。

当时工作极其的辛苦,每天都在12点之后下班,当时公司一共3个人,后来又找了俩兼职,我基本每天都是12点半开车把大家送到家,然后自己才到家。其实现在想起来那段日子也蛮难为自己媳妇的,基本都见不到几次面。(当然现在晚上也还是很晚,只是比当时12点这种量级还是好一点了)

后来,因为政策上的一些问题,公司产品出了点问题。我们三个合伙人决定引入投资。因为人脉上的关系,这次的投资引入的还是蛮快的。

我们三个一块见了次投资人,其他事情基本就另外两个合伙人在跑了。这里的事情就不细说了。

投资进来之后,公司几个月内的生存暂时不是问题,但是压力也相应而来,毕竟拿了别人的钱 ...

最后更新于 .

算起来,从离开腾讯自己创业已经过去一年半了,其中经历了太多事情,也有太多的东西想要记录和分享给大家,所以开了这个系列,希望能记录下来。

先说一下目前自己处于的状态,因为目前的状态会严重影响我对事情的判断,而很可能一年后的自己看到自己今天写的话会觉得全是扯淡。

目前公司已经拿到投资。公司总共17个人,其中创始人包括我共3个,分别负责渠道、产品、技术。
研发团队分3个组,分别是android、cocos2dx、后端,人数分别是4、3、3;产品 2人;美术1人;渠道1人。
挤在一个130平的房子内,周一至周六都上班,周一~周五都是最早10点下班,周六让大家早点走,6点吧。

研发的进度的话,android来开发一个完整的棋牌游戏在1.5月左右。cocos2dx也是这样一个时间表。
我们后端是用的python,所以开发会很快,一般在一周内就能写出一个可玩的牌桌内逻辑。

现状大体就是这样,先在这临时存个档,一会再读回来。

先从1年半前说起吧。

2013年3月份,自己从腾讯正式离职,当时还处于国内互联网“开放”吵得比较火的时候,而自己手里是有几款能盈利的pc应用的,所以相当于自己给自己发工资,日子过的还不错,也没怎么觉得多有压力。

到4月份,自己其中的一个产品被腾讯下线;再到8月份 ...

最后更新于 .

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

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 ...

每月存档

去年

2013

明年

2015