May the #! be with you

网络虚拟化技术大观

| Bojie Li | Comments

网络虚拟化(Network Virtualization)就是搭建一个与物理网络拓扑结构不同的虚拟网络。例如公司在世界各地有多个办事处,但希望公司的内部网络是一个整体,就需要网络虚拟化技术。

从 NAT 说起

Capture

假设北京办事处的一台机器 IP 是 10.0.0.1(这是一个内网 IP,不可以在 Internet 上使用),上海办事处的一台机器 IP 是 10.0.0.2,它们要通过 Internet 通信。北京办事处的公网(Internet)IP 是 1.1.1.1,上海办事处的公网 IP 是 2.2.2.2。

一种简单的方式是,在北京办事处的边界路由器(Edge ...

差分磁盘:从“恢复出厂设置”说起

| Bojie Li | Comments

智能手机、路由器等很多嵌入式设备都有“恢复出厂设置”的功能。按照PC机上大家习惯的“备份”做法,似乎需要把出厂时的整个系统备份在只读的 ROM 里。如果是这样,每次恢复出厂设置,ROM 里的内容都要拷贝到 Flash 存储里,浪费大量存储空间,而且恢复出厂设置需要比较长的时间。但事实上,恢复出厂设置只是重启一下就完成了,而且刚恢复的系统里 Flash 存储基本是空的。

(感谢 BW 的评论,Android 系统的恢复出厂设置不是使用差分技术,而是简单清空数据分区,对 /system 分区的修改没有被还原,我弄错了)

Capture

虚拟机快照

在纯软件的世界里,什么地方需要类似“恢复出厂设置”的功能呢?玩过虚拟机的小伙伴们也许知道“快照”(snapshot)功能,只要几秒钟快照就能建好。什么时候虚拟机玩坏了,只要几秒钟就能恢复到“快照”的状态。磁盘快照的秘诀在于“差分磁盘”。执行 ...

超线程竞争问题引发的思考

| Stephen Zhang | Comments

问题起因

Varnish有一个bug(或者说feature也许更合适一些),有一个项资源sess_mem,对应一个计数器n_sess, 有人要用就+1,用完就-1,另外有一个函数会根据这个数字来决定是否要预分配更多的空间。 这里,为了避免太多的性能损耗,所以对n_sess的操作并没有加锁。在多线程(本文中多线程均指软件概念上的线程, 超线程指CPU的超线程技术)的环境下对同一个变量进行不加锁的读写肯定是有问题的,但是,因为在一段时间内+- 的数量相当,因此一个线程中+和-操作被其他线程吞没的概率也相当,所以最终n_sess距离精确值的偏差(后面称漂移) 应该在一个比较小的范围内(即误差应该比较小),varnish认可这个误差,通过其他方式来定期的校准一下(例如定期 的数一下实际被使用的sess_mem有多少个)这个值。

然而,问题来了,有人发现,在启用了超线程(Hyper-Threading)的机器上,varnish经常会出现疯狂的分配 ...

使用Nginx的Lua模块实现简单的权限验证系统

| Stephen Zhang | Comments

Nginx本身是一个很单纯的http服务器,其附加功能少的可怜,也正因为单纯,nginx才能如此高效。

我们常常会有一些简单的权限验证的需求,例如一个纯静态文件的wiki站点,需要对不同的人进行简单的权限控制。

Nginx本身可以实现,使用http_auth_basic_module模块可以进行最基本的权限验证。 但缺点是,修改密码必须登录服务器进行修改,十分不方便,而且当团队人多时,基本上不具有管理账号的功能。 稍大一些的团队会使用LDAP来做集中的账号管理中心。

使用auth_ldap模块可以实现基于ldap的authn,但基本没有authz的能力。

什么是authn/authz?

常见的权限系统一般有两个任务,Authentication(常简称authn)和Authorization(常简称authz)。 authn的过程是验证一个用户是否是该系统内的合法用户,例如验证你是否拥有A网站的账号。 authz的过程是验证该用户是否有权限访问某项功能,例如你可能拥有账号,但你只能访问A网站的部分内容。

authn和authz有时会一起实现,有时也会分开实现。这两者都可能很简单也可能很复杂,看具体需求。

我们前面提到了使用LDAP做账号验证,通常是使用LDAP做authn。当然LDAP也支持简单的authz的功能, 可并不是任何时候都那么方便。

我在使用auth_ldap模块时碰到了有这些问题:

  • 对每一个请求,都要该模块进行authn,当然该模块具有一定的缓存能力,但是当各种服务较多时,也会对ldap服务器带来较大的负担。
  • 我需要稍微复杂一些authz,但也不需要过于复杂,支持基于uid ...

绕过运营商HTTP劫持

| Stephen Zhang | Comments

中国的网络是奇葩的,原因之一是有奇葩的屌丝运营商。

许多小运营商(二级运营商、三级运营商、N级运营商)为了节省成本,会使用缓存系统。 这个缓存系统可以认为是一种CDN,如果做得好的话,不仅会节省成本,也会提高用户体验, 例如许多小区里大家看优酷视频从来不会缓冲,下载速度都有3MB/s以上的速度。 然而,这些缓存系统并不是CDN,而是一种非常没有节操的黑盒子。

  • 你不知道什么请求会被缓存,没法控制。
  • 你不知道会被缓存多久。
  • 这种缓存不遵守任何行业内的规则(例如不遵守Cache-Control头)。
  • 发现缓存了错误的内容,你没有地方投诉。

许多用户和开发者都为此非常头疼。例如:

  • 我去年入手iPad后,尝试在电脑上安装iTunes,从官网下载安装后,提示版本太旧,不支持新iPad,于是 自动更新,更新非常快,但更新之后仍然提示版本太旧,仔细观察发现版本并没有变。后来发现是运营商 缓存了一份老的,而苹果分发iTunes时是同名更新的。
  • 许多网页游戏(主要是flash)的开发者都非常的头疼,flash资源的加载成功率能到90%以上就算非常不错了。 为此我们也想了各种dirty的方法,例如将后缀都改成.aspx?rnd-query-string,以期望绕过运营商缓存 ...