Socket通信を選択すべきときとそうでないとき

10年弱も前に書いた下記記事に未だに結構なアクセスがある。

これらについて思うところを書いていこうと思う。

背景

Web系・IT系のエンジニアの皆さんには想像がつかないとおもうが、サーバーアプリケーション間やサーバー・クライアント間の通信方式はソケットから真心込めて手作りしなさい。使っていいのはTCP/IPとUDPだけです、という設計のプロダクトを開発している会社は結構ある。だから今回の日記は日常的にHTTPに触っているエンジニアの方々にはいまいち何が問題なのか理解し難いかもしれない。

なぜHTTP通信を使用することがダメだと言われている開発現場があるのかというと、

A. 極端に小規模な組み込みシステムであるからHTTPサーバーを動かすリソースがない
B. HTTPサーバーを経由させるとでは応答速度・パフォーマンスの面で要求にマッチしない
C. オープンソースソフトウェアの使用を禁じられている
D. 何十年も動かしている古いシステムなので下手にリプレースできない
E. HTTPが分かる技術者が居ない(少ない)

などといった背景がある。私の経験した限りでは。そういう背景があったときに安易にSocketをselect()してデータを読み取るようなところから開発するのはしんどいよな、と思った人たちが検索して上掲のような記事にたどり着いているのだと思う。

Socketと比較したときにHTTPを使うメリットとしては、

  1. ネットワーク内を通り抜けやすい
  2. 開発に使用するためのツール群が非常に充実している
  3. プロキシ・リバースプロキシ・ロードバランサなどのHTTP通信を制御するためのソフトウェア資産も膨大に存在する
  4. メッセージは平文として表現可能でデバッグしやすい
  5. 古くから利用されているプロトコルでノウハウが蓄積している
  6. リクエストに対してレスポンスが得られる
  7. HTTPサーバは沢山のプロダクトから選択できる

などが挙げられる。

生のSocket通信は上記をすべて自前で実装しなければならない。すなわち、Socket通信を利用するデメリットは

  1. ネットワーク内を通り抜けるためにネットワーク構成を行う必要がある
  2. 開発に使用するためのテストツール群も開発する必要がある
  3. プロキシ・リバースプロキシ・ロードバランサなどの機能が必要になった場合はそれらも開発する必要がある(L4までで済むケースを除く)
  4. メッセージを人間が読み取れる形でデバッグできるような機能を開発しておく必要がある
  5. 新しく設計・開発したプロトコルは相応のテストを行う必要がある
  6. リクエストに対してレスポンスがほしいときはその機能も開発する必要がある
  7. サーバプログラムはすべてSocketをlistenするところからすべて自前で実装する必要がある

と、全部裏返しになる。

そもそも、HTTP通信はプレゼンテーション層〜アプリケーション層であるのに対し、Socket通信はそれら以下の層の話であるから本来比較することが変だと私は思う。

「Socket通信かHttp通信(あるいは他のL6以上のプロトコル)か、どちらのプロトコルを使うか?」という議論は、より適切には「TCP/IP以上のすべてを自ら開発するかどうか?」と議論すべきだ。

それを踏まえて既存のソフトウェア資産を購入するなり無償利用が認められているものを利用するなりして開発工数を下げるか、あるいはすべて自前で開発を行うかという検討がなされるべきだろう。

その上で、既存のソフトウェア資産を活用する場合はhttpだけでなくて、メッセージキューなのか、各種RPCなのか、メッセージングサービスなのか、KVSなのか、RDBMSなのか、NoSQLなのか、共有メモリなのか、パイプなのか、などなどを検討して適切な一つを選ぶべきである。

しかしながら私が経験してきた「HTTPを使うな」という現場では、上記のような事項が検討された形跡は一切なかった。そもそも通信方法に限らず、既存の設計を新しく刷新することがご法度であることが多かった。

もちろん、今までSocket通信で動いてきた「枯れた」ソフトウェア資産を今後もメンテして使い続けることにも益はある。ただ、ソフトウェア開発の世界はどんどん新しく、便利に、高い生産性を上げられるように進歩しているのも事実である。だから、何処かで今までのソフトウェアを保守するのとすべて新規開発するのとで、後者のほうがコストが安くなる損益分岐点が来ているかもしれない、という調査検討をせずにいつまでも古いままだとソフトウェア工学の進歩の恩恵に与れない。そうして自社が抱える技術者が劣化していく。生産性はどこかで打ち止めになり、新しい技術に対応できない時代の流れに取り残された社員ばかりを生み出すことになる。これが一番の問題だと思っている。

このあたりは、IT系の基礎的な技術というのはかなり長い年代に渡って使われ続けるので(HTTPだってそもそも新しい技術ではない)昔の技術でまだ最前線を戦い抜いていると錯覚してしまうこともあるのかもしれない。

残念ながら多少コストやリスクをかけてでも新しい技術を自社の技術者に習得させるという発想が私がこれまで経験してきた職場では無かったと思う。あったのは何か問題が発生してから実績と証拠づくりのために全社員一律で行われるeラーニング(当然内容は技術的なものではない)と、80年代に著書を書いたご年配の社員が開く講義(内容はITには生かしにくいプロセス制御技術など)、既存の仕組みに最小の手間を加えてコストをいくら削減しました、という数字遊びのストーリーを作って社内表彰されるという流れだけである。そういう貧乏くさいことをしているからいつまで経っても生産性が上がらないのは当然であるし、国際的な競争力も下がっていくのだろうなと個人的には思った。感想です。

生産性を上げるための効果的な教育活動が行われていないのだから、生産性が上がるわけが無いよね。

ただ、技術者の育成という点ではWeb/IT系の会社でも似たりよったりかもしれないな、と思う。IT技術者とは余暇の時間も勉強できる人が上達していくのだ。という、 単なる現状の説明と追認 が耳にタコができるまで叫ばれる。もしかしたらそう言っている人は、余暇の時間も仕事のためにに費やすべきだ、なぜならば俺はそうやって一流の技術者になったのだから。という精神論の意味をも含んでいるのかもしれない。

何でも大戦期の日本を例示して批判するのは好きではないが、しかし、どうしても私は太平洋戦争で航空機パイロットを効果的に育成できなかった日本の姿と一致して見えてしまう。このへんは。