Thursday, February 19, 2015

H2O, the new HTTP server goes version 1.0.0 as HTTP/2 gets finalized

I am happy to announce the release of H2O version 1.0.0 on the same day HTTP/2 gets finalized. The momentum for HTTP/2 is building up fast.

According to mnot’s blog: HTTP/2 is Done posted today,
The IESG has formally approved the HTTP/2 and HPACK specifications, and they’re on their way to the RFC Editor, where they’ll soon be assigned RFC numbers, go through some editorial processes, and be published.
Web browser developers have already implemented the protocol. Mozilla Firefox is already providing support for the HTTP/2 draft. Google has announced that they would turn on support for HTTP/2 on Chrome within weeks. Internet Explorer 11 on Windows 10 Technical Preview also speaks HTTP/2.

Considering the facts, it seemed that we'd better freeze the configuration directives of H2O now, so that people could rely on the software for serving HTTP/2 requests (note: the library API should still be considered unstable).

Features provided by H2O version 1.0.0 include the following; please refer to the README and `--help` for more information.

  • support for HTTP/1.x and HTTP/2
  • static file serving and reverse proxy
  • HTTP/2 server-push
  • excellent performance outperforming Nginx
  • graceful restart and self-upgrade via Server::Starter

Started last summer, H2O is still a very young project. We would never have advanced this fast without so much help from the community (the fact is clear especially regarding the support for HTTP/2 if we look at H2O issue #133 as an example). I would like to express my gratitude for their advises and suggestions.

We plan to continue improving H2O rapidly. The primary focus is on performance, ease-of-use, and flexible (even autonomous) reconfiguration that suites the cloud era.

Today, HTTP is facing challengers. With the rise of smartphone apps, it is no longer the only protocol that can be used. But wouldn't it be better if we could all continue using a single, well-known protocol a.k.a. HTTP?

Our goal is by providing an excellent implementation, to keep the protocol as the primary choice of the developers, and furthermore, to expand the adoption of HTTP even more than before.

Stay tuned!

Tuesday, February 17, 2015

Writing signal-aware waitpid in Perl

As I have talked in YAPC::Asia couple of years ago, the wait functions (e.g. wait, waitpid) of Perl do not return EINTR when receiving a signal.

This is a problem if you would want to wait for child processes until receiving a signal. Proc::Wait3 can be a solution, however the module may be hard to install as it is an XS module. It should also be noted that the module provides replacement for wait only; no workaround exists for waitpid.

So today I have scrubbed my head wondering if I could come up with a pure-perl solution, and, here it is. The Perl script below launches a worker process (that just sleeps), and waits for the process to complete, or until SIGTERM is being received.

use strict;
use warnings;
use Errno ();

our $got_sigterm = 0;
our $sighandler_should_die = 0;

# fork a child process that does the task
my $child_pid = fork;
die "fork failed:$!"
    unless defined $child_pid;
if ($child_pid == 0) {
    # in child process, do something...
    sleep 100;
    exit 0;
}

$SIG{TERM} = sub {
    $got_sigterm = 1;
    die "dying to exit from waitpid"
        if $sighandler_should_die;
};

warn "master process:$$, child process:$child_pid";

# parent process, wait for child exit or SIGTERM
while (! $got_sigterm) {
    if (my_waitpid($child_pid, 0) == $child_pid) {
        # exit the loop if child died
        warn "child process exitted";
        $child_pid = -1;
        last;
    }
}

if ($child_pid != -1) {
    warn "got SIGTERM, stopping the child";
    kill 'TERM', $child_pid;
    while (waitpid($child_pid, 0) != $child_pid) {
    }
}

sub my_waitpid {
    my @args = @_;
    local $@;
    my $ret = eval {
        local $sighandler_should_die = 1;
        die "exit from eval"
            if $got_sigterm;
        waitpid($args[0], $args[1]);
    };
    if ($@) {
        $ret = -1;
        $! = Errno::EINTR;
    }
    return $ret;
} 

The trick is that waitpid is surrounded by a eval within the my_waitpid function, and the signal handler calls die to exit the eval if the $sighandler_should_die flag is being set. It is also essential to check the $got_sigterm flag within the eval block after setting the $sighandler_should_die flag, since otherwise there would be a race condition.

By using these tricks it has now become possible to implement process managers in pure-perl!

Tuesday, February 10, 2015

[Ann] H2O version 0.9.2 released incl. support for HTTP2 server-push, state-of-art prioritization of streams

I am glad to announce the release of H2O version 0.9.2.

This is the third release of H2O, including a number of changes that can be found in the Changes file. And here, I am happy to mention that some of the changes were brought by other people than me, in fact five people have committed into improving the H2O since the last release, whose names can also be found at the top of the README.

Among the changes introduced in version 0.9.3 are improvements to the HTTP/2 protocol implementation.

HTTP/2 Server Push

As of version 0.9.2, H2O automatically pushes content using HTTP/2 server push when suggested by the upstream server using the link:rel=preload header. By using the feature, web applications can push resources mandatory for rendering the web pages on the client side, which results in faster perceived response time from the end-users viewpoint. In other words, web application developers are encouraged to list the files that block the rendering using the link: rel=preload header for optimum rendering speed.

Below is an example of a response sent by a web application running behind H2O. H2O recognizes the link header and starts to push the contents of /assets/main.css even before the client recognizes that the CSS is a blocker for rendering the webpage.
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Link: </assets/main.css> rel=preload


It is also worth noting that H2O is not alone in providing support for HTTP/2 server push. Following the discussion on an H2O issue discussing the topic, nghttp2 has added support for server-push using the same header as well. What's good here is that the developers are working together on HTTP/2 to provide a logical and a vendor-neutral way of providing access to the new technology; I am so happy to be part of the effort.

Improved Scheduler for HTTP/2 Streams

The HTTP/2 specification defines a somewhat complex logic for prioritizing the streams. In H2O version 0.9.3 we have polished up the scheduler implementation used for the purpose. H2O now is not only highly compliant to the specification implementing all the aspects of the specification, but also excels in performance as the internal code-paths are guaranteed to be O(1).

Implementation of the prioritization logic fully conforming to the specification is essential for a HTTP/2 server, since web browsers would be tuned against the specification. We may see unnecessary delays in page rendering speed if any error (or missing parts) exist within the server program. I am glad that H2O is unlikely to fall into such problem now that we have a complete implementation.


I am pleased that all the changes have been done within three weeks since last release. And my thank you goes to the contributors and the people who have gave us advises on improving the product.

Please stay tuned for the next release!

Thursday, February 5, 2015

なぜ今、新しいHTTPサーバが必要なのか - H2O について勉強会で話したこと

先月末の話になりますが、SAPジャパンさんを会場に開催されたデータ転送ミドルウェア勉強会で、私が中心になって開発しているHTTPサーバ「H2O」について話す機会をいただき、登壇してきました。

以下は当日使用したスライドです。なぜ今H2Oを開発しているのか、その背景にある現状認識と将来の方針について、日本語で説明してあるので、興味ある方はご覧ください。


発表の機会をくださった@repeatedlyさんと@frsyukiさん、会場を提供してくださったSAPジャパンさん、ありがとうございました。

H2Oの開発は順調に進んでおり、HTTP/2サーバプッシュへの対応も完了し、まもなく次のバージョンがリリースできるかと思います。今後ともよろしくお願いいたします。

Tuesday, January 20, 2015

H2O version 0.9.1 released with support for HTTP2 dependency-based prioritization

Today I am pleased to announce the release of H2O version 0.9.1. The release tar-ball can be found in the releases section of the GitHub repository.

H2O is an optimized HTTP server with support for HTTP/1.x and the upcoming HTTP/2 protocol.

Version 0.9.1 contains many improvements that have gone into the source tree since the initial release, including contributions by people other than the original developers. I am very happy and thankful to those who have started sending pull-requests to H2O.

The full list of the changes can be found in the changelog. But on this blogpost I would like to concentrate on the issues regarding HTTP/2.

■Support for draft-16

H2O version 0.9.1 supports both draft-14 and draft-16. Draft-16 is the latest draft of HTTP/2, now at the final stage of becoming an RFC standard. Draft-14 is still supported for interoperability with older user-agents.

■Dependency-based prioritization

Dependency-based prioritization is one of the key functions of HTTP/2. It allows the web browsers to control the order in which the server sends the responses (e.g. send CSS files before HTML). Firefox/37 is going to start using the prioritization method, and we are happy to be able to support it. For more information about dependency-based prioritization and how it would be used, I would suggest reading Bits Up!: HTTP/2 Dependency Priorities in Firefox 37.

As Mozilla has enabled HTTP/2 by default in Firefox/35, it is now possible to take the benefit of using HTTP/2 to serve contents to the users faster than ever. I hope that H2O could be of some help in doing so.

Thursday, January 15, 2015

[メモ] TCP上(もしくはHTTP)にリトライ可能なアプリケーションプロトコルを実現する方法

HTTP/1.1の持続的接続においては、サーバがリクエストを受け取ったあとに異常終了したのか、リクエストを受け取らずに接続を閉じたのか判別することができない。このため、べき等性の保証がないアプリケーションにおいて、リトライを行うべきか否か自動的に判断できなくなる場合がしばしば発生する

リトライ可能か否か(ピアがメッセージの処理を開始した否か)を判別するには、より細かな情報交換を行う別種のプロトコルを採用しても良いが、複雑なプトロコルはパフォーマンスに悪影響を及ぼす可能性が高いので避けたいところである。

というわけで、以下本題。

pipeliningを行わないHTTP/1.1のような単純なリクエスト/レスポンス型プロトコルをそのままに、アプリケーションレイヤへのリクエスト到達可否を判定する手軽な方法としては、SO_LINGERを用いる方法がある。具体的には、以下のような形式でサーバを実装する。
while (1) {
  receive_request();
  use_RST_for_close(); // SO_LINGERを使い、RSTで切断するよう設定
  handle_request();
  send_response();
  use_graceful_close(); // SO_LINGERを使い、graceful closeを行うよう設定
}
クライアントサイドでは、リクエスト送信後にEPIPE(write(2)の場合)かECONNRESET(read(2)の場合)を受け取った場合のみ、リクエストを再送すればよい。

別解としては、サーバが接続を切断する際に「HTTP/1.1 599 Going Away」のようなレスポンスを(たとえリクエストを受信していなくとも)送信するという方法が考えられる(この場合はlingering closeを行わない)。クライアントは、サーバからこのレスポンスを受信した場合のみ、リクエスト再送を行えば良い。

追記: H2Oでは後者の方式をサポートしようかと考えている。そうすれば「Docker と SO_REUSEPORT を組み合わせてコンテナのHot Deployにチャレンジ - blog.nomadscafe.jp」で挙げられているようなデプロイ手法において、(例示されている常にリトライする方法とは異なり)安全なホットデプロイが実現可能になる。

注: パイプライン処理については行わない前提で考える

Friday, December 26, 2014

[Ann] Initial release of H2O, and why HTTPD performance will matter in 2015

Happy Holidays!

Today I am delighted to announce the first release of H2O, version 0.9.0; this is a christmas gift from me.


H2O is an optimized HTTP server with support for HTTP/1.x and the upcoming HTTP/2; it can be used either as a standalone server or a library.

Built around PicoHTTPParser (a very efficient HTTP/1 parser), H2O outperforms Nginx by a considerable margin. It also excels in HTTP/2 performance.



Why do we need a new HTTP server? The answer is because its performance does matter in the coming years.

It is expected that the number of files being served by the HTTP server will dramatically increase as we transit from HTTP/1 to HTTP/2.

This is because current techniques used to decrease the number of asset files (e.g. CSS sprites and CSS concatenation) becomes a drag in page rendering speed in HTTP/2. Such techniques were beneficial in HTTP/1 since the protocol had difficulty in utilizing all the available bandwidth. But in HTTP/2 the issue is fixed, and the overhead of transmitting all the images / CSS styles used by the website at once while only some of them is needed to render a specific page, becomes a bad idea. Instead, switching back to sending small asset files for every required element consisting the webpage being request becomes an ideal approach.

Having an efficient HTTP/1 server is also a good thing, as we large-scale adopt the idea of Microservices; it increases the number of HTTP requests transmitted within the datacenter.

As shown in the benchmark charts, H2O is designed with these facts in mind, making it (as we believe) an ideal choice of HTTP server of the future.

With this first release, H2O is concentrates on serving static files / working as a reverse proxy at high performance.

Together with the contributors I will continue to optimize / add more features to the server, and hopefully reach a stable release (version 1.0.0) when HTTP/2 becomes standardized in the coming months.

Stay tuned.

PS. It is also great that the tools developed by H2O is causing other effects; not only have we raised the bar on HTTP/2 server performance (nghttp2 (a de-facto reference implementation of HTTP/2) has become much faster in recent months), the performance race of HTTP/1 parser has once again become (Performance improvement and benchmark by indutny · Pull Request #200 · joyent/http-parser, Improving PicoHTTPParser further with AVX2), @imasahiro is working on merging qrintf (a preprocessor that speeds up the sprinf(3) family by a magnitude developed as a subproduct of H2O) to Clang. Using H2O as a footstep, I am looking forward to bringing in new approaches for running / maintaining websites next year.