跳转到主要内容

博客

  • skynet 的协程

    发布于 文章 782 字 2 分钟

    Python

    之前对 skynet 的印象,主要是来自于我对 golang 的理解,对 gevent 开发的经验,以及云风的 blog。对于底层的代码,并没有仔细去阅读过。最近在实现业务系统的时候,发现有同事在同一个函数里做了一个互斥的判断,才发现对 skynet 的理解有误。 以前,用 python 的 gevent 框架实现游戏服务器的时候,会针对每个玩家建立 3-5 个 greenlet(协程),用于处理玩家身上的定时器事件,以及 IO 操作。然后还有少数几个协程处理全局的定时器事件。当然,战斗是放在独 …

    之前对 skynet 的印象,主要是来自于我对 golang 的理解,对 gevent 开发的经验,以及云风的 blog。对于底层的代码,并没有仔细去阅读过。最近在实现业务系统的时候,发现有同事在同一个函数里做了一个互斥的判断,才发现对 skynet 的理解有误。 以前,用 python 的 gevent 框架实现游戏服务器的时候,会针对每个玩家建立 3-5 个 greenlet(协程),用于处理玩家身上的定时器事件,以及 IO 操作。然后还有少数几个协程处理全局的定时器事件。当然,战斗是放在独 …

  • redis-persist 上线

    发布于 文章 614 字 2 分钟

    Python

    九月份惨不忍睹,因为代码质量不够高,直接被 Boss 喷成了筛子。被反复教育说要高质量的代码,要可维护、高性能 幸而,最后一周终于在紧张的加班中,灰度上线 redis-land-go 了,项目也改名为 redis-persist,github 在此 。 之前实现的,是 redis 到 leveldb,以及 skynet 从 leveldb 中读取数据的接口。最后一周添加的,是 SA 同事可能会用到的功能。主要是: dump restore_one restore_all sync …

    九月份惨不忍睹,因为代码质量不够高,直接被 Boss 喷成了筛子。被反复教育说要高质量的代码,要可维护、高性能 幸而,最后一周终于在紧张的加班中,灰度上线 redis-land-go 了,项目也改名为 redis-persist,github 在此 。 之前实现的,是 redis 到 leveldb,以及 skynet 从 leveldb 中读取数据的接口。最后一周添加的,是 SA 同事可能会用到的功能。主要是: dump restore_one restore_all sync …

  • 忙里偷闲的八月

    发布于 文章 990 字 2 分钟

    Python

    八月依然有些很狗血的策划案要做,以至于花了两周时间,周五做出来后,连策划自己都觉得配置超多超复杂。。。 这个月比较过瘾的,是下决心做了 dns 的实验。当时为了防止 DNS 污染,曾经用 Python 写过一个 DNS 代理,通过 TCP 管道传输解析包,避免墙的干扰,地址在 google code。项目原本是通过丢弃最先返回的 udp 包来实现的,后来改为了 TCP 查询。不过,当时硬着头皮读的 RFC1035,只读懂了 TCP 的部分,只要将接收到的包体加上长度作为包头,就可以直接丢到 …

    八月依然有些很狗血的策划案要做,以至于花了两周时间,周五做出来后,连策划自己都觉得配置超多超复杂。。。 这个月比较过瘾的,是下决心做了 dns 的实验。当时为了防止 DNS 污染,曾经用 Python 写过一个 DNS 代理,通过 TCP 管道传输解析包,避免墙的干扰,地址在 google code。项目原本是通过丢弃最先返回的 udp 包来实现的,后来改为了 TCP 查询。不过,当时硬着头皮读的 RFC1035,只读懂了 TCP 的部分,只要将接收到的包体加上长度作为包头,就可以直接丢到 …

  • 并行的边界

    发布于 文章 1185 字 3 分钟

    Python

    七月份忙的狗一样,还一度要 12 点赶回公司修 bug,真累。。。 入职以来的这两个月,一直在业务层摸索,苦于没有文档,rpc 协议、单件服务的启动、为热更新去准备的环境变量等等,都要一一在摸索中问出来。幸而,终于走过了这一段。这也促使我开始思考,skynet、gevent、golang 之间,各自的优点和缺点是什么。 先从 skynet 说起,最直观的感受是,skynet 在 lua/c 里几乎完全复制了 python 的标准库。上至打包用的 serialize、json 库,下至打印字典 …

    七月份忙的狗一样,还一度要 12 点赶回公司修 bug,真累。。。 入职以来的这两个月,一直在业务层摸索,苦于没有文档,rpc 协议、单件服务的启动、为热更新去准备的环境变量等等,都要一一在摸索中问出来。幸而,终于走过了这一段。这也促使我开始思考,skynet、gevent、golang 之间,各自的优点和缺点是什么。 先从 skynet 说起,最直观的感受是,skynet 在 lua/c 里几乎完全复制了 python 的标准库。上至打包用的 serialize、json 库,下至打印字典 …

  • 初来乍到

    发布于 文章 682 字 2 分钟

    Python

    来到新公司后,终于有机会用 git 作为版本控制的工具。通过 github 私有仓库进行 Pull Request 和 code review,的确十分方便。使用的时候发现自己关于分支的知识不够用了,出现过一次提交 Pull Request 后被 merge,然后自己本地又 merge 了,导致 git pull 时版本冲突的问题。另外,客户端不希望出现 merge,所有对共享配置的修改,都需要用 rebase 方式合并,又犯了一次错误 最近提交的代码里,主要是用 python 写的一个日志分析 …

    来到新公司后,终于有机会用 git 作为版本控制的工具。通过 github 私有仓库进行 Pull Request 和 code review,的确十分方便。使用的时候发现自己关于分支的知识不够用了,出现过一次提交 Pull Request 后被 merge,然后自己本地又 merge 了,导致 git pull 时版本冲突的问题。另外,客户端不希望出现 merge,所有对共享配置的修改,都需要用 rebase 方式合并,又犯了一次错误 最近提交的代码里,主要是用 python 写的一个日志分析 …

  • 进程 daemon 化

    发布于 文章 629 字 2 分钟

    Python

    最近跳槽,转去简悦了,新公司的技术氛围很好,我要更加努力 ~ 有些问题不写博客的时候,以为自己是懂的,但是实际讨论的时候,发现有一些细节还是没有搞清楚,这次试试讲进程怎样 daemon 化。 首先上代码,这次的代码来自于 stackoverflow:http://stackoverflow.com/questions/17954432/creating-a-daemon-in-linux 1 /* 2 * daemonize.c 3 * This example daemonizes a …

    最近跳槽,转去简悦了,新公司的技术氛围很好,我要更加努力 ~ 有些问题不写博客的时候,以为自己是懂的,但是实际讨论的时候,发现有一些细节还是没有搞清楚,这次试试讲进程怎样 daemon 化。 首先上代码,这次的代码来自于 stackoverflow:http://stackoverflow.com/questions/17954432/creating-a-daemon-in-linux 1 /* 2 * daemonize.c 3 * This example daemonizes a …

  • 引用计数 gc 机制使用不当导致内存泄漏

    发布于 文章 989 字 2 分钟

    Python

    上一篇文章找同事 review 了一下,收到的反馈是铺垫太长了,我尽量直入正题,哈哈 最近 dbd 压测时发现内存泄漏,其实这个问题去年已经暴露了,参见这篇 博客【压测周】。当时排查不够仔细,在此检讨下。关于 dbd 的内存问题,还有 这篇博客 讨论线程安全,以及 这篇博客 讨论临时变量的处理。当时还存了一个尾巴,因为用到关联数组进行脏数据管理,这部分数据是怎么释放的一直没搞明白。今天算是搞明白了,这个内存泄漏的 bug 也源于此。 基于引用计数的 gc 机制,应该是在引用计数为 0 的时候释放 …

    上一篇文章找同事 review 了一下,收到的反馈是铺垫太长了,我尽量直入正题,哈哈 最近 dbd 压测时发现内存泄漏,其实这个问题去年已经暴露了,参见这篇 博客【压测周】。当时排查不够仔细,在此检讨下。关于 dbd 的内存问题,还有 这篇博客 讨论线程安全,以及 这篇博客 讨论临时变量的处理。当时还存了一个尾巴,因为用到关联数组进行脏数据管理,这部分数据是怎么释放的一直没搞明白。今天算是搞明白了,这个内存泄漏的 bug 也源于此。 基于引用计数的 gc 机制,应该是在引用计数为 0 的时候释放 …

  • 嵌入式课程设计 -- 第一天

    发布于 文章 327 字 1 分钟

    Python

    今天花了一个早上去配置开发环境,晕死。。。 主要问题是找到一个合适的 2410 实验箱。电脑方面虽然普遍带毒,好歹还是能跑起来。但实验箱方面就比较麻烦。一个是线缆的配合,包括串行线,串行线方面有两种,一种是斜纹,一种是直纹的,它们分别是交叉线和非交叉线。另一个比较重要的线缆是 JTAG 线,我们见的 JTAG 线比较少,所以刚开始的时候拿了另一个实验箱的线。 然后是熟悉了一下 vivi 的操作,首先是尝试把一个 helloworld 的文件通过 JTAG 线烧进去,这个理论上机器正常都可以输出结 …

    今天花了一个早上去配置开发环境,晕死。。。 主要问题是找到一个合适的 2410 实验箱。电脑方面虽然普遍带毒,好歹还是能跑起来。但实验箱方面就比较麻烦。一个是线缆的配合,包括串行线,串行线方面有两种,一种是斜纹,一种是直纹的,它们分别是交叉线和非交叉线。另一个比较重要的线缆是 JTAG 线,我们见的 JTAG 线比较少,所以刚开始的时候拿了另一个实验箱的线。 然后是熟悉了一下 vivi 的操作,首先是尝试把一个 helloworld 的文件通过 JTAG 线烧进去,这个理论上机器正常都可以输出结 …

  • 脚本引擎栈指针误操作引起内存泄露

    发布于 文章 1279 字 3 分钟

    Python

    最近,为了确定目标部署机器的配置,我们对服务器进行了玩家登录的压力测试。在 E7500 cpu,3G 内存的开发机上,同一时间登录人数不能超过 20 人。以 0.01 秒间隔登录,测试人数 5000 人,登录时一个核心在 30%-60% 之间波动,另一个核心比较空闲。稳定后,CPU 平均在 5% 一下(玩家只是登录后保持心跳),峰值内存在 2.3G 以内。但比较诡异的是,当玩家全部断开后,服务器的内存还是没有降下来。我觉得,可能是发生内存泄露了。 发现这个问题后,我排查了底层对玩家 user …

    最近,为了确定目标部署机器的配置,我们对服务器进行了玩家登录的压力测试。在 E7500 cpu,3G 内存的开发机上,同一时间登录人数不能超过 20 人。以 0.01 秒间隔登录,测试人数 5000 人,登录时一个核心在 30%-60% 之间波动,另一个核心比较空闲。稳定后,CPU 平均在 5% 一下(玩家只是登录后保持心跳),峰值内存在 2.3G 以内。但比较诡异的是,当玩家全部断开后,服务器的内存还是没有降下来。我觉得,可能是发生内存泄露了。 发现这个问题后,我排查了底层对玩家 user …

  • 译 libev 和 libevent 的设计差异

    发布于 文章 973 字 2 分钟

    Python

    本文译自 what’s the difference between libev and libevent? 作者是 libev 作者 [ 问 ] 两个库都是为异步 io 调度而设计,在 Linux 上都是使用 epoll 机制,在 FreeBSD 上则都是 kqueue,还有诸如此类的很多相通之处。 除了这些表面上的差别外,其实这两者根本的区别在哪里呢?比如架构上,或者设计哲学上。 [ 答 ] 就设计哲学来说,libev 的诞生,是为了修复 libevent 设计上的一些错误决策。例如,全局变 …

    本文译自 what’s the difference between libev and libevent? 作者是 libev 作者 [ 问 ] 两个库都是为异步 io 调度而设计,在 Linux 上都是使用 epoll 机制,在 FreeBSD 上则都是 kqueue,还有诸如此类的很多相通之处。 除了这些表面上的差别外,其实这两者根本的区别在哪里呢?比如架构上,或者设计哲学上。 [ 答 ] 就设计哲学来说,libev 的诞生,是为了修复 libevent 设计上的一些错误决策。例如,全局变 …

  • libevent 库 1.4 升级到 2.0 时无法 flush 的解决办法

    发布于 文章 1117 字 3 分钟

    Python

    libevent 的接口兼容性做的还算不错,基本上替换一下就转到新版本了。但是,强制 flush 数据的时候出了问题。目前的应用场景是,遇到顶号登录这种情形,先用 bufferevent_write 向客户端发送错误信息,然后再断开 socket。用的 flush 是这样的: void try_flush(bufferevent *bev) { int size = evbuffer_get_length(bufferevent_get_output(bev)); if (size > 0) { …

    libevent 的接口兼容性做的还算不错,基本上替换一下就转到新版本了。但是,强制 flush 数据的时候出了问题。目前的应用场景是,遇到顶号登录这种情形,先用 bufferevent_write 向客户端发送错误信息,然后再断开 socket。用的 flush 是这样的: void try_flush(bufferevent *bev) { int size = evbuffer_get_length(bufferevent_get_output(bev)); if (size > 0) { …

  • 游戏协议加密及身份验证

    发布于 文章 1093 字 3 分钟

    Python

    时间如白驹过隙,一眨眼就过去了,本打算在 2 月份发这篇的,结果一直误以为 2 月有 31 日 这一块之前一直感兴趣,终于在 2 月份争取到机会去做这一块的工作。前辈给我留下了一个鉴权的框架: 客户端连接服务器 服务器将随机数发给客户端 客户端用客户端私钥加密,发回到服务器 服务器端用客户端公钥解开密文,比对解开的随机数是否与原来的一致 如果一致,则客户端发送随机数到服务器,服务器用服务器端私钥加密,将密文发送到客户端;同时,产生新的随机数,用于稍后对会话进行 rc4 加密,并将这个随机数以客户 …

    时间如白驹过隙,一眨眼就过去了,本打算在 2 月份发这篇的,结果一直误以为 2 月有 31 日 这一块之前一直感兴趣,终于在 2 月份争取到机会去做这一块的工作。前辈给我留下了一个鉴权的框架: 客户端连接服务器 服务器将随机数发给客户端 客户端用客户端私钥加密,发回到服务器 服务器端用客户端公钥解开密文,比对解开的随机数是否与原来的一致 如果一致,则客户端发送随机数到服务器,服务器用服务器端私钥加密,将密文发送到客户端;同时,产生新的随机数,用于稍后对会话进行 rc4 加密,并将这个随机数以客户 …