文章
PullRequest 找原作者做 review
最近对代码库进行了一次全局替换,改了 150 个左右的文件,发了 PR 后需要找原作者确认一下,于是写了个工具做 git blame, 地址在这里 写完发现一个问题,如果只是新增一个函数,没有调用,是应该不用找原作者的 …… 但是,要识别出新增一个函数,没想象中容易,需要基于 ast 来做 diff,才能发现。也就是说,这个工具对于批量替换的功能,才比较好用,其他改动不太合适,蛋疼
最近对代码库进行了一次全局替换,改了 150 个左右的文件,发了 PR 后需要找原作者确认一下,于是写了个工具做 git blame, 地址在这里 写完发现一个问题,如果只是新增一个函数,没有调用,是应该不用找原作者的 …… 但是,要识别出新增一个函数,没想象中容易,需要基于 ast 来做 diff,才能发现。也就是说,这个工具对于批量替换的功能,才比较好用,其他改动不太合适,蛋疼
Nginx 超时设定
最近针对公司的 goscon 网关发了一个 PR,新增了握手阶段的超时判定。现在回顾一下 Nginx 的所有超时判定,看看目前还缺少哪些判定 **client_header_timeout (默认 60 秒)** **client_body_timeout (默认 60 秒)** **keepalive_timeout (默认 75 秒)** **lingering_timeout (默认 5 秒)** **<strong>resolver_timeout (默认 30 秒)** …
最近针对公司的 goscon 网关发了一个 PR,新增了握手阶段的超时判定。现在回顾一下 Nginx 的所有超时判定,看看目前还缺少哪些判定 **client_header_timeout (默认 60 秒)** **client_body_timeout (默认 60 秒)** **keepalive_timeout (默认 75 秒)** **lingering_timeout (默认 5 秒)** **<strong>resolver_timeout (默认 30 秒)** …
Rust 对协程的思考
最近和同事聊起来,觉得 lua 缺乏编译型语言的类型校验功能,还有变量拼写检查之类的,导致线上总是有低级错误出现。比如最近有一个是变量名拼写少了一个字母,导致某功能没开启;还有一个是变量传参时,之前测试多加了一个参数,测试完成后忘记删了,导致参数顺序不对。之前看过有个 TypeLua,没想到现在已经不怎么维护了,去搞了 Titan-lang,然而 Titan 也是 4 个月没动静了。。。 目前也没想到什么好的解决办法,于是顺带看看 Rust-lang,开阔一下思路。我最佩服 rust 这帮人的, …
最近和同事聊起来,觉得 lua 缺乏编译型语言的类型校验功能,还有变量拼写检查之类的,导致线上总是有低级错误出现。比如最近有一个是变量名拼写少了一个字母,导致某功能没开启;还有一个是变量传参时,之前测试多加了一个参数,测试完成后忘记删了,导致参数顺序不对。之前看过有个 TypeLua,没想到现在已经不怎么维护了,去搞了 Titan-lang,然而 Titan 也是 4 个月没动静了。。。 目前也没想到什么好的解决办法,于是顺带看看 Rust-lang,开阔一下思路。我最佩服 rust 这帮人的, …
Python 的定时执行
最近手把手教妹子写 Python,被一篇博客误导了,这里记录一下。 妹子需要的是一个定时闹钟,到点往钉钉群里推个消息。她一顿搜索猛如虎,参照着其他人的博客,搞了一个 while: target_time = mktime(time.strptime("2019-5-29 15:30:00", "%Y-%m-%d %H:%M:%S")) while True: now = time.time() if now > target_time: print(u" 到点 ") break 这种没啥技术含量 …
最近手把手教妹子写 Python,被一篇博客误导了,这里记录一下。 妹子需要的是一个定时闹钟,到点往钉钉群里推个消息。她一顿搜索猛如虎,参照着其他人的博客,搞了一个 while: target_time = mktime(time.strptime("2019-5-29 15:30:00", "%Y-%m-%d %H:%M:%S")) while True: now = time.time() if now > target_time: print(u" 到点 ") break 这种没啥技术含量 …
Mesh 内存分配器的 mmap 小技巧
最近看了 一篇内存分配器的论文 ,原理很简单,但是里面的数学论证还没看懂,这次先简单写一下原理和用到的 API。 内存分配器是用于封装操作系统提供的底层 API,给应用程序提供动态内存的。内存不断申请释放后,往往会形成内存碎片。当需要申请一段较大的内存时,当前剩余内存总量是够的,但是被当前申请的内存块隔断成一个个小隔间,内存分配器无法给出指定长度的内存。这时就只能向操作系统重新申请,或者对应用程序返回分配失败了。 ( 图片来自这里 ) 如上图所示,不断申请内存后,内存占用如 Figure 2 所 …
最近看了 一篇内存分配器的论文 ,原理很简单,但是里面的数学论证还没看懂,这次先简单写一下原理和用到的 API。 内存分配器是用于封装操作系统提供的底层 API,给应用程序提供动态内存的。内存不断申请释放后,往往会形成内存碎片。当需要申请一段较大的内存时,当前剩余内存总量是够的,但是被当前申请的内存块隔断成一个个小隔间,内存分配器无法给出指定长度的内存。这时就只能向操作系统重新申请,或者对应用程序返回分配失败了。 ( 图片来自这里 ) 如上图所示,不断申请内存后,内存占用如 Figure 2 所 …
尝鲜 svnup
最近有同事折腾了一下 svnup 的编译,终于可以在 Mac OS X 和 Linux 上面编译通过了, 仓库在这里:https://github.com/lvzixun/svnup/ 看 subversion 的代码,他是封装了一个 libsvn_client 的库来做实际逻辑的。update 的时候一个一个请求的发,是因为有可能需要处理冲突的情况,一个一个处理冲突,对于 frontend 来说比较简单吧 所以 svnup 其实相当于一个爬虫,根据版本号直接批量将文件下载下来,不管本地文件有没 …
最近有同事折腾了一下 svnup 的编译,终于可以在 Mac OS X 和 Linux 上面编译通过了, 仓库在这里:https://github.com/lvzixun/svnup/ 看 subversion 的代码,他是封装了一个 libsvn_client 的库来做实际逻辑的。update 的时候一个一个请求的发,是因为有可能需要处理冲突的情况,一个一个处理冲突,对于 frontend 来说比较简单吧 所以 svnup 其实相当于一个爬虫,根据版本号直接批量将文件下载下来,不管本地文件有没 …
HTTPPostmultipartform-data 支持
最近需要向平台发送录像文件,但是 Skynet 没有 multipart/form-data 的 Post 请求支持,写篇 blog 记录一下 所以只能有最原始的 httpc.request 方法了。请求头比较灵活,可以自己设置为 Content-type: multipart/form-data; 除了这个,还需要设置一个 boundary,用来分割需要同时上传多个 field 的情况。每个 field 长这样: …
最近需要向平台发送录像文件,但是 Skynet 没有 multipart/form-data 的 Post 请求支持,写篇 blog 记录一下 所以只能有最原始的 httpc.request 方法了。请求头比较灵活,可以自己设置为 Content-type: multipart/form-data; 除了这个,还需要设置一个 boundary,用来分割需要同时上传多个 field 的情况。每个 field 长这样: …
redis 的 LRU 算法(二)
前文再续,书接上一回 。上次讲到 redis 的 LRU 算法,文章实在精妙,最近可能有机会用到其中的技巧,顺便将下半部翻译出来,实现的时候参考下。 搏击俱乐部的第一法则:用裸眼观测你的算法 Redis2.8 的 LRU 实现已经上线了,在不同的负载环境下经过测试,用户没有抱怨 Redis 的清理机制。为了继续改进,我希望能观察到算法的性能,同时不会浪费大量 CPU,不增加 1 比特空间占用。 我设计了一个测试用例。导入指定数量的 key,然后顺序访问他们,好让他们的最近访问时间顺序递减。再添 …
前文再续,书接上一回 。上次讲到 redis 的 LRU 算法,文章实在精妙,最近可能有机会用到其中的技巧,顺便将下半部翻译出来,实现的时候参考下。 搏击俱乐部的第一法则:用裸眼观测你的算法 Redis2.8 的 LRU 实现已经上线了,在不同的负载环境下经过测试,用户没有抱怨 Redis 的清理机制。为了继续改进,我希望能观察到算法的性能,同时不会浪费大量 CPU,不增加 1 比特空间占用。 我设计了一个测试用例。导入指定数量的 key,然后顺序访问他们,好让他们的最近访问时间顺序递减。再添 …
Skynet 服务热点火焰图分析
最近花了一周时间对场景服务进行热点分析,利用 以前的火焰图工具 做了一点微小的贡献,分享下心得(仓库地址在 https://github.com/spin6lock/skynet_systemtap_set)。 Skynet 是一个轻量级的多线程在线游戏框架 。线程作为 worker,从服务的队列中抽出有消息的,然后处理上面的消息。服务间通过发消息来相互通信。目前服务主要是用 Lua 进行编写。 以前做的火焰图工具,没法单独看一个 skynet 服务的堆栈,只能看到整个进程的。要想针对单个服务做 …
最近花了一周时间对场景服务进行热点分析,利用 以前的火焰图工具 做了一点微小的贡献,分享下心得(仓库地址在 https://github.com/spin6lock/skynet_systemtap_set)。 Skynet 是一个轻量级的多线程在线游戏框架 。线程作为 worker,从服务的队列中抽出有消息的,然后处理上面的消息。服务间通过发消息来相互通信。目前服务主要是用 Lua 进行编写。 以前做的火焰图工具,没法单独看一个 skynet 服务的堆栈,只能看到整个进程的。要想针对单个服务做 …
内存爆灯
最近产品在韩国上线了,上线后的第一个周末,人数最多的一服内存爆了,被 OOM 杀掉宕机了,很郁闷 机器用的 4 核 16G,aws 的实例。周四开服后,每天零点左右的在线人数峰值,内存都超过了 80% 的告警线。但是运营方不希望停机,于是采取了定时通过 GM 指令调用 gc,15 分钟回收一次内存,希望撑过峰值。到了周六晚,白天加班回到家,有点松懈了,就没再盯着内存曲线看,结果一不留神就爆了。。。峰值从 78% 飙升到 91%,只用了 7 分钟,定时 gc 没赶上,就这样挂了 按之前内网的压测结 …
最近产品在韩国上线了,上线后的第一个周末,人数最多的一服内存爆了,被 OOM 杀掉宕机了,很郁闷 机器用的 4 核 16G,aws 的实例。周四开服后,每天零点左右的在线人数峰值,内存都超过了 80% 的告警线。但是运营方不希望停机,于是采取了定时通过 GM 指令调用 gc,15 分钟回收一次内存,希望撑过峰值。到了周六晚,白天加班回到家,有点松懈了,就没再盯着内存曲线看,结果一不留神就爆了。。。峰值从 78% 飙升到 91%,只用了 7 分钟,定时 gc 没赶上,就这样挂了 按之前内网的压测结 …
时区问题
最近,游戏要上国外运营了,搞完就算告一段落了放下种种不舍,搞好时区的问题,好好的送它一程吧 受时区影响的问题主要分两类,一类是运营活动,一类是特殊玩法的开启。每天定时刷新的本来就有考虑时区,略过不表 运营活动设计的时候已经考虑到时区,每个活动设计的时候,都需要填写活动开启的日期、时间及时区,这方面问题简化了很多。中间需要修改的,是偶尔有几个活动自作聪明,没有用库提供的日期计算函数,自己拿秒数来算。换上考虑时区的函数之后,就没有问题了。核心代码如下: local TD = TIMEZONE * …
最近,游戏要上国外运营了,搞完就算告一段落了放下种种不舍,搞好时区的问题,好好的送它一程吧 受时区影响的问题主要分两类,一类是运营活动,一类是特殊玩法的开启。每天定时刷新的本来就有考虑时区,略过不表 运营活动设计的时候已经考虑到时区,每个活动设计的时候,都需要填写活动开启的日期、时间及时区,这方面问题简化了很多。中间需要修改的,是偶尔有几个活动自作聪明,没有用库提供的日期计算函数,自己拿秒数来算。换上考虑时区的函数之后,就没有问题了。核心代码如下: local TD = TIMEZONE * …