以Docker为平台部署服务器时,最应该理解透彻的便是网络配置。离上次学习,Docker网络又更新了不少内容,重新温习一下。

通过docker run--network选项可配置容器的网络,Docker提供了多种网络工作模式,none, host, bridge, overlay 等。

none

不为Docker容器进行任何网络配置,容器将不能访问任何外部的路由(容器内部仍然有loopback接口),需要手动为其配置网卡,指定IP等,否则与外部只能通过文件IO和标准输入输出交互,或通过docker attach 容器ID进入容器。

host

与宿主机共用网络栈,IP和端口,容器本身看起来就像是个普通的进程,它暴露的端口可直接通过宿主机访问。相比于bridge模式,host模式有显著的性能优势(因为走的是宿主机的网络栈,而不是docker deamon为容器虚拟的网络栈)。

bridge

默认网络模式,此模式下,容器有自己的独立的Network Namespace。简单来说,Docker在宿主机上虚拟了一个子网络,宿主机上所有容器均在这个子网络中获取IP,这个子网通过网桥挂在宿主机网络上。Docker通过NAT技术确保容器可与宿主机外部网络交互。

阅读全文 »

go select思想来源于网络IO模型中的select,本质上也是IO多路复用,只不过这里的IO是基于channel而不是基于网络,同时go select也有一些自己不同的特性,这里简单探讨下。

go select 的特性:

  1. 每个case都必须是一个通信
  2. 所有channel表达式都会被求值
  3. 所有被发送的表达式都会被求值
  4. 如果任意某个通信可以进行,它就执行;其他被忽略。
  5. 如果有多个case都可以运行,select会随机公平地选出一个执行。其他不会执行。否则执行default子句(如果有)
  6. 如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。

下面通过几个例子来理解这些特性:

阅读全文 »

本文记录最近做战斗系统的一些心得和思考,由于我们的战斗系统是回合制的,与大部分回合制游戏一样,需要服务器计算战斗,客户端以战报的方式回放。这里探讨一下服务端战斗系统的设计思路,实现一个灵活,可配置,扩展性强的战斗系统。

战斗流程

战斗地图是一个X*Y的矩阵,每个参与者(Fighter)初始位于其中一个格子上。战斗开始后,按照回合迭代,达到胜负条件或最大回合数则战斗结束。回合内,英雄按照出手顺序先后行动(Action),英雄的Action包括移动,释放技能和普攻。

战斗流程是比较简明易懂的,整个战斗系统的难点在于多样的技能实现。每个英雄有N个技能,每个英雄可通过学习其它技能来实现不同的战斗效果,技能的效果和作用比较繁杂,例如:

阅读全文 »

常见并发模型

之前对比过Go和Erlang的并发模型,提到了Go的优势在于流控,下面列举几种常见的流控:

Ping-Pong

这通常针对于两个goroutine之间进行简单的数据交互和协作,我们常用的RPC也属于此类,通过channel的类型可以灵活实现交互方式:

  • 同步单工: 单个双向非缓冲channel
  • 同步双工: 多个单向非缓冲channel
  • 异步双工: 多个单向缓冲channel
阅读全文 »

源于从Erlang转到Go的一些思维碰撞,整理下来记于此。

Erlang Actor

Actor模型,又叫参与者模型,其”一切皆参与者(Actor)”的理念与面向对象编程的“一切皆是对象”类似,但是面向对象编程中对象的交互通常是顺序执行的(占用调用方的时间片),而Actor模型中Actor的交互是并行执行的(不占用调用方的时间片)。

在Actor模型中,Actor的交互通过向对方Actor发送消息来完成。即Actor只关注要和谁通信,并不关注对方在哪里、如何和对方通信。模型只提供异步消息交互一种通信原语,甚至不保证对端一定能正确收到消息。

从Actor自身来说,它的行为模式很简单:

  • 发送消息给其它的Actor
  • 接收并处理消息,更新自己的数据状态
  • 创建其它的Actor

每个Actor都有一个通信信箱(mailbox,FIFO消息队列),用于保存已经收到但尚未被处理的消息。actorA要向actorB发消息,只需持有actorB ID(mailbox邮箱地址),发送的消息将被Push到actorB的消息信箱尾部,然后返回。因此Actor的通信原语是异步的。消息QoS和请求-响应机制完全交给应用层去实现。这是Actor分布式友好的基础。

由于Actor这种”最坏预期”的设计理念,Actor模型天然有如下好处:

  • 由于Actor只通过消息交互,因此避免了锁的问题
  • 由于Actor并不关心对方具体位置以及通信介质,这种位置透明的特性使得它在分布式下具备很好的扩展性
  • 由于Actor只提供异步消息交互,因此整个系统的下限更高(锁和同步调用是高可用系统深深的痛)

Erlang作为最早的Actor模型实践者,同时也是Actor模型的推广者和标杆。Erlang实现了完整的轻量级Actor(Erlang Process),包括位置透明性、异步交互、基于规约的公平调度器等。使得它在并发和分布式方面有得天独厚的优势。

阅读全文 »

目前所在的项目基于erlang cluster搭建框架,再接入lua用于写逻辑。由于之前有一些erlang+lua的开发经验,因此着手项目的重构和优化,过程中一些体会,记录于此。

先简述一下项目架构,erlang做集群,网络层,节点交互,DB交互等,lua层只写逻辑。一个erlang的Actor持有一个luastate,为了加速erlang和lua之间的交互效率:

  1. 将逻辑数据置于lua中而不是erlang中,在落地时,以二进制格式丢给erlang进行DB操作
  2. lual_ref和msgid等方式,尽量用整数代理字符串
  3. erlang和lua异步运行,lua跑在原生线程池中,这在这篇博文中介绍过
阅读全文 »

Variables

  • 访问一个不存在的全局变量得到nil
  • 释放一个全局变量只需将其赋值为nil,效果与未定义该变量一样
  • Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量
  • 局部变量比全局变量访问更快
阅读全文 »

系统的资源是有限的(如CPU,内存,内核所能打开的最大文件数等),资源限制对针对进程能使用的系统资源设定上限。防止恶意进程无限制地占用系统资源。

资源限制分为两种,硬限制(Hard Limit)和软限制(Soft Limit),软限制作用于实际进程并且可以修改,但不能超过硬限制,硬限制只有Root权限才能修改。

相关命令

在Mac OS X下,有如下三个命令与系统资源有关。

launchctl

launchctl管理OS X的启动脚本,控制启动计算机时需要开启的服务(通过后台进程launchd)。也可以设置定时执行特定任务的脚本,类似Linux cron。

例如,开机时自动启动Apache服务器:

$ sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
阅读全文 »

环境管理

  • Go版本管理: gvm(go version manager)
  • GOPATH管理: gvp(go version package)
  • 依赖版本管理: gpm(go package manager)

go build

用于编译指定的源码文件或代码包以及它们的依赖包。

import导入路径中的最后一个元素是路径名而不是包名,路径名可以和包名不一样,但同一个目录只能定义一个包(包对应的_test测试包除外)

阅读全文 »

一. 选择器

1. 普通选择器

类别 例子 解释
标签选择器 div 以HTML 标签类型来选择元素,又叫类型选择器
类选择器 .span1 以class属性值来选择元素,可在页面中出现多个
ID选择器 #inst 以id属性值来选择元素,在页面中只能出现一次
阅读全文 »