Archive for 5月, 2008

Grizzlyの概要 : C10K問題に対応するGlassFish(Grizzly)

さて、おまたせ致しました。

本日より、JJUGで発表したGrizzlyについて紹介したいと思います。

まず、Grizzlyって聞いたことありますか?

「GrizzlyはGlassFishコミュニティの中のサブプロジェクトの1つで
JavaのNew I/Oを使って記述された汎用的なネットワークサーバエンジンです。」

Project Grizzly :
https://grizzly.dev.java.net/

Project Grizzlyによって開発された成果物(ネットワークサーバエンジン)は GlassFishとは独立して単体で使用することができます。また、Grizzlyは独自の進化を遂げていっています。現在、Grizzlyの最新バージョンは1.7.3.1です。

今回紹介するGrizzlyは少しバージョンが古いのですが、GlassFish v2.x系にバンドルされているGrizzly 1.0.x(1.0.19)について紹介します。

●Grizzly誕生の背景

まず、Grizzlyのできあがった背景について説明します。Grizzlyは元々GlassFishのHTTPをハンドリングするHTTPサーバを開発するプロジェクトとして開始しました。それまでのSunのアプリケーションサーバは、TomcatのCoyoteを内部で使用していたのですが、GlassFishではCoyoteを使用せずにJavaのNew I/Oを使用して実現するHTTPサーバとして実験的に作成を開始しました。
(Grizzly1.0.19でもHTMLの解析等で一部apacheのAPIを使用してます)

そして開発を進めて行くに従い、Grizzlyの潜在能力の高さが判明してき、HTTPだけではなく、他のプロトコルも扱うことのできる汎用的なネットワークサーバエンジンになりえることが分かってきました。その結果、現在ではHTTP以外にTCP,UDPといった下位のレイヤープロトコルを始めとし、TLS,FTPやSIP等といったマルチプロトコルに対応するハイパフォーマンスなネットワークサーバエンジンになっています。ですので、仮に開発者が新たに独自のネットワークサーバを構築する必要がでてきた場合、GrizzlyのAPIを一部拡張して実装して頂くことでハイパフォーマンスな独自ネットワークサーバを構築することも可能になっています。

例えば、GrizzlyのHTTPサーバエンジン以外の使用例として独自のsyslogサーバを構築することも可能になります。Grizzlyの背景とできることは上で説明しましたが、何故今ここでGrizzlyという新しいネットワークサーバエンジン(フレームワーク)が登場したのでしょうか。以下ではWebサーバの実装における過去の歴史とGrizzlyが登場した理由を説明します。

●Web サーバの実装における歴史
Webサーバは古くはCERN,NCSA等といった所で作成されていましたが、Apacheでhttpdが作成された後はApacheにシェアを奪われていきました。こういった古いWebサーバや初期のApache httpdはプロセス起動型のサーバの実装になっていました。

このプロセス起動型のサーバではHTTPクライアントであるブラウザからリクエストがくる度にhttpdのプロセスを起動しリクエスト数が多くなると子プロセスをfork()して処理を行っていました。当時のWebサーバは今程リクエスト数も多くなく、FastCGI等も無いこの時代にはサーバサイドで実行するプログラム(Perl,C等のCGI)もfork()して子プロセスで実行していました。

しかし、プロセスのfork()はシステム(OS)に対して多大な負担を掛けます。そこで登場したのがマルチスレッド型のサーバです。

マルチスレッド型のサーバでは単一のプロセス内でリクエスト毎にスレッドを起動し、各スレッドでHTTPの処理を行うことで、子プロセスを起動するよりシステムに対する負担は大幅に軽減するようになります。この頃になり、マルチスレッドサーバ上でサーバサイドで実行するプログラムとしてServletが脚光を浴びました。しかし、実際のWebサーバの実装は上に説明した程簡単ではありません。上記の図中にスレッドの起動プログラム例を記載していますが、Webサーバのように大量のリクエストを扱うようなプログラムの場合、accept()の処理は負荷はあまり掛からないのですが、スレッドの起動はaccept()の処理に比べ非常に負荷が高くなってしまいます。この状況ではパフォーマンスにボトルネックが生じます。

そこで、スレッドの起動に関する問題を軽減する為に、実際のWebサーバではaccept()処理とスレッドの処理を分離し、間に接続キューを設けることでaccept()の処理を素早く受け流すことができるようになります。(SunのWeb ServerはC++で上記のように実装)そして、実際にHTTPの処理を行うワーカスレッドが接続キューからコネクションを取得し、HTTPの処理を行うようになります。他のサーバの実装を細かく見たことはありませんが、恐らく現在のWebサーバの実装は似たような実装になっているのではないかと思います。

●マルチスレッドサーバの問題 (Blocking I/O型サーバ)
ソケット通信を行うプログラムを実装する場合、accept()やI/Oのread(),write()等を使用しますが、これらのメソッドは処理をブロックします。

例えば、ServerSocket#accept()メソッドはクライアントが接続するまで待ち状態になり、クライアントからの接続があって初めてメソッドの処理を終了します。複数のクライアントからの接続を処理できるようにする為には、サンプルのようにスレッドを生成し実際の処理は別スレッドで行うように実装します。このような実装の場合、接続してくるクライアントの数が増えれば増える程、大量のスレッドが生成されることになります。そして、スレッドが大量に生成される場合、大量のメモリが必要になってきます。下記のグラフではJavaでスレッド数を増やしていった場合に実際に必要なスレッドのスタックサイズを現していますが、これによると10,000スレッドを同時に生成した場合、約10Gバイトのメモリが必要になっています。また、2万スレッドになると約20Gバイトのメモリが必要になっていることがわかります。このように、単純にスレッドを増やしていくモデルのサーバはアクセス数が増えれば増える程大量のメモリを消費していくことがわかります。

●C10K問題を解決できるサーバ (Non Blocking I/O型サーバ)
GlassFish(Grizzly)は上記の問題を解決するためにNon Blocking I/Oを使用して実装が施されています。Non Blocking I/Oを使用するとスレッドの作成数を減らすことができます。

実際には、Java NIOではServerSocketChannel#accept()メソッドでaccept処理を行いますが、この処理はブロックしません。仮にこのメソッドが呼び出された時にクライアントからの接続がない場合は、すぐにnullを返します。ServerSocket#accept()メソッドのように処理をブロックしないので、クライアントのリクエスト毎に新たなスレッドを生成する必要もなくなります。言い換えると、ServerSocketChannel#accept()を呼び出した元のスレッドで引き続き処理を続けることができるようになります。

※ つまり複数のリクエストを処理するために、接続毎に新規スレッドを生成しなくてもよいようになります。

Grizzlyの開発者の1人であるJean-Francoisは次のように述べています。
「Grizzlyではたった30スレッドで10,000の接続を捌くことができます。」
This strategy prevent one thread per request, and enable Grizzly to server more that 10 000
concurrent users with only 30 threads.

●Asynchronus Request Processing(ARP)
さて、GrizzlyはJava New I/Oで実装されているだけでもすごいのですがさらに、ARPも実装されています。ARPはComeのアプリケーションや、ビジネスプロセスの処理にとても時間が掛かるような場合、つまり長時間接続を保持しなければならないアプリケーションの動作も実現できるように実装されています。APRも又1つの接続辺り1スレッドを消費しないように実装されているため、今までのマルチスレッドサーバ、Synchronus Request Processingに比べComet等のアプリケーションを実行する環境としても最適です。

●まとめ
Grizzlyは汎用的なネットワークサーバエンジンです。独自にサーバを構築する際はGrizzlyのフレームワークを再利用することでハイパフォーマンスな独自サーバを構築することが可能になります。GrizzlyはJava NIOで実装されARPに対応しているのでComet等のアプリケーションの実行環境としても最適です、そしてパフォーマンスも良いのです。GlassFish(Grizzly)を使用して新しい先進的なアプリケーションを作成してください。

最後に、今回はGrizzlyの概要について紹介しました。GlassFish(Grizzly)が何故パフォーマンスがよいのかの概要を掴んでいただけたのではないかと思います。次回は、さらに深くGrizzlyの内部の実装を知りたい方、もしくはJava NIOで実装されたサーバに興味のある方を対象に、Grizzlyのソースコード(Grizzly 1.0.19)の見方を紹介します。

広告

2008年5月15日 at 12:00 AM

GlassFish SDC連載記事4月号のアップデート情報



先月のSDCの連載記事で下記の記事を書きましたが、

連載記事のアップデート情報をPDF資料にまとめ、

ダウンロードできるようにしましたので、紹介します。



アップデート情報の入手はこちらから



本資料はSDCの記事で紹介したドメインの構成例を

具体的にコマンドライン、もしくは管理コンソールから

実行した例を示しています。ですので是非連載記事と

併せてご覧頂ければと思います。




SDC連載記事:

GlassFishではじめるアプリケーションサーバのかんたん構築

第2回:アプリケーションサーバの管理の基本



http://sdc.sun.co.jp/java/series/glassfish/200804.html

2008年5月14日 at 5:59 AM

GlassFish Enterprise Server 日本語マニュアル公開



皆様、嬉しいお知らせです。



GlassFish Enterprise Serverの日本語のマニュアルがdocs.sun.comに

公開されていました。



こちらの資料は私が所属する部署の方々による日本語レビューが済んでいます。

  #すいません、私は当時発表続きでレビューに参加できていません。(^_^;)



Sun Java System Application Server 9.1管理ガイド(日本語)

Sun Java System Application Server 9.1 高可用性(HA)管理ガイド(日本語)

Sun Java System Application Server 9.1配備計画ガイド(日本語)

Sun Java System Application Server 9.1クイックスタートガイド(日本語)



また、GlassFish日本語コミュニティの翻訳の方もかなり進んでいます。

中でも「カナさん」の御協力はすごいです!!

カナさんに訳していただいたコンテンツだけで下記のコンテンツがあります!!

カナさん、御忙しい中本当にありがとうございます!!!!





GlassFish 日本語翻訳プロジェクトについての進捗状況等の詳細



マイグレーションツールオンラインヘルプ:


マイグレーションツール概要

インストールと設定

マイグレーションするアプリケーションの準備



マイグレーションガイド:


標準でない JNDI 名を使用するローカル EJB 参照

WAR ファイル最上位にパッケージされるクラス

Facelets の利用

JBoss EJBQL != Glassfish(J2EE Spec) EJBQL

GlassFish Cache でエンティティとして参照される組み込みオブジェクト

GlassFish キャッシュリフレッシュ




2008年5月13日 at 4:45 AM

JJUG イベントの発表資料(Grizzly)



先日、開催されたJJUGのイベントで発表時に使用した資料を公開します。



恐らくJJUGでも同様の資料が公開されるかと思いますが、どちらから

リンクが貼られるかが分からないので念のため、自分のブログからも

取得できるようにしておきます。



本資料では、Grizzly1.0.x系の内部実装について詳しく紹介しています。

Grizzlyに興味のある方、Java NIOについて興味のある方は、

是非ご覧ください。



資料はこちらから



PS.

説明が無いと資料の内容を理解して頂くことは難しいとは思いますが、

説明は後日ということで。(^_^;)


2008年5月9日 at 5:30 AM

ゴールデンウィーク終了



皆様、GWは如何御過ごしでしたか?



今、サンフランシスコではJavaOne 2008が開催中ですが、

私は、今年は日本でゆっくりとGWを過ごささせていただきました。(^_^)




JJUGのイベントが終わり、それまでとても忙しい日々を送っていたのでGW中はゆっくり休みたい!!、

緑が見れる所に行きたい!!と考えたのですが、結局ガソリン代も高騰するこのご時世に、

車で石川まで行ってきました。(^_^;)


でも、深夜出発して高速の割引つかったり、帰りも輪島から長野まで下道を使ったりと

遠出ながらもかなり貧乏旅行してきました。(^_^;)

さすがに往復1,300Kmは車の運転好きな私もさすがにちょっと疲れましたぁ。。。



旅程:

飛騨→白川郷(世界遺産)→金沢兼六園→輪島の朝市










飛騨











白川郷











金沢の兼六園






輪島の朝市





PS.
JJUGで話をしたGrizzlyの詳細については、ブログで少しずつ

まとめていきたいと思いますので、暫く御待ちください。

2008年5月6日 at 11:30 PM

新しい投稿


Java Champion & Evangelist

Translate

ご注意

このエントリは個人の見解であり、所属する会社の公式見解ではありません

カレンダー

2008年5月
« 4月   6月 »
 1234
567891011
12131415161718
19202122232425
262728293031  

カテゴリー

Twitter

clustermap

ブログ統計情報

  • 1,152,960 hits

RSSフィード