Supervisor 简介

参考文献列表:
http://supervisord.org/

Supervisor 被用于在类 Unix 系统上进行进程控制,进程被 Supervisor 以子进程的形式启动。这里列举一些 Supervisor 的特点:

  1. 可以配置被 Supervisor 管理的进程在崩溃后自动重启
  2. Supervisor 能够准确的获知管理的进程的 up/down 状态
  3. Supervisor 能够按一定顺序开启和关闭一组进程

安装 Supervisor

如果你使用的 Python 解释器安装了 Setuptools 并且可以访问因特网,那么可以使用 easy_install 来安装 Supervisor:

easy_install supervisor

安装完成 Supervisor 就需要生成配置文件(这里生成在当前目录下): […]

Golang 程序调优

本文为以下文章的读书笔记:
http://blog.golang.org/profiling-go-programs
https://golang.org/pkg/runtime/pprof

CPU Profiling

Golang 提供了 pprof 包(runtime/pprof)用于输出运行时的 profiling 数据,这些数据可以被 pprof 工具(或者 go tool pprof,其为 pprof 的变种)使用。通常我们这样来使用 pprof 包:

// 定义 flag cpuprofile
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {
    flag.Parse()

    // 如果命令行设置了 cpuprofile
    if *cpuprofile != "" {
        // 根据命令行指定文件名创建 profile 文件
        f, err := os.Create(*cpuprofile)
        if err != nil {
            log.Fatal(err)
[…]

Golang MongoDB 驱动 mgo 的若干问题

mgoMongoDB 的 Golang 驱动。

连接池

我们通过 Dial 函数创建一个新的 session:

session, err := mgo.Dial(url)

创建的 session 能够和 MongoDB 集群中的所有服务器通讯。需要注意的是,对于一个集群只需要调用一次 Dial,通过此 Dial 返回的 session 的 NewCopy 方法能够创建更多的 session 出来,这些 session 共用底层的连接池(Dial 创建的多个 session 之间使用不同的连接池)。

更为具体的来看下 Strong session(Strong 为一种一致性模式,这里讨论 Strong session 是因为其相对简单,详见下文)。一个 Strong session […]

MongoDB 简介

参考文献列表:
http://docs.mongodb.org/manual/

安装 MongoDB

http://docs.mongodb.org/manual/installation/

MongoDB 简介

MongoDB 是一个开源的文档数据库(document database),一个文档一条记录。MongoDB 的一个文档类似于 JSON(实际上为 BSON)的一个对象:

{
    name: "name5566",
    db: ["mongodb", "mysql"]
}

集合(collection)包含了一组文档,一个集合类似于关系型数据库中的一张表。

安装好 MongoDB 后,我们可以使用 mongo 命令。mongo 提供了一个完整的 JavaScript 环境(可以执行 JavaScript 代码)。执行 mongo 会默认连接 localhost […]

Golang 和 JSON

参考文献列表:
http://blog.golang.org/json-and-go

Golang 提供了 json 包来处理 JSON 相关内容。

编码为 JSON

编码为 JSON 数据使用 Marshal 函数:

func Marshal(v interface{}) ([]byte, error)

看一个具体的例子:

package main

import (
    "encoding/json"
    "fmt"
)

type Message struct {
    Name string
    Body string
    Time int64
}

func main() {
    m := Message{"Alice", "Hello", 1294706395881547000}
    b, err := json.Marshal(m)
    if err != nil {
        return
    }

    fmt.Println(string(b))
}

此程序输出:

{"Name":"Alice","Body":"Hello","Time":1294706395881547000}

需要注意的是,Marshal 函数的返回值为 []byte。

Golang 数据结构编码为 JSON: […]

Golang 的 panic、recover

参考文献列表:
http://blog.golang.org/defer-panic-and-recover

panic 是一个内置函数,当一个函数 F 调用 panic,F 的执行就会停止,F 中 deferred 函数调用会被执行,然后 F 返回控制到它的调用者。这个过程会沿着调用栈执行下去,直到当前 goroutine 中的所有函数返回,然后程序 crash。出现 panic 是因为:

  1. 调用了 panic 函数
  2. 出现了运行时错误(例如,数组越界访问)

recover 是一个内置函数,用于恢复一个 panicking goroutine 的控制。需要注意的是,recover 只能使用在 deferred 函数中。如果当前的 […]

了解 Golang 的 interface

参考文献列表:
http://blog.golang.org/laws-of-reflection

类型和接口

Golang 是静态类型的,每一个变量都有一个静态类型:

type MyInt int

var i int
var j MyInt

这里的 i 静态类型为 int,j 静态类型为 MyInt,它们的静态类型不同,但是有相同的底层类型(underlying type)int。

接口类型是很重要的类型,表示了固定的方法集。一个接口类型变量能够存储实现了此接口所有方法的值。我们看一个例子:

var r io.Reader
r = os.Stdin
r = bufio.NewReader(r)
r = new(bytes.Buffer)
// and so on

io.Reader 为一个接口,无论变量 r 持有了什么样的值,r […]

史玉柱在游戏策划上的一些经验

本文内容主要来自《史玉柱自述:我的营销心得

史玉柱策划的经验主要集中在 MMORPG 类。

网络游戏最重要的是游戏性。

玩家的需求

玩家对游戏是有需求的,并且需求还不少,但最重要的需求有几个:

  1. 荣耀。荣耀是最重要的需求(没有之一),荣耀是其他人给予的。一般来说,谈到荣耀,想到的是大号,而忽略了小号的荣耀,如果重视小号的荣耀,对在线人数有很大的帮助。任何的功能都要过荣耀关
  2. 目标。目标分为短、中、长期目标。短期目标可能需要花费几分钟、几小时来完成,中期目标可能需要花费几小时、一整天来完成。对于玩家来说,在任何一个时间节点上,都应该同时有短、中、长期三种目标存在。玩家感觉无事可做,就是玩家没有目标了。策划为玩家设定的目标不一定就会被玩家接受,玩家不接受的目标就不是玩家的目标(策划要通过各种方式了解玩家的需求,不要设定玩家不需要的目标)。为玩家设计目标时,首先需要给玩家制造压力,压力能够体现目标的价值,然后根据目标的价值确定玩家努力的时间,最后目标达成后,让玩家多体验目标的价值。特别需要注意的是,玩家达成目标后会有一段时间的失落感,因此需要在目标达成之前就确立新的目标。什么时候设目标(告诉他你可以做什么),什么时候给价值(通过压力),多久可以完成,这些可以使用黑点图来管理
[…]

在 Golang 中使用 C 代码

参考文献列表:
http://golang.org/cmd/cgo/

cgo 使得在 Golang 中可以使用 C 代码。

Hello World

为了有一个较为直观的了解,我们来看一个简单的例子,创建文件 main.go:

package main

/*
#include <stdio.h>

void sayHi() {
    printf("Hi");
}
*/
import "C"

func main() {
    C.sayHi()
}

执行程序:

go run main.go

程序执行并输出 hi(更多的范例可以见 $GOROOT/misc/cgo)。我们可以使用命令:

go build -x main.go

来显示构建时的命令。

Windows 下的准备工作

如果想要在 Windows 上使用 cgo,那么需要安装 gcc 编译器,这里我使用 mingw-w64,可以在这里 […]

在 Golang 中使用 Protobuf

https://github.com/golang/protobuf 项目为 Golang 提供了 Protobuf 的支持。

安装 goprotobuf

  1. https://github.com/google/protobuf/releases 获取 Protobuf 编译器 protoc(可下载到 Windows 下的二进制版本)
  2. 获取 goprotobuf 提供的 Protobuf 编译器插件 protoc-gen-go(被放置于 $GOPATH/bin 下,$GOPATH/bin 应该被加入 PATH 环境变量,以便 protoc 能够找到 protoc-gen-go)
    go get github.com/golang/protobuf/protoc-gen-go
    

    此插件被 protoc 使用,用于编译 .proto 文件为 Golang 源文件,通过此源文件可以使用定义在 .proto 文件中的消息。

  3. 获取 goprotobuf 提供的支持库,包含诸如编码(marshaling)、解码(unmarshaling)等功能
[…]

Linux 下安装和配置 VPN(Virtual Private Network)

了解 VPN

VPN 是 Virtual Private Network(虚拟私有网络)的缩写。所谓私有网络指的是使用私有 IP 地址空间的网络,例如企业内部建立的局域网。有些时候,我们需要通过公有网络(public network,例如 Internet)来建立私有网络,这种私有网络也就是 VPN。我们常见的 PPTP(Point-to-Point Tunneling Protocol)就是实现 VPN 的一种协议。PPTP 使用 PPP(Point-to-Point Protocol)来对数据包加密和验证,而 PPTP 本身主要用于为 PPP 提供路由支持。PPTP 不够安全,但是相关安装和配置很简单,你可以根据具体需要来选择使用 […]

Golang 极简指南(4)— 编码

参考文献列表:
http://golang.org/doc/code.html

workspace

Golang 的代码必须放置在一个 workspace 中。一个 workspace 是一个目录,此目录中包含几个子目录:

  1. src 目录。包含源文件,源文件被组织为包(一个目录一个包)
  2. pkg 目录。包含包目标文件(package objects)
  3. bin 目录。包含可执行的命令

包源文件(package source)被编译为包目标文件(package object),命令源文件(command source)被编译为可执行命令(command executable)。使用 go 命令进行构建生成的包目标文件位于 pkg 目录中,生成的可执行命令位于 […]

关于能力

我认为人最关键的能力有两个:

  1. 解决问题的能力
  2. 与人合作的能力

生活中充满了各种各样的问题。解决问题才能够推进事物的发展。

一个人能够解决的问题是有限的,主要是由于个人的能力和精力是受限的,所以与人合作就显得至关重要。有效的合作可能是基于能力互补的,也可能是弥补精力不足的,或者两者兼有之。 […]

Golang 极简指南(3)— 并发支持

参考文献列表:
http://tour.golang.org/

Golang 运行时(runtime)管理了一种轻量级线程,被叫做 goroutine。创建数十万级的 goroutine 是没有问题的。范例:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    // 开启一个 goroutine 执行 say 函数
    go say("world")
    say("hello")
}

我们使用 channel 和 goroutine 通讯。channel 中是一种带有类型的通道,被用于接收和发送特定类型的值。操作符 <- 被叫做 channel 操作符(这个操作符中箭头表明了值的流向):

// 发送
[…]