推导利滚利公式
自从开始学习智能合约之后,接触到了很多「资金盘」游戏,比如前段时间大火的 Fomo3D,不过自从 333ETH 崩盘之后,此类游戏暂时已经没有市场了,因为本质上来说,它们都属于庞氏骗局,在研究相关代码后,让我对利滚利公式产生了一点兴趣,其实很简单,但我年纪大了,实实在在推导了好几遍才搞定,索性把推导过程记录下来。 比如有一个资金盘游戏,开始你投入 10000 块钱,然后每天我给你返利...
View Article学习Golang的HTTP中间件机制
因为 Golang 内置的 net/http 天生就支持 HTTP 中间件机制,所以即便不用 gin 之类的 Web 框架,我们也可以写出扩展性很好的 Web 应用。 假如你不了解 Golang 的 HTTP 中间件机制的话,那么可以把它看成是一个洋葱: 通过洋葱看中间件...
View Article在Golang的HTTP请求中共享数据
首先,我们需要先明确一下问题的描述:本文所要讨论的共享数据可不是指的 cookie、session 之类的概念,它们描述的是在「请求间」共享数据,而我们关注的是在「请求中」共享数据,也就说是,在每个请求中的各个 middleware 和 handler 之间共享数据。 实际上,我之所以关注这个问题是因为 httprouter,众所周知,httprouter 是目前 Golang 社区最流行的...
View ArticleTo panic or not to panic
大家都知道 Golang 推荐的错误处理的方式是使用 error,这主要得益于 Golang 方法可以返回多个值,我们可以很自然的用最后一个值来表示是否有错误,这一点是其它很多编程语言所不具备的,不过这多少让那些习惯了 exception 的程序员无所适从,虽然 Golang 没有 exception,但是实际上可以通过 panic/recover 来模拟出类似的效果,于是很多 Gopher...
View Article如何优化Golang中重复的错误处理
Golang 错误处理最让人头疼的问题就是代码里充斥着「if err != nil」,它们破坏了代码的可读性,本文收集了几个例子,让大家明白如何优化此类问题。 让我们看看 Errors are values 中提到的一个 io.Writer 例子: _, err = fd.Write(p0[a:b]) if err != nil { return err } _, err =...
View ArticleGolang之Context的迷思
对我而言,Golang 中的 Context 一直是谜一样的存在,如果你还不了解它,建议阅读「快速掌握 Golang context 包,简单示例」,本文主要讨论一些我曾经的疑问。 Context 到底是干什么的? 如果你从没接触过 Golang,那么按其它编程语言的经验来推测,多半会认为 Context 是用来读写一些请求级别的公共数据的,事实上 Context...
View Article聊聊AES
说起加密,通常分为对称加密和非对称加密,所谓对称加密中的对称,指的是加密和解密使用的是同一个密钥,如此说来什么是非对称就不用我多做解释了。对称加密相对于非对称加密而言,优点是速度快,缺点是安全性相对低一点,不过只要能保证密钥不泄露,其安全性还是有保证的,所以在实际项目中,对称加密的使用非常广泛。 目前最流行的对称加密标准是 AES。需要说明的是:AES 是一个标准,而不是一个算法,实际上背后的算法是...
View Article关于手机App的Https抓包
我喜欢用 Mitmproxy 来处理手机 App 抓包之类的工作,本来用它来抓 Https 包是很容易的一件事,只要设置好代理,浏览 mitm.it 按提示安装证书即可,可是当 Android 版本升级到 7 以后,此方法就失效了,为什么呢?因为新版 Android 缺省情况下只信任系统级证书,而不再信任用户级证书,问题详细描述可以参考:听说安卓微信 7.0 不能抓 https?...
View ArticleOpenResty 101
本文是 OpenResty 的初学者指南,提供一些资料的汇总。 OpenResty 初学者在刚开始学习 OpenResty 的时候,最好能先对 Nginx 有一定的了解,推荐阅读 OpenResty 作者 agentzh 撰写的 Nginx 教程,有中文版和英文版。 一旦对 Nginx 有了基本的认知,那么可以读十遍 lua-nginx-module 的官方文档,同时 iresty...
View Article被忽视的time命令
如果要选 Linux 下最容易被忽视的命令,time 应该算一个。简单来说,它是一个用来计算命令运行时间的工具,之所以说它容易被忽视,一方面很多人根本不知道 time 的存在,而是习惯在命令启动前后记录两个时间戳,然后手动计算命令运行时间;另一方面很多人虽然知道 time 的存在,但是却并没有真正理解它的含义。 下面让我们通过若干例子来理解 time 的真正含义: shell> time ls...
View Article如何使用PHP解析XML大文件
如果使用 PHP 解析 XML 的话,那么常见的选择有如下几种:DOM、SimpleXML、XMLReader。如果要解析 XML 大文件的话,那么首先要排除的是 DOM,因为使用 DOM 的话,需要把整个文件全部加载才能解析,效率堪忧,相比较而言,SimpleXML 和 XMLReader 更好些,SimpleXML 相对简单,而 XMLReader...
View Article关于Cosocket的SocketBusy报错
关于 OpenResty 的 cosocket,文档里有如下一段描述: the cosocket object here is full-duplex, that is, a reader “light thread” and a writer “light thread” can operate on a single cosocket object simultaneously (both...
View Article如何扩展一个OpenResty模块
因为 Lua 本身并没有继承之类的语法,所以我们不能通过 OOP 的套路来扩展模块,不过实际上对于 Lua 来说,扩展一个模块有更简单的方法,下面我们以 lua-resty-string 模块中的 aes 加解密功能为例子来说明一下。 在 aes 加解密的过程中,有一个「填充」的过程,相关技术细节可以参考我以前写的「聊聊AES」,当然,不懂也没关系,你只要知道目前的 resty.aes...
View Article一个尾调用相关的诡异报错信息
一个 OpenResty 的接口报错了,我查了一下日志,发现如下报错信息: bad argument #1 to ‘test’ (string expected, got userdata) 看上去这就是一道送分题啊:无非就是 test 函数的第一个参数类型应该是 string,实际传递的却是 userdata。就当我觉得可以轻而易举解决问题的时候,突然发现 test...
View Article手把手教你用OpenResty里的FFI
了解 OpenResty 的人应该知道,OpenResty 原本的 API 都是基于 C 实现的,不过在新版里都已经改成了基于 FFI 实现的,为什么这么做?因为 FFI 在效率上更有优势,除此以外,FFI 还有一个优点是可以很便利的和 C 交互,我们不妨设想一下,C 语言有那么多成熟的库,通过 FFI,我们可以轻而易举的引入到自己的应用中,何乐而不为呢? 本文通过 Hashids 手把手教你用...
View Article如何在OpenResty里实现代码热更新
所谓「代码热更新」,是指代码发生变化后,不用 reload 或者 graceful restart 进程就能生效。比如有一个聊天服务,连接着一百万个用户的长连接,所谓代码热更新就是在长连接不断的前提下完成代码更新。实际上因为所有的 require 操作都是通过 package.loaded 来加载模块的,只要代码是以 module 的形式组织的,那么就可以通过 package.loaded...
View Article关于OpenResty里的ngx.on_abort
关于 OpenResty 里的 ngx.on_abort,官方文档里是这样说明的: Registers a user Lua function as the callback which gets called automatically when the client closes the (downstream) connection prematurely....
View Article记一次有惊无险的丢包调试经历
某个项目把服务器从 CentOS 操作系统从 5 升级到了 7(3.10.0-693),一切都很顺利,直到我在服务器上闲逛的时候,无意间发现了一个「大问题」:网卡 eth0 在 RX 上存在丢包(dropped)现象,丢得还很有规律,每一两秒丢一个包! watch -d -n1 ‘ifconfig’ 一开始怀疑是不是网卡的 ring buffer 太小了,通过「ethtool」确认:...
View Article记一次Redis连接池问题引发的RST
某个项目,因为监控尚不完善,所以我时常会人肉查查状态,终于有一天发现了异常: watch -d -n1 ‘netstat -s | grep reset’ 如图所示,服务器发送了大量的 reset,在我 watch 的时候还在发,多半有问题。 通过 tcpdump 我们可以简单抓取一下 RST 包: shell> tcpdump -nn 'tcp[tcpflags] &...
View Article