Archive for 1月, 2012
今回は、あるオライリーの
MIND HACKS「実験で知る脳と心のシステム」
という本の紹介です。
ここで、いろいろな脳の仕組みを説明しているですが、
ちょっと、私的に気を引いたのが、表題のとおりの事です。
走っている自動車を見ると、タイヤは初めは進行方向に回転しているのですが、
突然、反対方向に回り始めます。(そう見えます。)
でも、これをキチンと説明して。と言われれば、?????となってしまいます。
ですが、この本を読めばわかるわけです。
たとえば、映像は1/24で構成されます。
速度が遅いときは、次の一コマは、現在よりちょっとだけ、進行方向に進むわけです。
しかし、速度が速い場合には、だいぶ進行方向に向かって回転します。
ただし、回転運動ですから、つまり、現在よりもちょっとだけ、反対方向に進んだともとれるわけです。
3300度回転は、反対方向に30度回転と同じ事です。
つまり、これを連続的に見れば、タイヤは反対方向に回転という事です。
まあ、映像は1/24だけど、実際の目では・・・・
と思うかもしれません。
そう、思っていたから私もこんな簡単な事を説明できなかった訳ですが、
普通の人が思っている当たり前っぽいことを、キチンと実験などを通じて説明しているのが、
この本のおもしろいところです。
もし、アニメーションを作っていてタイヤを早く回したいときには、
反対方向にゆっくりまわせばいいという事ですね。
さて、こんな事を知ってどうするの?
と思う方に、この本で書いてある別のちょっとおもしろいところを紹介。
人間は、聞きたいこと、みたいものを感覚を増幅して認識できる能力があります。
これは、「ノイズ」のおかげらしいのです。
人間はわざと、信号にノイズをのせて認識をすることで、
認識できないはずの正しい情報を間違えさせることにより、
認識レベルの情報まで引き上げているとの事です。
そして、それを他の情報をあわせて、認識をするので、
このノイズを乗せるという手法が有効になるという事です。
私たちコンピュータを扱う人達が、以下にある情報から、ノイズを削るのにやっきになって作業をしているというのに、
人間様は、その情報にわざとノイズを乗っけているというのですから、
ちょっと、残念なところです。
しかし、全く想像もしていないものがきっかけで、別の事実を知るみたいなことって、
結局、このノイズなのではないかと思います。
というわけで、ノイズの一つ通して、読んでみるのもよいのではないかと思った次第です。
Zimbraをインストールしてみました。
Zimbraというのは、Outlook みたいな環境をつくるためのオープンソースです。
これにあわせて、ムームードメインでドメインを取得し、新たなVPSサーバに設定をしてみました。
ドメインを新たに取得したのは、独自ドメインでのメール運用とかもGoogleさんとかで気軽にさせてもらえるようなので、
これを機に、もう一つ取得してみました。
さて、Zimbraですが、中身は、3rdパーティと、本体があるのですが、
メール送信はPostfixで、アカウント管理はOpenLDAPなどを使っているようです。
逆に、いままでインストールしてあったPostfixやApacheなどと競合してしまいます。
もちろん、POPやIMAPも公開しますので、そこでも競合します。
さらに、syslogでさえ、入れ替えようとします。
もちろん、インストール時に指定はできるようなのですが、
結局、それだと、自分で設定ファイルを編集しなければいけなくなると思うので、やめました。
また、インストールされたPostfixに設定を変えても、サービスの再起動で変更が取り消されてしまいます。
WEB UIでも設定画面があるので、そこがマスターとなっており、
書き換わってしまうのだと思います。
そういう意味では、既存の環境にインストールするのはちと面倒な感じです。
ただし、初期にこれらのLinuxの環境をするのが面倒である場合には、
けっこういいと思います。
まあ、トラブルがあったら、純粋な環境でないのでちと、面倒そうですが、
それでもまったくわからないものを触るよりもいいかもしれません。
あとは、個人的にはLDAPが動いているのは助かります。
あと、気になった点は、むちゃくちゃ、起動や停止が遅い。
(再起動で1分くらいかかっているような感覚です。あくまで感覚ですが・・・)
すべてのサービスの起動・停止をやっているのと、
JAVA関連が遅そうなのですが、
個別にサービスを再起動できるようになっていると助かります。
ただ、LDAPだけは、いつも面倒なので手をつけていなかったので、いいですね。
このLDAPを公開できれば、アカウント管理できるかも・・・・とちょっと思っています。
一般的に使われている信頼できるオープンソースを組み合わせて、
このような統合環境として管理できるのは、よいと思いました。
世の中のIMAPサーバがどのような状況(どんな機能を備えているのか?)なのか..
IMAP対応というのは、ちょっと前まではgmailぐらいしかなかったのですが、
スマートフォン対応ということで、いろいろなところが対応してきました。
しかし、相変わらずサービスのサイトを見ても、
たいていはPOP3の記述はすぐに見つかるのですが、IMAPの設定が見つかりません。
なぜでしょうか?、まだあまりつかってほしくはないのかな・・・・
ということで、実際、かくプロバイダのIMAPではどのくらいまでできるのか、
IMAPのCAPABILITYの結果を調べてみました。
調べた対象は
- gmail ( imap.gmail.com:993 )
- nifty ( imap.nifty.com: 993 )
- biglobe (mail.biglobe.ne.jp:993)
新しい環境です。去年の12月くらいに新しくなったそうです。 - Yahoo JAPAN (imap.mail.yahoo.co.jp:993)
まだIMAPは制限中とのことです。ログインまではできましたが、自分のメールボックスがありませんでした。 - さくらのメール(有料:年間1000円 – *****.sakura.ne.jp:993)
Gmail IMAPの結果
CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE
gmailは独自拡張があるので、ちょっと他のIMAPサーバとは毛色が違います。
ここにその拡張の仕様の記述がありますが、
なるほど、結構使えそうです。ただ、gmail専用のクライアント(もしくはモード)があるのであれば、使いやすいでしょう。
Niftyの結果
CAPABILITY IMAP4rev1 NAMESPACE AUTH=CRAM-MD5
NiftyはいつもWEBメールなどはかなり早くよい感じになってリリースされましたが、
ちょっとIMAPでの対応はいまいちのようです。
Biglobeでの結果
CAPABILITY IMAP4rev1 ACL BINARY CATENATE CHILDREN CONDSTORE ENABLE ESEARCH ESORT I18NLEVEL=1 ID IDLE LIST-EXTENDED LIST-STATUS LITERAL+ LOGIN-REFERRALS MULTIAPPEND NAMESPACE QRESYNC QUOTA RIGHTS=ektx SASL-IR SEARCHRES SORT THREAD=ORDEREDSUBJECT UIDPLUS UNSELECT WITHIN XLIST
なにやら盛りだくさんで、わからないものが多々ありますが、
IDLEコマンドもあるのでIMAPでのPUSH通知も可能です。
オプションもあって私的には良さそうです。
さすがについ最近、リプレースしただけあります。
どうやら、zimbraを使っているようです。
コネクションをきるときに、この製品だよってコメントが出ます。
さくらのメールでの結果
CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN ACL ACL2=UNION
有料なのですから、もうちょっとがんばってほしいものです。
Yahoo(Japan)での結果
CAPABILITY IMAP4rev1 ID NAMESPACE UIDPLUS LITERAL+ CHILDREN XAPPLEPUSHSERVICE AUTH=PLAIN AUTH=LOGIN
まあ、WEBメールか、POPをつかってね。
というレベルですね。
前回、HTTPのchunkごと(がわかるように)の受信を調べてみた。
やはり、URLStreamではできないことがわかった。
データの中身をみて、できていないのだからできないのだろうが、
Content-Typeかなんかに違いがあるのかなとも思い始めたので、
BlazeDSのソースをみてみることにした。
で、簡単にだめだというのでつまらないので、私なりの調べ方を記しておく。
ソースをダウンロードしてみて、
find ./ | grep java$ | xargs grep -i -n "chunked"
とやってみると、
./modules/core/src/flex/messaging/endpoints/BaseStreamingHTTPEndpoint.java:71: * This token is used in chunked HTTP responses frequently so initialize it statically for general use.
./modules/core/src/flex/messaging/endpoints/BaseStreamingHTTPEndpoint.java:76: * This token is used for the terminal chunk within a chunked response.
./modules/core/src/flex/messaging/endpoints/BaseStreamingHTTPEndpoint.java:719: res.setHeader("Transfer-Encoding", "chunked");
./modules/core/src/flex/messaging/endpoints/BaseStreamingHTTPEndpoint.java:1063: * "Transfer-Encoding: chunked" format.
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:79: private static final String CONTENT_CHUNKED = "content-chunked";
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:88: protected boolean contentChunked = false;
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:169: * <content-chunked>false</content-chunked>
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:374: // Content Chunked
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:375: if (properties.getProperty(CONTENT_CHUNKED) != null)
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:377: boolean ch = properties.getPropertyAsBoolean(CONTENT_CHUNKED, false);
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:378: setContentChunked(ch);
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:432: * Returns the <code>content-chunked</code> property.
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:434: * @return <code>true</code> if <code>content-chunked</code> property is
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:437: public boolean isContentChunked()
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:439: return contentChunked;
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:443: * Sets the <code>content-chunked</code> property. Default <code>false</code>.
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:445: * @param contentChunked The <code>content-chunked</code> property.
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:447: public void setContentChunked(boolean contentChunked)
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:449: this.contentChunked = contentChunked;
./modules/proxy/src/flex/messaging/services/http/HTTPProxyAdapter.java:596: context.setContentChunked(contentChunked);
./modules/proxy/src/flex/messaging/services/http/proxy/ProxyContext.java:52: private boolean contentChunked;
./modules/proxy/src/flex/messaging/services/http/proxy/ProxyContext.java:227: public boolean getContentChunked()
./modules/proxy/src/flex/messaging/services/http/proxy/ProxyContext.java:229: return contentChunked;
./modules/proxy/src/flex/messaging/services/http/proxy/ProxyContext.java:232: public void setContentChunked(boolean value)
./modules/proxy/src/flex/messaging/services/http/proxy/ProxyContext.java:234: contentChunked = value;
./modules/proxy/src/flex/messaging/services/http/proxy/RequestFilter.java:165: ((EntityEnclosingMethod)httpMethod).setContentChunked(context.getContentChunked());
これで、対象のソースは
flex/messaging/endpoints/BaseStreamingHTTPEndpoint.java
しかないことがわかる。
res.setHeader(“Transfer-Encoding”, “chunked”);
とTransfer-Encodingに設定しているところがここしかないからである。
こんか感じに、私はソースを調べる場合にはたいてい、linuxなどのshellが使える環境で探す。
それでもって、ソースをみるもの、viewコマンドでみていく。
なぜなら、検索がらくなので、書くのはEclipse、みるのはviewコマンドが私なりの開発手法です。
さて、話は戻って、
怪しそうな場所を抜粋すると、
try
{
currentThread.setName(threadName + STREAMING_THREAD_NAME_EXTENSION);
// Open and commit response headers and get output stream.
if (addNoCacheHeaders)
addNoCacheHeaders(req, res);
res.setContentType(getResponseContentType());
res.setHeader("Connection", "close");
res.setHeader("Transfer-Encoding", "chunked");
ServletOutputStream os = res.getOutputStream();
res.flushBuffer();
// If kickstart-bytes are specified, stream them.
if (kickStartBytesToStream != null)
{
if (Log.isDebug())
log.debug("Endpoint with id '" + getId() + "' is streaming " + kickStartBytesToStream.length
+ " bytes (not counting chunk encoding overhead) to kick-start the streaming connection for FlexClient with id '"
+ flexClient.getId() + "'.");
streamChunk(kickStartBytesToStream, os, res);
}
とこんな感じ。
最後のstreamChunkでデータを書き出していそうだ。
では、kickStartBytesToStreamという変数があるが、これがそのためのデータっぽい感じだ。
そして、そのメソッドの中身をみてみれば・・
protected void streamChunk(byte[] bytes, ServletOutputStream os, HttpServletResponse response) throws IOException
{
if ((bytes != null) && (bytes.length > 0))
{
byte[] chunkLength = Integer.toHexString(bytes.length).getBytes("ASCII");
os.write(chunkLength);
os.write(CRLF_BYTES);
os.write(bytes);
os.write(CRLF_BYTES);
response.flushBuffer();
}
else // Send final 'EOF' chunk for the response.
{
os.write(ZERO_BYTE);
os.write(CRLF_BYTES);
response.flushBuffer();
}
}
やはり、データをチャンクとして書き出している。
この中でちゃんとチャンクの長さも調べている。
で、kickStartBytesStreamを調べてみると、
int kickStartBytes = agentSettings.getKickstartBytes();
if (kickStartBytes > 0)
{
// Determine the minimum number of actual bytes that need to be sent to
// kickstart, taking into account transfer-encoding overhead.
try
{
int chunkLengthHeaderSize = Integer.toHexString(kickStartBytes).getBytes("ASCII").length;
int chunkOverhead = chunkLengthHeaderSize + 4; // 4 for the 2 wrapping CRLF tokens.
int minimumKickstartBytes = kickStartBytes - chunkOverhead;
kickStartBytesToStream = new byte[(minimumKickstartBytes > 0) ? minimumKickstartBytes :
kickStartBytes];
}
catch (UnsupportedEncodingException ignore)
{
kickStartBytesToStream = new byte[kickStartBytes];
}
Arrays.fill(kickStartBytesToStream, NULL_BYTE);
}
と、あれれ・・・
なんらかのデータの長さをチャンクデータとして書き出している。
つまり、最初にChunkデータとして、次のChunkデータサイズを出力し、
次にデータそのものを送っている感じだ。
あー、やっぱり。
だからStreamingConnectionHandlerというflexのクラスの方では、
Chunkサイズがとれていたのですね。
これで、送り元と受信先のプログラムのロジックが一致しました。
あー紛らわし。
できれば、先頭xxバイトはデータの長さとか別のルールにしておいてくれれば・・・
そんなこんなで、結局、
ActionScriptでChunkごとのデータを受信して、Server-Sent Eventのようにするには、
データのデリミタをデータフォーマットの定義として必要にしないといけないようです。
Flexでも、JavaScriptでもどっちでも使えるようにデータ送信方法を設計したかったので、
chunkごとの切れ目がわかればよかったのですが、あきらめるしかないようです。
java netty: HTTPストリーミングのサービスを作るにはで、
ChunkedのデータをFlex(ActionScript)で、Chunk毎に受信をする方法を、再度調べてみることにしました。
というのも、StreamingConnectionHandlerというクラス内で、
チャンクデータを扱っています。
私のやり方のどこがいけなかったのかはまだわかりませんが、
ちょっとこのソースの中身を見てみても、
以下のようにデータのサイズを計算しています。
if (state == SIZE_STATE)
{
value = chunkBuffer.readByte();
if (value == NULL_BYTE) // Ignore the null heartbeat byte.
continue;
// CR indicates that we've finished reading the size.
if (value == CR_BYTE)
{
dataBytesToRead = parseInt(hexChunkSize, 16);
state = LF_STATE;
}
else // Hex digit.
{
hexChunkSize += String.fromCharCode(value);
}
if (chunkBuffer.bytesAvailable == 0)
break;
}
もう一度、このソースを参考に、URLStreamで自分なりにどこが間違っているのか、確認します。
結局、URLLoaderを使っていたために、
出力も一括でいいかなと思っていたのですが、
想定していなかった、URLLoaderがtimeoutの例外イベントを発行します。
だったら、出力はChunkedで出した方がよく、
Chunkedでどうせ出すならば、やはり、ActionScriptでもどうできるのかを、
事前にリスクを洗い出しておこうと思った次第です。
また、StreamingConnectionHandlerはAMF3だけを対象にしているようですが、
Server-Sent Eventにも対応を考えれば、
汎用的なクラスを作っておいた方が良さそうだという次第です。
うまくいったら、airxlibのライブラリの一部として公開する予定です。
まず、http before sshなんていう機能はありません。
私が勝手につけました。ようは、pop before smtpみたいなものを
sshの接続のために構築します。
つまり、sshでアクセスするためにはhttpに一度アクセスして許可を取らなければいけないとします。
どうして、こんなことをしようと思ったかといえば、
ちょっと、昨日設定したiptableの設定が考慮不足で自分で自分のサーバにemobileを使ってアクセスができなくなってしまった。
まあ、結構いい加減に許可をしていたので、もうちょっと厳しくしようかなと思ったものの、
それで失敗してしまった。
ということで、どうせやるならもうちょっときちんとやろうと思った次第です。
さて、この
http before ssh
ですが、ここでは2つの方法を紹介します。
1つは、httpでアクセスしたIPから数秒以内だけsshの接続を許可する。
2つは、httpであるページに接続しそこで認証したら、そのIPからのみ数十分間だけsshの接続を許可する。
というものです。
どちらも、iptablesを使うので、まずは安全のための準備をします。
iptablesを安全につかうための準備
iptablesで設定している最中がもっとも、間違いやすく、
ましてや、リモートからiptablesの設定をするとなると多少は勇気がいるものです。
しかし、ここでは私なりの間違いが起きにくい方法を紹介します。
1)ゼロからiptablesの設定をするのも面倒ですし、
間違いがあってもいけないのでCUIベースの設定ツールがあればそれを使って簡単な設定を行います。
たとえば、CentOS等であれば
” system-config-securitylevel-tui”
などのツールを使って概要をつくってから、
/etc/sysconfig/iptables
のファイルをいじっていきます。
まずはここで必ず、sshを有効にしましょう。
この前提で記述してあるので、-RH-Firewall-1-INPUTと記述してあります。
2)自分がアクセスするIPからsshを無条件で許可するようにします。
私は、e-mobileからだったので、ある程度のレンジで指定します。
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -m iprange --src-range 117.55.65.0-117.55.65.255 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
ここでポイントは、既存の22ポートも許しておくことです。
設定が終わったら、iptablesを再起動します。
そして、sshでアクセスをしてみます。
(当然、接続はできます。)
ここで、どちらのルールに適用されて許可されたのかを調べる為に、
#iptables -nvxL
と打てば、
Chain RH-Firewall-1-INPUT (2 references)
pkts bytes target prot opt in out source destination
1 52 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 source IP range 117.55.65.0-117.55.65.255
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
とこんな感じに表示されます。
ここで、pktsが接続毎に増えていれば、そこが使われているということです。
それで、IPのレンジ指定で許可されているのがわかります。
これで多少は安心して、接続元の指定がない22番ポートへの接続を切ることができます。
httpでアクセスしたIPから数秒以内だけsshの接続を許可する
この方法のネタ元はhttp://blog.onoh.info/linux-sshiptablesです。
多少ちがいますが、ほとんど同じです。
こちらはiptablesさえあれば実現可能です。
http(ポートを変えた方がいいかも)にアクセスしてから、数秒(5秒)以内だけsshの接続を受け付けるようにします。
ここで、この方法を知っている人と、httpのポート番号を知っているひとがsshできる対象というわけです。
それ以外はsshのポートすらあいていることすら知りません。
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 8888 -m recent --set --name check --rsource -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 5 --name check --rsource -j ACCEPT
と設定します。
こちらも、設定が終了したら再起動します。
また、
#iptables -nvxL
も忘れず実行し、実際に思い通り動いているか確認しましょう。
httpであるページに接続しそこで認証したら、そのIPからのみ数十分間だけsshの接続を許可する。
こちらはもうちょっと複雑です。
WEBの画面を使って認証(ログイン)すると、その接続元IPから接続できるように動的にiptablesに設定を追加し、
atコマンドを使って一定の時間経過後に、その設定を削除するというものです。
ちなみに、使う環境として
iptables
syslog-ng
at (/usr/bin/at )
php (やcgiなど)
です。
syslog-ngを使うのは、syslogのメッセージによりコマンドを発行するためであり、
また、root権限にてiptablesへの追加ができるようにするためです。
ここでは、syslog-ngを含めてインストールは説明しません。
まずは、PHPにて
< ?php
if($_POST['auth'] == "1"){
$ip = $_SERVER['REMOTE_ADDR'];
openlog("ipconn",LOG_INFO,LOG_LOCAL1);
syslog(LOG_INFO,"@$ip");
}
?>
<html>
<body>
<form method="POST">
<b>Your IP Address: < ?php print $_SERVER['REMOTE_ADDR']; ?></b>
<input type="hidden" name="auth" value="1" />
<input type="submit" value="CONNECT" />
</form>
</body>
</html>
のようなプログラムをつくりWEBでアクセスできるようにします。
実際には、何らかの認証もつけるのですが、私は面倒なのでhttpsとBASIC認証で代用してしまいます。
ここでは、重要な点はログに
“@IP_ADDRESS”
のような形式を出力することです。
このあと設定するsyslog-ngはこのメッセージを受けたら、IP_ADDRESSを許可するというようにします。
次に、syslog-ngから起動されるプログラム(shell)を記述します。
(もちろん、実行権限を忘れずに・・・)
#!/bin/sh
IPTABLES=/sbin/iptables
ATCMD=/usr/bin/at
NAME=RH-Firewall-1-INPUT
while read line;
do
IP=`echo $line | cut -d@ -f2`
ADD_IP="$IPTABLES -I $NAME 7 -p tcp -s $IP -m multiport --dport ssh,smtp,imap,pop3,svn -j ACCEPT"
DEL_IP="$IPTABLES -D $NAME -p tcp -s $IP -m multiport --dport ssh,smtp,imap,pop3,svn -j ACCEPT"
$ADD_IP
echo $DEL_IP | $ATCMD now +60minutes
done
ここで、”@”以降をIPアドレスと見なしてそれをもとに設定を追加します。
ADD_IP="$IPTABLES -I $NAME 7 -p tcp -s $IP -m multiport --dport ssh,smtp,imap,pop3,svn -j ACCEPT"
で”7″とありますが、$NAMEで指定したルールの7行目に追加するという意味なので、
実際に何行目に設定するかをかえてください。
また、同時に、atコマンドを使って削除する指定もしておきます。
(atdが動いていないと実行されないので、そこはご確認を)
これで、60分だけ接続ができるようになります。
ちなみに私はsshだけではなく、それ以外のサービスも同時に設定しているのでmultiport指定を使いました。
ここまで、準備ができたら、これらをsyslog-ngの指定でつなげていきます。
destination d_ipconn_at { program("/usr/local/bin/ipconn.sh"); };
filter f_ipconn { program("ipconn"); };
log { source(s_sys); filter(f_ipconn); destination(d_ipconn_at); };
の指定をsyslog-ngに追加してください。
これで、syslog-ngを再起動したら終了です。
これの応用で無人サーバ運用も広がっていくことと思います。
最近、IS03のタッチの反応が遅くなってきました。
なんか、PCみたいです。
(使っているうちにだんだん遅くなる感じが・・・)
このため、ロック解除で一番右まで鍵を持って行こうとしても、
半分くらいまでしかついてこれないことが多々あります。
かれこれ、1年前だというのに、
もう旧世代ですね。
中古屋さんでも、9000円くらいでうられているので、
とりあえず、Androidは中古でいいような気がしました。
ちなみに、音楽プレイヤーとしてAndroidが発売されていますが、
IS03からSIMカードを抜いて使って見たところ、
ワンセグも使えるし、Wi-Fiがつかえれば電話ができないだけの端末として使える気がします。
そんな感じで、Andorid ICSが当たり前になったら、
中古屋さんでなにか別の機種にきりかえようかなと・・・
どれくらいSIMカードなしで使えるかは実際のところわかりませんが・・・
ちょっと、「システムはなぜダウンするのか」という本を図書館で借りてみました。
そこで、すごくびっくりしたのが、下記のような構成図らしきものが多数記述があるのです。

説明をよめば、決して間違いとはいえないかも・・・
とは思えるものの、
「WEBサーバの同時接続数×WEBサーバの台数」
が、「同時要求データ件数」である。
とあります。
おいおい、これを書いている人はWEBサーバがどの程度、同時接続可能なのか?知っているのかい?
たいていは、APPサーバ1台の方が同時に裁ける件数はすくないのですよ。
といいたくなります。
また、APPサーバは、リクエストを待ち行列に加えるとある。
確かに待ち行列に加えるとあるが、そのリクエストにタイムアウトがあるのだよ。
いったいクライアントはいつまで待ってくれる前提で書かれているのか・・・
そして、実際私は、この構成をしたために、ダウンしたシステムを何度見たことか。
(両手の指では数え切れないくらいはあります。
そのたびに、ひたすらApacheの接続数とプロセスのプール数を少なくしてきました。)
たいていのWEB+DBのシステムではWEBサーバが一番少なくていいはずである。
なぜなら、一番処理が軽いのですから。
これは、システムに限らず、私たちの身の回りでもこのノウハウは使われている。
たとえば、レストランを想像すればよい。
通常のWEB+DBのシステムでは、
WEBサーバはレストランの入り口だとおもえばよい。
もっとも、負荷がかるいところである。
でも、なぜか、その入り口で人が待ってはいないだろうか?
これは、わざと待たせているのである。
テーブルがあいているじゃないか?
と思うこともあるだろう。
でも、テーブルにすわって、注文を受けたら2時間待たされた。ということはほとんど無いはずである。
(これがあったら、私はそうとう頭にくるし、多くの人がそう思うだろう。)
でも、入り口で2時間くらい待たせるときはある。
(一応、その説明は店員からうけるが・・・)
そして、テーブルに座ったら、込んでいても、すいていても、全体の待ち時間を含めて考慮すれば、
体感的にそれほど変わらないはずである。
それに、入り口が最大のボトルネックのシステムなんて、
設計も非常に楽だろう。
途中が一番重いから、負荷に対する処理の設計が難しく、そして、トラブルが起きやすいのである。
といっても、サーバだけを見ている人が入り口を狭めるという英断はし難いだろう。
教科書的な本にも、WEBサーバが一番多く描かれているし、
そして、なにより、APPサーバが満足に動くようにWEBサーバの接続で問題を起こさせるわけになるのだが、
そこで責任問題が起きれば、サーバ管理者が責められる。
本当は、システムが急なアクセス増加(攻撃だってありえる)でも安全に動くようにしているにもかかわらず。
と、まあ、実は、システム設計の問題ではなく、
単に、責任問題で障害が起きている。
単一部署(責任者)がサーバもアプリも見ていれば、このような障害は起きにくく、
また、起きても、その間違いに気がつけば、次の爆発的なサービス的成功なくして、まず再発はない。
しかし、ハード屋さん、ソフト屋さん、みたいに分かれているところは、
そこら中でこの問題を発生させるのである。
もしかしたら、追加ハードや追加ライセンスを買わせるためかもしれませんけどね・・・
今まで主に、ライブラリ関連をやってきました。
AIRのライブラリが中心ですが・・
その一方で、Gravity Mailという
すべてAIRではありますがソフトウェアも作りました。
ここで、やはりすべてAdobe AIRでやることの限界(自分の限界?)も感じました。
今まで、「つれずれ」とあえて、ずれをやってきましたが、
そろそろ「つれづれ」になれるように、もうちょっと集中してやりたいと思います。
(かなり昔に、ずれの間違いを友人に指摘してもらいましたが、せっかくなので、
そのままに自分の「ずれ」が直るまで、そのままにすることにしました。)
そこで、やはりやりたい事は、メール関連です。
Gartner Predicts 2012にも
モバイル・デバイスの利用者が増加し、エンタプライズ・アプリケーションをブラウザ環境で利用する上での快適性が高まっている。このことは、操作性や表現力のより高い電子メール・クライアントとアクセス環境の組み合わせが登場することを運命付けており、今後4年間、驚くほどのペースで変化するものと思われます。同じ理由から、電子メール・システムのベンダーも、多様なデバイス向けのモバイル・クライアントを開発・提案する可能性があります。モバイル・デバイス管理プラットフォーム・ベンダーの市場機会は急激に増え、一方でインスタント・メッセージやWeb会議、ソーシャル・ネットワーク、共有ワークスペースなど、増加するコラボレーション・サービスのポートフォリオをサポートするサプライヤーに対して、プレッシャーは高まると考えられます。
とありますし、そろそろこんな感じのものを解決するためのサービス(ソフトウェア)作りをしたいと思います。
私風に言えば
「RIA メール」
です。
WEBメールでもなく、クライアント型のメーラでもありません。
技術スタックとしてはこんな感じです。

Gravity Mailでやったように、メール内容が他のシステムと連携できるようにしたく思います。
そのために、Nettyのパイプライン(フィルターのようなもの)構造はすごくマッチしている思いました。
それぞれの結合度が非常に緩くつくれるので、レゴブロックのように組み合わせがしやすいです。
また、最上位層をHTTPにしているのは、やはりマルチスクリーン(PC、スマートフォン、タブレット等)に対応するためです。
たとえば、メール本文をHTMLにして、そこにTODO管理システムへのリンクを作るといった場合でも、
オリジナルに手を入れずに、上の「CUSTOM Handler for LAN」と書いた部分に、
Nettyの新たなHandlerを作ればいいわけです。
後は、フィルターのレイヤー毎にインストールする場所(サーバ、PC)を分けられます。
たとえば、IMAPやSMTPのサービス部分だけ、LAN上に配置すれば、
メールボックスをインターネット上の公開しなくてもいいわけです。
こんな感じのサービスを目指して、2012年は進もうと思います。
最後に、もしそんなサービスをうちで作ってほしいという方がおりましたら、
メールをいただけると助かります。
他に必要な情報をお望みでしたら、お送りいたします。
(メールアドレスはこのブログの一番したにあります。)


