目次
06-22 IBM 産業スパイ事件(1982)
06-22 node.js の雑感
今日は IBM 産業スパイ事件の発覚した日(1982)。
日本のコンピューター業界を震撼させた事件でした。
今となっては日立と三菱がスパイをやった、という程度の、企業が行き過ぎただけの話だと思われているけど、これ「国策」の一環が暴走したのです。
日本のコンピューター開発は…どこまででも遡れますが、FACOM 100 の話から始めましょう。
富士通の池田敏雄が設計し、1954年に完成したコンピューターで、リレー式でした。
名前は似ていますが別会社の富士写真フィルムは、1956年に FUJIC を完成します。
これが、日本で最初の真空管式コンピューターでした。
技術者であった岡崎文次が、レンズの設計のために独自で開発したもので、会社としての関与はありません。
IBM の SSEC の影響を受けています。
1959年には、東京大学が中心となり、東芝・日立が協力し、TAC が完成します。
実は、FUJIC よりも先に開発が開始された、国の予算をつぎ込んだ国家プロジェクトでしたが、目標が野心的過ぎ難航、何度も設計変更を繰り返しています。
その影響もあり、完成した時にはすでに時代遅れでした。
こちらは EDSAC の影響を受けています。
1964年には、通産省の予算で富士通・沖電気・日本電気が共同で FONTAC を作成。
この頃から、各社が「コンピューターの作り方」を理解し、独自開発を開始します。
日立の HITAC、富士通の FACOM、日本電気の NEAC、東芝の TOSBAC 、三菱の MELCOM、沖電気の OKIMINTAC…
通産省は、この状況に危機感を持ちます。
コンピューターは、これから確実に産業の中心となる、というのは誰の目にも明らかでした。
1970年代初頭、IBMが巨大メーカーに成長しつつありました。
日本国内だけで6社も互換性のないコンピューターが乱立していては、これらの大企業に潰されてしまいます。
そこで、通産省では、「国内で、IBMに対抗できるコンピューターを育てる」ための対策を行います。
方法は3つ。
1) IBMと技術提携を行わない、IBM互換機路線
2) IBMに対抗できる大企業の互換機路線
3) 日本独自路線
2 の大企業とは、事実上ハネウェル社です。
1960年代、アメリカには8つのコンピューターメーカーがあり、「IBM と7人の小人」と呼ばれていました。
ハネウェルはその一つでありながら、1970年に MULTICS の技術を持つGE社と合併し、力を伸ばしていました。
通産省の指導の元、国内の各社は上のいずれかの道を選び、提携することが求められました。
まず、富士通と日立はすでにIBM互換機を作成していたため、互換路線を選びました。
日本電気はすでにハネウェルと提携していました。
東芝も、すでにGEと提携していましたが、GEがハネウェルに吸収合併されました。
そこで、日本電気と東芝も提携し、ハネウェル互換路線を選びます。
三菱・沖電気は「取り残された」形で提携し、独自路線を歩むことになりました。
さて、時間を一気に進め、産業スパイ事件の話へ。
富士通と日立は提携し、技術的な交流は図りつつもお互い独自に、IBM System/370 の互換機を作成していました。
これ、互換性を持つ機械を独自技術で作成している、という形で、IBM との技術提携はありません。
ただし、IBM で System/360 (370の旧世代機)を設計した技術者で、後に独立したジーン・アムダールの会社と富士通は提携し、技術的ノウハウを得ていました。
1981年、IBM はこうした「互換機」が世界中で増えていたため、設計を一部変更して、性能を上げるとともに互換機を作りにくくした、System/370-XA を発表します。
日立はこの「設計変更」の詳細を入手しようとして、IBM のおとり捜査に引っかかり、1982年の今日、社員5名が逮捕されます。
#この時、日立社員5人と共に、三菱社員1名も逮捕されています。
三菱は当初は「独自路線」グループでしたが、この頃には余りに強くなった IBM の互換機を作ろうとしていました。
この刑事事件は、司法取引により決着。しかし、IBM から、民事損害賠償訴訟を起こされます。
System/370-XA は、各種回路が特許で守られていたうえ、それまでは後から読み込まれるソフトウェアであった「OS」の一部を、ハードウェア内に持つようになっていました。
(現在でいう、BIOS に相当するもの)
System/360 や 370 の頃は、同等の機能の回路で置き換えも可能でしたが、370-XA の特許は強力で、簡単には回避できません。
また、BIOS に関しては単純な回路ではなく、プログラム…著作物です。
著作権の場合「類似したもの」を作ったとしても、盗作としてアウトです。
#少なくとも、この時点では IBM はそのような認識で動いていた。
ずっと後に、IBM・コンパックが BIOS の著作権を争い、現在は違う認識となっている。
結局、日立は IBM の許可を得ずに機械を販売しないこと、訴訟費用は全部日立が負担すること、ソフトウェアやインターフェイスなどに関して、使用する対価を払うこと…などを条件に和解します。
日立からすれば、IBM 互換路線に「お墨付き」を貰った格好で、この後も互換路線を進みます。
富士通も日立の訴訟に危機感を持ち、同様の取引を結びますが、徐々に IBM 互換路線から非互換路線にシフト。
いずれにしても、通産省の狙った「独自技術による互換」という路線は無くなってしまったことになります。
この頃は、IBM が強くなりすぎてハネウェル社もコンピューターから事実上の撤退。
特に、吸収合併したGEの互換機は消滅し、GE互換だった東芝も撤退、同じグループだった日本電気にコンピューター部門を売却しています。
独自路線だった三菱・沖も、先に書いたように三菱がIBM互換路線に進もうとして、スパイ事件に発展。
沖電気は、コンピューター本体は断念して、周辺機器製造に特化しています。
国策だった3グループ化は大失敗。日本のコンピューター産業は死んでしまう…。
「IBM産業スパイ事件」とは、そうした危機的な状況を意味する事件だったのです。
翌1983年、日本電気がスーパーコンピューターの新シリーズ、SX-2 を発表します。
(シリーズ最初の機種が 2 で、後に廉価版の 1 を発売)
この SX-2 は、世界で初めて GFLOPS を超えたコンピューターで、同時に初めてアメリカ以外のコンピューターが速度で世界一になった機械でした。
日本のコンピューター産業復活の狼煙、でした。
…この後、急に力を付ける日本のコンピューター業界にアメリカが危機感を感じ、1980年代後半から90年代前半の貿易摩擦につながっていきます。
同じテーマの日記(最近の一覧)
別年同日の日記
申し訳ありませんが、現在意見投稿をできない状態にしています。 |
ここ1年くらい、仕事で node.js をいじっているのだけど、ちょっと愚痴を書いてみる。
node.js が流行したのはもう何年も前のこと。
Apache よりずっと速く処理できる、ということだったけど、仕事でそこまで処理速度が必要なことはやっていなかったし、その時は、ふぅん、そんな技術もあるんだ、という程度。
1年ほど前に、WEB socket 使いたい仕事があって調べたら、node.js を使うのが一番やりやすいとわかった。
最初はよくわからない技術だったけど、その後それなりに実績もあるようだし、使ってみようと思った。
と書いたところで、相変わらず node.js がマイナー技術だという認識なので、コイツが何者であるかを最初に説明しよう。
今これを読んでくれている人は、おそらくPCかスマホの WEB ブラウザで読んでいるだろう。
多分、そのブラウザには Javascript というプログラム言語の実行環境が備わっている。
プログラムなんてどんな言語でもそれほど大きくは変わらないものだけど、それぞれ特徴はある。
Javascript の最大の特徴は、WEB ブラウザという「利用者が直接使う部分」に密着する様に作られている、ということだ。
人が使う部分…フロントエンドとか、ユーザーインターフェイスとか言われるけど、その部分はとにかく人を待たせてはいけない。
Javascript も、「人を待たせない」ことを理念として作られている。
具体的に言うと、「1秒待つ」とか、「ユーザーの入力を待つ」とか、「ファイルを開いて内容を得る」なんて考え方が無い。
これらは、パソコンの計算速度に比べると、途方もなく遅いからだ。
代わりに存在しているのが、「1秒後に関数呼び出し」「ユーザー入力が終わったら関数呼び出し」「ファイルの内容を引数に関数呼び出し」というように、とにかく待つ代わりに「あとで呼び出して」と依頼しておく方法。
このプログラム方法、初心者にはとてもわかりづらい。
まぁ、初心者にわかりづらい、なんていうのは些細な話。
ブラウザだから、ユーザーを待たせないことが第一で、そのためにはプログラマーが苦労するのは当然なのだから。
でも、ブラウザに限らず、プログラムが「待たせたくない」場所は多い。
サーバーは人が使わないから多少遅くてもいい…と言われたのは昔の話で、今は多数のサーバーアクセスを高速にこなすことが求められている。
だって、クラウド時代だもの。昔とはサーバーの接続量がケタ違い。
で、Apache …というか、その上でよく使われる PHP は「ファイルを開いて内容を得る」とか「SQL にクエリを投げて、返事を待つ」とか、とにかく遅い動作が多い。
これ、Javascript みたいに「終わったら関数呼び出し」にしたらいいんじゃない? というのが、node.js の基本的な発想。
google が作成し、chrome に搭載されている Javascirpt のエンジンを使って、サーバーで動作できるようにしてしまった。
書ける人が多い Javascript がサーバーでも使える~というような説明も見るのだけど、これはミスリードだと思う。
主眼は Javascript を使うことではなくて、「待たせない」プログラム手法がすでに確立されている言語を使うこと。
先に WEB socket を使うなら node.js と書いたけど、これは実のところ node.js である必要はない。
WEB socket というのは、TCP/IP ソケット上で実現されている HTTP 接続の上で、TCP/IP のような「ソケット」を実現しよう…という、回りくどい技術。
でも、HTTP というのは、TCP/IP の機能の、ほんの一部を利用して作っているんだ。
それを拡張し、再度 TCP/IP のような汎用性を持たせれば、メリットは計り知れない。
じゃぁ TCP/IP 使えばいいじゃん、となりそうだけど、WEB socket だと、HTTP の延長上にあるので WEB ブラウザから使いやすい。
Apache + PHP だと、Apache が完全に HTTP を前提に作られているので、WEB socket は扱いにくい。
そこで、node.js の出番となる。
実のところ、WEB socket はまだブラウザごとに実装が一部食い違ったり、実装していないブラウザもある。
そういう場合でも、node.js 上のライブラリ、socket.io が、ブラウザごとの差異を隠してくれる。
さて、前提条件の話だけでずいぶん長くなったな…
node.js + socket.io の勉強を始めた時は、右も左もわからなかったので、分かりやすいチュートリアルに従って使い始めた。
そのチュートリアル自体が多少古いものだったので、Express ver.2.x を前提としていた。
この Express は、node.js 上で動く WEB サーバー。
当時の socket.io では、WEB サーバーが前提として必要だった。
でも、実はこの時点で Express の最新版は 3.x だった。
判っていたけど、3.x 対応の使い方説明で良いものがなかったので、「後でバージョンあげられるでしょ?」と思って、古いバージョンを使った。
…で、話は一気に最近へ。
Express は v2 と v3 と v4 で、全然互換性が無い。
いや、全然というのは間違いか。でも、ずいぶん書き変えないと動かない。
socket.io も、v0.9 が長い間使われていたけど、v1.x 系列となった。
こちらも、かなり書き換えないと動かない。
メールを扱おうと思って nodemailer というライブラリを使った。
これも、v0.7 から最近 ver1.0 になり、かなり書き換えないと動かない。
互換性を保てない設計変更が悪い、とは言わない。
最初から完璧な設計なんてできないし、作り進めるうえで変更しないといけないことも多いだろう。
でも、node.js の界隈は、互換性を気にしている人なんて誰もいない、というように思える。
理由は二つあって、node.js を使う最大の理由が「速度」だというのが一つ。
過去との互換性を気にして速度を落とすなんて馬鹿馬鹿しい。効率のためには互換性を切ったっていいだろう。
もう一つ、おそらくは「後から関数を呼んでもらう」というスタイルのプログラムは、速度効率は良いかもしれないけど、互換性を保ったまま拡張することが困難になりやすい。
多分、多くの原因はこちらだろう。
これは自分がプログラムしていて困った部分だけど、ループ処理している部分があった。
その中で、扱う値を「SQL DB に入っている値を参照して」扱いを変えなくてはならない、ということになった。
これ、絶望的なプログラム書き換えを伴う。
PHP なら、SQL に問い合わせて、答えを見るだけだ。
でも、node.js では、SQL 問い合わせは関数を呼び出してもらう必要がある。関数が増える。
この関数は、「後で」呼び出されるものだ。すぐに答えを得られるわけではない。
でも、ループしているのは「全部を処理する」ためのループではなく「順次処理する」ためのループだった。
1つの処理が終わってから次の処理に入らないといけない。
処理の中の DB 問い合わせが、すぐに結果を得られないため、ループそのものを解体する必要が出てきた。
ループの中身を関数として書き出し、関数の中で DB 問い合わせをし、結果を貰うための関数を呼び出す。
結果で呼び出される関数の中でループ変数にあたるものを操作し、必要であればループの中身にあたる関数を呼び出すことで「ループ」を構成する。
再帰プログラムのようで、再帰ではない。
だって、呼び出しは遅延して行われるのだもの。DB 問い合わせした後に関数は終了し、スタックは解放されるので、再帰階層が深くなってもメモリを馬鹿食いしたりはしない。
逆に言えば、スタック解放されるからローカル変数は使えない。
グローバルをやたら増やしたくはないから、クロージャのように関数内で変数と関数を定義して、「解放されないローカル変数」を作り出す必要がある。
複雑怪奇なプログラムになった。
こういう大幅な書き換えがあると、呼び出し方法も変わることが多い。
そう、つまり、ライブラリ作者たちも同じような理由で呼び出し方法を「変えざるを得ない」ことがあるのではないかな、と思う。
Apache + PHP だと、ロードバランサ―を使って多重化できる。
万が一サーバーが死んでも大丈夫。
PHP は、アクセスの度に呼び出される。エラーが起きても、次のユーザーの接続で再起動される。
でも、node.js はそうではない。Apache にあたる、サーバー自体を書いている。
正しくエラーハンドリングすれば止まることはないのだけど、止まったら致命的。
でも、多くの人が同じ悩みがあるから、cluster を作ることができる。
複数のプロセスを同時に起動しておいて、どれかが止まっても大丈夫なようにするのね。
この cluster 化の方法が、多くの人が考えたため、たくさんある。
プログラムを大幅に書き変える必要がある物から、簡単に cluster 化できるものまで。
最近の流行は pm2 のようだ。
クラスタ化するだけでなく、接続を出来るだけ保ったまま、順次プログラムの再起動も出来る。
#socket.io は「ずっと通信路を保つ」ため、この通信路はどうしても切れてしまう。
socket.io 自体に、通信が切れたらすぐ再接続する仕組みはあるが、再接続後に先ほどと同じ状況を整えるのはプログラムが責任を持つ必要がある。
もっとも、これは pm2 と関係なく、いつ通信が不安定になるかわからないので、作らないといけない処理だ。
で、この pm2 を使おうとしたら、socket.io はおかしくなる。
socket.io はそのままではクラスタ対応できていないのだ。
まぁ、PHP だって、ロードバランサを使う時には守らないといけない決まりがある。
これは当然だろう。そして、socket.io も、いくつかの決まりを守ればクラスタ化できる。
…うまいくいかない。
この作業、半年くらい前に一度やって、どうしてもうまくいかないので一度断念した。
最近再チャレンジして、理由がわかった。
socket.io の v0.9 までは、クラスタ化に対応いしていたのだけど、v1.0 になった時に対応を「外部に任せた」のだった。
いや、そのことは知っていたよ。
多くのページがその方法を書いているから、その通りにしたのだけどダメだった。
で、知識が増えて再チャレンジして、多くのページが勘違い記述していることを知った。
世の中の半数以上のページが v0.9 前提で書かれていて、残る半数のうち、8割以上が 0.9 から 1.0 になって、新たな記述方法となったことを伝えている。
でも、そうじゃない。v1.0 になって、概念が変わった。細分化された。
クラスタ対応は「通信」と「ハンドシェイク」の2段階に分割され、多くのページに書かれているのは「通信」の対応だけだったのだ。
通信はできるが、ハンドシェイクにすごく時間がかかるようになる。
#socket.io は、ハンドシェイクのために2回アクセスを行う。
この2回が同じサーバーなら成功して通信に入るが、違うサーバーだとリトライする。
確率問題で成功するまで、延々リトライを繰り返すため、接続に時間がかかるようになる。
socket.io の公式ページの奥底に、ハンドシェイクは外部の別プログラムに任せる、ということと、推奨するライブラリが書いてあった。
でも、このライブラリは、pm2 とは違う cluster 化ライブラリを前提としていた。
そのライブラリは、確かにクラスタ化してくれるが、低機能で役に立たない。
探し回って、やっとわずかな情報で socket.io のハンドシェイクをクラスタ対応にする方法がわかった…ように思えた。
方法は二つあった。
1つは、大幅に socket.io の接続部分を書き変える方法。
もう一つは、それをライブラリ化したもの。
ライブラリの方を使ってみたら、うまく動かない。
どうやら、socket.io やその他もろもろのライブラリに依存してしまうようだ。
バージョンが変わるごとに非互換になるので、こういうことになる。
大幅に書き換えが必要な方は、まだ試していない。
その書き換え方法が、どのバージョンでつかえるのか明記されていないため。
でも、node.js の歴史自体が浅く、まだバージョンによって互換性が致命的に失われることを理解している人が少ないため、バージョンを明記した記事はあまり見かけない。
自分が求めている方法を見つけては、試しに自分のプログラムに組み込んでみて(場合によっては非常に大きな書き換えを伴う!)、ダメだったら自分の勘違いなのかバージョンが違っているのかを理解して、多くの場合は「諦め」て別の情報を探す、という決断が必要となる。
と、以上は node.js に対する愚痴でした。
node.js を使いこなしている人から見たら、入り口付近で悩んでいるだけかもしれない。
ライブラリも全部 javascript で書かれているから、自分で解析して書き変えてしまう、という方法もなくはない。
でも、今後のバージョンアップ(と、そのたびの非互換性)を考えると、手を加えるのは得策でないように思う。
同じテーマの日記(最近の一覧)
別年同日の日記
申し訳ありませんが、現在意見投稿をできない状態にしています。 |