Network Programming

October 27, 2010

XSSに強いウェブサイトを作る – テンプレートエンジンの選定基準とスニペットの生成手法 (第1回神泉セキュリティ勉強会発表資料)


October 16, 2010

My Slides at YAPC::Asia 2010 (Writing Prefork Servers / Workers, Unix Programming with Perl)

The slides I used for my presentations at YAPC::Asia 2010 are now available from the links below. Thank you to those who came, and JPA and the volunteer stuff for running the event. I hope you enjoyed (will enjoy) my slides!

August 17, 2010

Releasing Starlet 0.10, now runs faster than ever

Last Sunday my friend told me that Starman is now way faster than Starlet and I started to wonder why.  There should not be such a difference between the two servers, sicne they share a lot in common.  So I looked into the code yesterday, found the bottleneck and fixed them, as well as adding some tweaks.  Here's what I did, and the chart[1] shows how the performance changed.


1) optimize the calculation of Content-Length

Plack::Middleware::ContentLength was the larget bottleneck.  Instead of calling the module Starlet now calculates the Content-Length header by itself in a faster way, when and only when necessary.

2) use TCP_DEFER_ACCEPT on linux

TCP_DEFER_ACCEPT is a flag that suppresses the return of accept(2) until any data arrives on a newly-established TCP socket.  By using the flag, same number of HTTP requests can be handled by a smaller set of workers, since they do not need to poll waiting for HTTP requests to arrive on non-keepalive connections.  The fact leads to less memory pressure and higher performance.  Starlet turns on the flag by default.

3) switch from alarm to select-based polling

Apps can now use alarm for their own purposes.

4) reuse the fake psgi.input

An optimization copied from Starman.

5) merge short content-length with response headers

It is sometimes faster to merge data within perl and send them as a single packet than sending the two separately.  BTW, anyone going to write a wrapper for writev(2)?

The conclusion is that Starlet is still a good choice if you are looking for an application server that runs behind a reverse proxy, maybe better than Starman until miyagawa-san copies the optimizations back :-p

NOTE 1: The benchmark was taken on linux-2.6.32 (x86_64), using a single core of Core 2 Duo running at 3GHz.  The options used were "ab -c 50", "plackup -s Starlet --max-reqs-per-child=10000", "--workers=64" for keepalive and "--workers=16" for non-keepalive.

July 02, 2010

Writing a Fast and Secure HTTP Parser (in the case of HTTP::Parser::XS)

In May, I had a chance to give a talk at Tsukuba.xs Beer Talks #1.  I forgot to upload the slide since then, but finally, here it comes :-p

The slide titled "HTTP::Parser::XS - writing a fast & secure XS module" covers the design and implementation of HTTP::Parser::XS: an XS HTTP Parser that is used by a number of Plack-compatible web servers, and picohttpparser: its underlying HTTP parser written in C.

My intention was to introduce to programmers who mostly use Perl the fun of writing tight (fast and beautiful) code using the C programming language.  It would be grateful if you could feel some of my addiction from the slides.  Enjoy!

PS. And if you find any security holes or bugs, please let me know. Thank you in advance.

April 24, 2010

REST におけるトランザクションについて (Re: Web を支える技術)


Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESSプラスシリーズ)(山本 陽平) - ただのにっき(2010-04-23)

Web を支える技術」は自分もとてもいい本だと思う (教科書としてすばらしいし復習用としても読みやすいのでイイ) のですが、トランザクションの所だけは分かりづらいなと感じました。その原因は、atomic transaction で解決できる課題を例として使っているという点と、トランザクションと更新クエリのレイヤ分割がされていない、という2つの点によるものではないでしょうか。

HTTP 上でトランザクションを表現する必要があるケースのほとんどは、atomic transaction ではなく、2相コミットもしくは long-running transaction を行う場合だと思います。

たとえば、HTTP 上で2層コミットを行っているシステムの代表例としては、おさいふケータイのチャージ機能が挙げられます (あれって HTTPS ですよね?)。また、たとえば、数量に限定がある商品を課金代行サービスを使って販売する場合等においては、long-running transaction が必須になります。

なので、トランザクションレイヤを RESTful に表現する手法は理解しておいて損がないものだと思います。具体的には、

  • トランザクションの開始は POST を使ったトランザクションリソースの生成
  • トランザクション開始後は POST ではなく PUT を使い、クライアントがリクエスト ID を指定することで、ネットワーク障害への耐性を確保
  • トランザクションのコミットも再送可能じゃないと困るので PUT
  • コミットの返り値を確認してからトランザクションリソースを DELETE


以下、具体例として、「アライブドアチケット」というチケット販売サイトから、ミュージカル「夜のhidek様」のチケット (2010年5月24日の公演) を購入する例を示します。支払いには Yappo! ペイメントを利用します。


GET夜のhidek様/seats-left HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json

  "seats-left": 11


Content-Length: 0

HTTP/1.1 201 Created

次に、座席を確保します。サーバは席が確保できれば「201 Created」を、既に満席になっていれば「409 Conflict」を返します。

Content-Type: application/json

  "url"    : "夜のhidek様",
  "seats"  : 2

HTTP/1.1 201 Created



HTTP/1.1 200 OK
Content-Type: application/json

  "amount": "10000",
  "currency": "JPY"

次に、クライアントは Yappo! ペイメントを使って、アライブドアチケットの口座に指定された金額を振り込みます。振込が完了すると、Yappo! ペイメントは振込IDを返すので、その振込IDを指定してトランザクションをコミットします。

Conetnt-Type: application/json

  "payment_id" : ""

HTTP/1.1 200 OK

「200 OK」が返ってきたので、支払が完了し、取引が成立したことがわかります (失敗した場合は「409 Conflict」が返ってくるでしょう)。最後にトランザクションリソースを削除します。


HTTP/1.1 200 OK

以上のような流れになると思います。「夜のhidek様」言いたかっただけ (ry

処理の対象となるリソース (上の例では夜のhidek様) が、トランザクション中の Request-URI に含まれていないのが気持ち悪い、という意見もあるかもしれません。ですが自分は、トランザクションリソースを使う場合は、HTTP はトランザクション処理に専念、HTTP 上のペイロードで処理対象のリソースを表現する方が、レイヤが分かれるので良いと考えます。

December 01, 2009

TCP通信ではデータの送信をまとめて行うべき、もうひとつの理由(& サーバのベンチマーク手法の話)







 自分が昨日の #12 で「サーバプログラムはリモートホストからベンチマークすべき注2」と主張したのは、以上に基づき、不要なコンテクストスイッチを避けるべき、という考えからです。今、手元にいいデータがないのですが、サーバとベンチマークプログラムの両者を同一ホスト上で動かした場合のみ、コンテクストスイッチが頻発しパフォーマンスが低下するケースがあったと記憶しています注3


注1: 確か linux 2.6.18 で測定。TCP_NODELAY はセットしています
注2: 「実際の利用形態がリモートホストからのアクセスになるのであれば」とすべきかも
注3: 例えばマルチスレッドなサーバとマルチスレッドなクライアントだと速度が落ちると思います
注4: 最大スループットを必要とするような大規模の運用では、通常リモートホストからサーバを利用すると考えられるため

October 05, 2009

Apache で X-Reproxy-URL ヘッダを使えるようにするモジュール mod_reproxy を書いた

ウェブアプリケーションにおいて、認証がかかっている画像や大きなファイルを配信する場合には、Perlbal 等でサポートされている X-Reproxy-URL ヘッダが有効なことが知られていて、その理由としては、

  • (メモリを大食いする) アプリケーションサーバのプロセスを転送終了まで占有しない
  • HTTP ベースの分散ファイルシステムとリバースプロキシが直接交信するので、ネットワーク負荷が低い

といった点が挙げられます。「でも、Apache は X-Reproxy-URL ヘッダをサポートしてないんだよねー」という話が、先日の YAPC::Asia 2009 においても話題になっていました[要出典]。回避策としては、ワンタイムURLのような手法もあるのですが、セキュリティな懸念もあります。

なんとかしたいなと思っていたのですが、気が向いたので、Apache に X-Reproxy-URL ヘッダ対応機能を追加するモジュール mod_reproxy を書いてみました。Github に置いてあります。

kazuho's mod_reproxy at master - GitHub

使い方は簡単。ダウンロードして、apxs を使って、コンパイル&インストールを行います。

# apxs -i -a -c -Wc,-Wall -Wc,-g -Wc,-O2 -lcurl mod_reproxy.c

その後、Apache の設定ファイルに

Reproxy On

と追記すれば、その追記した範囲において、X-Reproxy-URL ヘッダによる内部リダイレクトが有効になります。


参考: lighttpd の X-Sendfile を使えるApacheモジュール - spiritlooseのはてなダイアリー

September 22, 2009

「サーバ書くなら epoll 使うべき」は、今でも正しいのか

 多数のTCP接続をハンドリングするサーバを書くなら、1コネクション1スレッドのモデルではなく、epollやkqueueのようなイベント駆動型のI/O多重化を行うべきだ、と言われます。だが、そのような主張は、「C10K問題」が書かれた2002年から7年経過した今でも有効なのでしょうか? echoサーバを書いて、ベンチマークを取ってみることにしました。


  • epoll も per-thread モデルも、良くスケールする
  • epoll は、ワークセットが小さい場合に (最大50%) per-thread モデルよりも高速



注1: イベント駆動モデルでは、ファイルシステムへのアクセス等も非同期 /Oを使用して書く必要があります
注2: mycached は、このケース

参考: 軽量スレッドブームだと思うので、そこらへんの情報をまとめてみる, Thousands of Threads and Blocking I/O, Completely Fair Scheduler によるマルチプロセッシング

August 26, 2009

Picoev: a tiny event loop for network applications, faster than libevent or libev

I am sure many programmers writing network applications have their own abstracting layers hiding the differences between various I/O multiplex APIs, like select(2), poll(2), epoll(2), ... And of course, I am one among them.  While writing mycached (see Mycached: memcached protocol support for MySQL for more information), I was at first considering of using libev for multiplexing socket I/Os.  Libevent was not an option since it does not (yet) provide multithreading support.

But it was a great pain for me to learn how to use libev.  I do not mean that its is an ugly product.  In fact, I think that it is a very well written, excellent library.  However, for me it was too much a boring task to learn how the things are abstracted, already being familiar with the problems it tries to hide.

So instead I thought it might be a good occasion to write my own library that could be used in any programs I may write in the future.  The result is picoev, and it is faster than libevent or libev!  The benchmark used is a re-modified version taken from and can be found here.

Why is it faster?  It is because it uses an array and a ring buffer of bit vectors as its internal structure.  Libevent and libev seem to use some kind of sorted tree to represent file descriptors.  However, if we concentrate on Un*x systems, there is a guarantee that the descriptors will a small positive integer.  Picoev utilizes the fact and stores information related to file descriptors (such as pointers to callback functions or callback arguments) in an array, resulting in a faster manipulation of socket states.

Another optimization technique used by picoev is not to use an ordered tree for keeping timeout information.  Generally speaking, most network applications do not require accurate timeouts.  Thus it is possible to use a ring buffer (a sliding array) of bit vectors for the purpose.  Each bit vector represents a set of file descriptors that time-outs at a given time.  Picoev uses 128 of bit vectors to represent timeouts, for example, the first bit vector represents the sockets that timeout a second after, the second bit vector representing them of two seconds after..., and the bit vectors slide every second.  If the maximum timeout required by the web application is greater than 128, the minimum granurality of timeout becomes two seconds.

I would like to reiterate that both libevent and libev are great libraries.  Picoev is not at comparable to them especially in maturity and the number of features.  It only supports select(2), epoll(2), and kqueue(2) for the time being.  However the design is simple than the other two, and I think it will be a good starting point to write network applications, or to use as a basis for writing one's own network libraries.

If you are interested in using picoev, the source code can be found at

Mycached: memcached protocol support for MySQL

It is a well-known fact that the bottlenecks of MySQL does not exist in its storage engines, but rather in the core, for example, its parser and execution planner.  Last weekend I started to wonder how fast MySQL could be if those bottlenecks were skipped.  Not being able to stop my curiousity, I started  adding memcached proctol support to MySQL as a UDF.  And that is Mycached.

From what I understand, there are two advantages of using mycached (or the memcached protocol, in general) over using SQL.  One is faster access.  The QPS (queries per second) of mycached is roughly 2x compared to using SQL.  The other is higher concurrency.  As can be seen in the chart below, mycached can handle thousands of connections simultaneously.

And the lack of the described advantages has been the reasons for large-scale web applications to use memcached, even though it requires application developers to take care of keeping consistency between mysql and memcached.  In other words, mycached could become a good alternative here.

Mycached is still in very early stage of development.  I would never recommend using current version in a production environment, but if you are interested, the details of how to use it is as follows.

Source code of mycached is available at  There is no Makefile or configure script yet, use GCC directly to create the UDF.  Source code of mysql is needed and should be set as include directories (you need to run make on the source code of mysql prior to compiling mycached).

% g++ -DMYCACHED_USE_EPOLL=1 -shared -fPIC -Wall -g -O2 -I ~/test/mysql-5.1.37/src/include -I ~/test/mysql-5.1.37/src/sql -I ~/test/mysql-5.1.37/src/regex -o

Once the compilation succeeds, copy the shared library into the plugins directory of the lib directory of mysql, and use the CREATE FUNCTION statements to activate the necessary UDFs.  And to start mycached, call mycached_start.  The function takes three arguments: host, port, and number of worker threads to be used for handling requests.  To stop the mycached, call mycached_stop().

mysql> CREATE FUNCTION mycached_start RETURNS INT SONAME '';
mysql> SELECT mycached_start(0, 11211, 4);

The only memcached command currently supported by mycached is get (but you can do other things using SQL :-p).  As the following example shows, specify more than one db_name.table_name.primary_key to fetch a row of a table, separated by a whitespace.  The returned value will be a repetition of columns, each of them in the format of column_name:value_length:value.  It is also possible to specify JSON as the response format by adding ":JSON", however it will be slower, since the server needs to convert the values of the columns to UTF8 and to escape them.

$ telnet localhost 11211
Connected to localhost.localdomain (
Escape character is '^]'.
get test.t1.1
VALUE test.t1.1 0 68
id:1:1message:51:hello world! hello world! hello world! hello world!
get test.t1.1:json
VALUE test.t1.1 0 72
{"id":1,"message":"hello world! hello world! hello world! hello world!"}

Thank you for reading.  If you have any ideas or suggestions, please leave a comment.