风河博客

风河的DNS相关技术

轻松支持5W并发的webserver

前面的文章说过,用libevent这类事件机制,写个server支持几万并发并不难。
libev是libevent的改进版,EV是libev的Perl封装模块,作者基于EV实现了一个很NB的事件框架,叫做AnyEvent。
用AnyEvent写个简单webserver,支持几万并发很轻松。

如下是示例代码:

use AnyEvent::HTTPD;

my $httpd = AnyEvent::HTTPD->new (port => 9090);

$httpd->reg_cb (
   ’/’ => sub {
      my ($httpd, $req) = @_;

      $req->respond ({ content => ['text/html',
         "<html><body><h1>Hello World!</h1>"
         . "<a href=\"/\">test page by pyh</a>"
         . "</body></html>"
      ]});
   },
);

$httpd->run;

把上述代码存为httpd.pl,运行perl httpd.pl,一个webserver就产生了,侦听在9090端口。

为了支持更高并发,在web服务器上,Linux内核简单调整如下参数:

net.core.somaxconn = 1024                # 挂起请求最大数量
net.core.netdev_max_backlog = 3000       # 进入包最大设备队列
net.ipv4.tcp_max_syn_backlog = 81920     # syn队列长度
net.ipv4.tcp_wmem = 8192 436600 873200   # TCP写缓存
net.ipv4.tcp_rmem = 32768 436600 873200  # TCP读缓存
我们用ab做压力测试,由于ab默认最大支持2W并发,因此如下修改ab源代码:
(1)
        /* catch legitimate fatal apr_socket_recv errors */
        else if (status != APR_SUCCESS) {
            err_recv++;
            if (recverrok) {
                bad++;
                close_connection(c);
                if (verbosity >= 1) {
                    char buf[120];
                    fprintf(stderr,”%s: %s (%d)\n”, “apr_socket_recv”, apr_strerror(status, buf, sizeof buf), status);
                }
                return;
            } else {
                apr_err(“apr_socket_recv”, status);
                bad++;
                close_connection(c);
                return;
            }
        }
上述橙色标明的是新增加的部分。
(2)
#define MAX_CONCURRENCY 50000   //最大并发数,原来是20000,改为50000
改完后,重新编译ab。
用ab对webserver执行压力测试,共50000个请求,50000个并发:
./ab -n 50000 -c 50000 http://example.com:9090/
测试结果如下图。50000个请求全部成功,每秒请求1150个,服务器端压力几乎为0.
所以,事件驱动的网络服务,高并发说明不了什么问题。
Posted in 未分类 | Tagged | Leave a comment

Evernote的故事

本人很喜欢Evernote这个云端记事本,不管是电脑还是手机都装了它的客户端,并且还写了Net::Evernote的Perl客户端库。当然Net::Evernote还很简单,有时间我会逐步完善它。

Phil Libin 还记得他将童年落在身后的那一刻。这大概是四年前,那时候他的互联网公司集资失败。那时候的他,35岁。

这个公司曾经给他带来了无数喜悦,直到集资失败的那一刻。在凌晨三点,因为资金耗尽,他已经无助地等了很久,等待一个风险投资家或者天使投资或者一 个CEO或者任何一个人来回应他绝望的请求,但是什么都没有等到。他知道他需要关闭Evernote,一个帮助人们记住事情的软件应用。“我意识到我将在 明天早晨醒来,然后解雇公司里的每一个人。”他说。

筋疲力尽士气低落的他正准备伸手去关上灯的开关,突然他的邮件提醒响了。他心中瞬间升腾起希望——但是,不,只不过是一个粉丝的消息而已,最近他已 经看过太多这样的消息。这个消息是来自于Sweden的一个人,一个同行的软件企业家,他发的消息和往常的粉丝发的消息一样,不过是“Evernote改 变了我的生活”诸如此类。Libin差点就错过了消息的最后一行:“如果你需要资金的话,可以联系我。”

Libin稍微有些清醒了,他很快回复:“我们现在正好需要一些资金。你能提供多少?”

回复立刻就来了:“50万美元够吗?”

更多阅读:http://www.chinaz.com/news/2012/0104/230091.shtml

Posted in 未分类 | Tagged | Leave a comment

哪些知名创业公司在用Gmail

留意到国外的创业公司绝大多数都在用Gmail作为企业的电子邮箱服务,至少如下知名互联网企业是用的Google企业邮局:

Evernote.com: 流行的云记事本
Dropbox.com: 最热门的云存储
Cloudflare.com: 非常好用的免费CDN
Github.com: 近来很火的代码托管服务
Groupon.com: 团购网鼻祖
Tumblr.com: 轻博客鼻祖
Instagram.com: 最有名的手机照片分享应用
Quora.com: 知识问答社区
Color.com: 照片分享社区
Box.com: 云存储
Cloudns.net: 免费DNS
Fab.com: 创意产品闪购网站
Soundcloud.com: 云端音乐

Gmail的确是做的很完美的一个产品,除了在中国经常被墙导致访问不了外,几乎找不到它的任何缺点。

Posted in 未分类 | Tagged | Leave a comment

检查ZONE的序列号一致性

某个域的DNS服务器通常有多台,保证这多台DNS的数据同步非常重要,避免因为数据不一致而造成解析上的失误。写了一个小Perl模块DNS::SerialNumber::Check用来验证这个一致性,在我的CPAN目录里:

http://search.cpan.org/~yhpeng/

用法很简单:

  1. use DNS::SerialNumber::Check;
  2. my $sn = DNS::SerialNumber::Check->new;
  3. my $re = $sn->check(“dnsbed.com”);

在Perl脚本里,第一句加载这个模块,第二句创建一个对象,第三句调用对象的check方法,它的参数是要检查的域名例如dnsbed.com。方法的作用是检查某个域名的各个权威服务器的ZONE序列号是否一致。

也可以指定域名的NS服务器名字或IP进行检查:

  1. $re = $sn->check(“dnsbed.com”,['ns1.dnsbed.com','ns2.dnsbed.com']);

显示检查的结果:

  1. print $re->status;

如果打印1,则说明各NS服务器的序列号都一致,如果是0,就说明不一致。

  1. use Data::Dumper;
  2. print Dumper $re->info;

最后,这个$re->info返回参考信息,包含各NS服务器的名字以及它们对应的序列号。

一个用途是用这个模块写一个Nagios插件,检查ZONE的序列号一致性,有问题就触发报警。

Posted in 未分类 | Tagged | Leave a comment

也谈谈Apache与Nginx

不断有人跟我说Nginx比Apache好、比Apache快之类。Nginx更主要是作为反向代理,而非WEB服务器使用。我翻译过一本关于反向代理的技术书籍,同时精通Apache API开发,对Nginx和Apache的工作原理都略有了解,粗谈一下看法。

不管是Nginx还是Squid这种反向代理,其网络模式都是事件驱动。事件驱动其实是很老的技术,早期的select、poll都是如此。后来基于内核通知的更高级事件机制出现,如libevent里的epoll,使事件驱动性能得以提高。事件驱动的本质还是IO事件,应用程序在多个IO句柄间快速切换,实现所谓的异步IO。事件驱动服务器,最适合做的就是这种IO密集型工作,如反向代理,它在客户端与WEB服务器之间起一个数据中转作用,纯粹是IO操作,自身并不涉及到复杂计算。反向代理用事件驱动来做,显然更好,一个工作进程就可以run了,没有进程、线程管理的开销,CPU、内存消耗都小。所以Nginx、Squid都是这样做的。当然,Nginx也可以是多进程 + 事件驱动的模式,几个进程跑libevent,不需要Apache那样动辄数百的进程数。Nginx处理静态文件效果也很好,那是因为静态文件本身也是磁盘IO操作,处理过程一样。至于说多少万的并发连接,这个毫无意义。我随手写个网络程序都能处理几万的并发,但如果大部分客户端阻塞在那里,就没什么价值。

再看看Apache或者Resin这类应用服务器,之所以称他们为应用服务器,是因为他们真的要跑具体的业务应用,如科学计算、图形图像、数据库读写等。它们很可能是CPU密集型的服务,事件驱动并不合适。例如一个计算耗时2秒,那么这2秒就是完全阻塞的,什么event都没用。想想Mysql如果改成事件驱动会怎么样,一个大型的join或sort就会阻塞住所有客户端。这个时候多进程或线程就体现出优势,每个进程各干各的事,互不阻塞和干扰。当然,现代CPU越来越快,单个计算阻塞的时间可能很小,但只要有阻塞,事件编程就毫无优势。所以进程、线程这类技术,并不会消失,而是与事件机制相辅相成,长期存在。

总结之,事件驱动适合于IO密集型服务,多进程或线程适合于CPU密集型服务,它们各有各的优势,并不存在谁取代谁的倾向。再盲目的言之Nginx可以取代Apache的,该好好反思了。

Posted in 未分类 | Tagged | Leave a comment

为什么com和net使用一组相同的名字服务器

我们执行如下dig:

$ dig +short com ns |sort
a.gtld-servers.net.
b.gtld-servers.net.
c.gtld-servers.net.
d.gtld-servers.net.
e.gtld-servers.net.
f.gtld-servers.net.
g.gtld-servers.net.
h.gtld-servers.net.
i.gtld-servers.net.
j.gtld-servers.net.
k.gtld-servers.net.
l.gtld-servers.net.
m.gtld-servers.net.
Continue reading

Posted in 未分类 | Tagged | 2 Comments

idig命令

idig是我在Linux里最常用的工具,它的好处是按标准DNS RR格式打印DNS ANSWER的内容。

我也做了一个艰难的决定,决定公开它的源代码,它的全部源代码是:

#!/bin/sh
[ -z $1 ] || dig +nocmd $@ +noall +answer

Posted in 未分类 | Tagged | 2 Comments

谁负责NS记录的权威解析?

今天有个读者来信问我,是本域的权威名字服务器,还是上一级名字服务器来权威应答域的NS记录?
这个问题正好借用腾讯DNS的不正确配置来回答。
早前一阵,我发现QQ的DNS配置有点问题,我们执行如下两个dig:

$ dig www.qq.com ns @ns1.qq.com

; <<>> DiG 9.4.2-P2.1 <<>> www.qq.com ns @ns1.qq.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50734
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;www.qq.com.                    IN      NS

;; ANSWER SECTION:
www.qq.com.             86400   IN      NS      ns-tel1.qq.com.
www.qq.com.             86400   IN      NS      ns-tel2.qq.com.

;; AUTHORITY SECTION:
qq.com.                 86400   IN      NS      ns4.qq.com.
qq.com.                 86400   IN      NS      ns1.qq.com.
qq.com.                 86400   IN      NS      ns2.qq.com.
qq.com.                 86400   IN      NS      ns3.qq.com.

;; Query time: 7 msec
;; SERVER: 219.133.62.252#53(219.133.62.252)
;; WHEN: Sat Jul  9 08:58:38 2011
;; MSG SIZE  rcvd: 144 Continue reading

Posted in 未分类 | Tagged | Leave a comment

一个错误的DNS系统设计

测试了下某个DNS系统,查询如下:

$ dig mytest.blogchina.org @ns1.dnsv5.com

; <<>> DiG 9.4.2-P2.1 <<>> mytest.blogchina.org @ns1.dnsv5.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24560
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;mytest.blogchina.org.          IN      A

;; AUTHORITY SECTION:
mytest.blogchina.org.   600     IN      NS      ns2.dnsv5.com.
mytest.blogchina.org.   600     IN      NS      ns1.dnsv5.com. Continue reading

Posted in 未分类 | Tagged | Leave a comment

一个非常隐晦的DNS故障

现在是凌晨4点,处理珠海机房的烂事情,并顺便写下这篇博客。希望我的头脑是清醒的。

很多人跟我反馈,他们的DNS系统基本工作正常,但偶尔不正常,不知道是哪里出了问题。

这种现象,很可能与胶水记录有关,NS的胶水记录(glue)与权威记录不一致,导致查询异常。

对于顶级域名如example.com,它的胶水记录就是在上一级DNS里注册的记录,见我前一篇博文“为什么DNS服务器必须注册”。假设注册了如下NS服务器: Continue reading

Posted in 未分类 | Tagged | Leave a comment