概要 †
- なぜ?への探究心、そして、再発防止のために何をすべきか?
- ガシャガシャやらずに、常にロジカルに戦略的に。何個かバックアッププランを持っておくように。
- RFC=仕様書読め
目次 †
勉強すべきこと †
- 必ずやること
- システムデザイン
- 各種用語の説明練習
- ブロードキャストとかに関してもっときちんと
- ネットワークアドレス、ブロードキャストアドレス、SMTP、ARP、ローカルホスト
- SQLかるく復習
- ネットワーク系はこれが良さそう
- TCP/IPでどうやって次のMACアドレスを得るの?誰が管理している?
- IPv6について
- backupの種類
- 具体的なデバッグモニタが動かないんですけdお
- OSIの全列挙
- スイッチとハブとルータって何。何するの。
- MACアドレスの構造は?
- MACアドレステーブルって何?スイッチにあるらしい
- IP RangeでClass A-E全部教えて。じつは、IP RangeとPrivate IP Range(A-C)は別らしい。
- FTPは何のために使うのか?
- これめっちゃ良さそう https://www.youtube.com/watch?v=fBBp9uqiIls
- 優先度つけて(system designがかなり大きい割合を持っていそう)
- Design a database to support a valet parking system.
- シェルスクリプトをちゃんと学ぶ
- 名前解決するレゾルバがDNSよりも優先するローカルにあるhostsファイル
- BigQuery?
- GSuiteのサーベイ
- フラッピングの対応は?
- ナイス値とプロセスの優先度の違い
- syslogdとは
- OAuth, basic auth
- 子が親殺したらどうなる?何のためにやる?
- httpsのローカルのチェックってなにやるの?
- buffered IOとunbuffered IOの違い
- プロセステーブル
- ゾンビ多いと何が問題?どう検知?どう直す?
- なぜUDPは1対多でOKと言えるのか
- パケットのルーティングの仕組み(トップレベルルータに流すのではなく、知らなかったら上流に流している。MACアドレスとの関係は?)
- バーチャルホスト
- VPSとは?
- NASとは?
- TCPって具体的にデータをどうやって送ってるの?
- パケットのルーティングは、トップレベルルータに流すのではなく、知らなかったら上流に流す。(どうやって勉強するんだ)
- 孤児プロセスってどうやってinitに引き取られるの?引き取られたあとはどうなるの?
- curlでどうやってHTTPリクエストを送るの
- localhosts
- ポート
- ポートはTransport (L4)で初めて出てくる概念なので、pingにはポート指定も何もない
- PingはICMPと呼ばれるインターネット層で動作するプロトコル
- systemctl start dockerのsystemctlとは
- psコマンドのもう少し細かい使い方
- デーモンとは
- ストリームとは
- IPの逆引きについて
- topとかいろいろ復習
- TCPのリスニングってなに
- tomcatとは https://knowledge.sakura.ad.jp/14427/
- ポートフォワードとは
- クッキーのプライバシー・セキュリティの問題
- SSHのデバッグ
- どうやってSMTPは繋いだパソコンを認識しているの?
- DNSのやり取り
- routeの解析方法
- RESTAPIの使い方
- POST通信とは?
- vmstat https://qiita.com/saikoro-steak/items/0ae51b4f5de520b37a44#_reference-126384302dd0632c1402 https://qiita.com/saikoro-steak/items/244362bcceec4df19343
- stack, heap領域
- nginxとは
- どうやってHTTPの内容を盗み見るの?
- Webサーバの挙動というか順番は?
- HTTPの標準化についてW3C以外のものとは?そもそもW3Cとは?
- ゾンビプロセス、どうやって検知・排除するの?
- ICMP
- DHCPの設定はどこ?-
- プロキシのキャッシュを逃れてサーバにアクセスする必要があるときはどうする?
- SSl http://wa3.i-3-i.info/word116.html
- SSL系のデバッグどうするん
- killした後の話
- Unix hanbookをよめ
- システムコール
- docker
- アパッチ
- systemd
- ポート
- どうやってHDDを変えるの?ディスクフルの対応方法は?
- トラブルシューティング系のシミュレーションしとく
- OOP
- ネットワークの可視化ツールを具体的に試す
- VLANって何
参考 †
OS †
- ソフトとハードのinterpreterとなり、UIとして動くもの。
データベース †
- RDBMS ・・・複雑なデータに向いている。データの肥大化による性能劣化が起きることがある。
- NoSQL・・・単純なデータに向いている。データが肥大化しても性能劣化が起こりづらいが、複雑なデータは苦手。
Unix †
仮想メモリ †
- 仮想メモリと物理メモリはページテーブルによって割り当てられる。
- これによって物理メモリの断片化を気にすることなく仮想メモリを使える。
- デマンドページングと言って、参照が発生した仮想メモリに対して実メモリを割り当てていく。
- さらに、forkした時に仮想メモリのページは共有されて、オンデマンドに子のページが作られる(コピーオンライト)。
- ユーザ空間では、テキスト・データ・ヒープ・スタック域が割り当てられる。
- heapはbrk(2)とかをした時に使われる
- bssにグローバル変数を置く
- stackは関数の引数やローカル変数や関数の呼び出し順(これは要するに関数がDFS的だからstackで表されるねという話)
- 動的リンクと静的リンク
- 静的リンクはめっちゃ仮想メモリの機能を使ったうまいやつ
- 動的リンクでは、オブジェクトファイルを予めリンクしてしまうので
- オブジェクトが実行可能ファイル毎に複製されるので、 ディスク空間を多量に浪費してしまう。
- 複数のプロセスが、 同一の関数を異なるテキスト・セグメントにロードして実行するので、 メモリを不必要に浪費してしまう。
- ライブラリ関数を変更した場合、 それを使うすべての実行可能ファイルは、再リンクしなければならない。
- 一方、ダイナミック・ローダは、 ライブラリがマップされたときにリンケージ・テーブルのエントリを、 共有ライブラリの関数のアドレスで埋めます。 このリンケージ・テーブルは、関数呼び出しのジャンプ・テーブルとして働きます。
- 一方共有ライブラリは、共有ライブラリから出力ファイルへはテキスト (コード) またはデータをコピーしない
- ダイナミック・ローダが、 実行時にそのライブラリをプロセスのアドレス空間にマップします。
- リンカは、プログラムから共有ライブラリ・ルーチンおよびデータへの参照を、 リンケージ・テーブルのエントリにバインドするだけ
デバイスドライバ †
シェル †
- 全てのシェルは新たにプログラムを起動するときに0, 1, 2のファイルディスクリプタをオープン
- それぞれSTDIN_FILENO, STDOUT_FILENO, STDERR_FILENO
- stty -aで、Ctrl-Cみたいなものでどんなシグナルを送れるかを一覧できる
- Ctrl-S, Qのように、シグナルを発行しないものもある
- ttyコマンドで自分の端末名がわかる
- 端末名がわかると、psコマンドでどの端末から立てられたプロセスなのかがわかる
- linuxに直接接続している場合はtty, そうでない場合はptsとなる
- デーモンは?というやつで、標準入出力・エラー出力が全部/dev/nullに繋がれる
- ちなみに、GUIから起動した普通のターミナルはtty…ではなくpts。多分本当に黒画面のやつがttyなんやね
- デーモンをC言語レベルで作る場合は、以下を行う
- initプロセス(プロセス番号1)を親プロセスとしていて
- 制御端末を持たないプロセスをデーモンと認識する
リダイレクト †
カーネル †
- プログラムの流れ
- カーネル→シェル→アプリケーション
- カーネル→アプリケーション
- カーネル→システムコール→アプリケーション
- /etc/passwd
- ユーザ名・パスワード・ユーザID・グループID・コメント・ホームディレクトリ・シェル
- ところでシェルのbashはbourne again shell, ちなみに元のbashはbourne shell
システムコール †
- システムコール一覧
- よく使うやつに限ったもの
- カーネルの昨日を使うためのC言語の関数(manで見るときは2)
- 例えば、sbrk(2)はメモリ割り当てをする。malloc(3)を実装するのに必要
- 他にも、kill(1)はkill(2)のために必要
- どれくらいのどんな種類のシステムコールが使われているかは、strace /bin/echo helloなどで確認できる
read(3, "", 4096) = 0
close(3) = 0
open("/usr/share/locale/ja_JP.eucJP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja_JP.eucjp/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja_JP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja.eucJP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja.eucjp/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/ja/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja_JP.eucJP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja_JP.eucjp/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja_JP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja.eucJP/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja.eucjp/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/ja/LC_MESSAGES/procps-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
kill(14031, SIGTERM) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
名前 | 何の略? | やること | 備考 | brk | break | ヒープ領域のブレーク値(=ヒープ上の未割り当てメモリの先頭アドレス)を変更する。現在のブレーク値との大小によって割当・開放を切り替えられる | sbrkという差分指定のbrkもある。mallocと併用不可 | kill | kill | プロセスIDやプロセスグループを指定して、シグナルを送る | | dup | duplicate | ファイルディスクリプタを複製して最小未割当ファイルディスクリプタに割り当てる | 複製と言っているが、実際に使うのはファイルディスクリプタの付け替えに使いがち。dup2というファイルディスクリプタを指定できる奴もあって、こっちのほうが便利。 |
入出力 †
- unbuffered I/O
- open, read, write, lseek, closeの5つ(標準入出力ルーティンではない、ファイル書き込みたち)
- open, openat ファイルをオープンする。openatはfdからの相対パスでのオープン
- creat 新規ファイルの作成(open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)と同値。WRONLYなのでつらいね)
- lseek openされたファイルは、ファイルオフセットという位置を管理する
- これをセットしたりいじったりする。シーク不能ならば-1を返す(パイプ、FIFO、ソケットに対してはシーク不能)。
- ファイルサイズを超えた位置にシークすることは許されていて、writeするとシークしていない部分はちゃんと0で読めて、しかもディスクブロック数は抑えられるらしい(hole, 間隙)。
- read 要求バイト数を指定して、ファイル/ネットワーク/パイプ/FIFO/レコード型装置から「読む」。30文字しか入っていない状態で100バイトを読もうとすると、readはまず30文字を返し、次に読むときに次に0文字を返すらしい。
- 同じファイルを複数のプロセスからいじる場合、lseek->read, writeがアトミックである必要があるが、それはpread, pwriteで保証できるらしい(ちなみに、appendは自動的にatmicなので気軽に使って良い)
- fcntl 初めにopenした時にO_WRONLYといったが、あとでappendに変えたい、みたいなことができる
プロセス †
構造 †
- プロセスはinitプロセスを根とした木構造
- initプロセスの番号は常に1
- pstreeを使うとプロセスの木構造を見ることができる!
- プロセスグループIDとは、initの直接の子cの部分木をグループcと名づけている
- ゾンビプロセス
- プロセステーブルのエントリでしかない(4kb-8kbくらい)ので、あまりリソースは食わない。
- 原因は二点
- 親が先に死んだプロセスは孤児プロセス
- 子プロセスが終わったのに親プロセスがwait()してくれなかったプロセスはゾンビプロセス(その意味では、全ての正常終了するプロセスはゾンビプロセスの状態を一瞬介す。これ簡潔で良い: A zombie process is simply a process that has exited but its parent has not yet read the processes exit code. )
- 対処方
- 基本的にはゾンビプロセスそのものはkillでは殺せない
- 親を殺しても、親の親にすげ替えられるだけ
- ゾンビプロセスを終了させるためには「kill -9 <PID>」コマンドを実行しますが、ゾンビプロセスの親プロセスが CentOS7 の場合「systemd」、CentOS6 の場合「init」の場合は OS 再起動しかありません。
- また、kill -9 <PID>コマンドでもゾンビプロセスが消えない場合は、やはり OS 再起動しかありません。
- 起きうる問題
- 基本、1個や2個ある分には問題ない
- ただし、ゾンビプロセスが継続的に発生すると、プロセステーブルが一杯になり、場合は新規でプロセスを生成することができなくなります。(forkが失敗します)
システムコール †
- プロセス制御はfork, exec, waitpid
- spawn=fork+exec
- execは7種類ある
- fork(2)
- 自分のプロセスコピーを作る
- プログラムポインタの位置まで同じプロセスがその時点で作成される。キモい。
- forkの返り値によって親か子かがわかるという仕様
タスクの種類と優先度 †
- 優先度
- 静的優先度=120+nice in [-20, 19]。niceと静的優先度は同値
- 動的優先度=CPUを使いまくっていると優先度が下がってしまう
- タスクにはいくつかの種類がある
- スケジューリングポリシー
- SCHED_OTHER, SCHED_BATCHは、niceにより割当時間が変わる(1違うと1.25倍伸びる, 5変わると3倍伸びる。nice値はthreadごとに割り当てられる!!)
- SCHED_IDLE(超優先度低い)
- SCHED_FIFO, RR (FIFOは入力待ちまで他に制御が映らない、と思いきや1秒に一回移る(入力待ちしないプログラムだったらずっと俺のターンだと思っていたのだけど…)。RRは他にFFにタイムアウトが付いたやつ。リアルタイムで、priority = 1-99)
- SCHED_DEADLINE(散発タスク)
- 優先度の分類
- 優先度は1-129まである
- 1-100がrtprioで、101-129が普通のpriority
- rtprioにはnice値は無いし、otherのプロセスにはrtprio値はない(完全に一対一)
- rtprioはFIFOかRR
- psでこれを確認するには、ps -C stress-ng -o comm,pid,ppid,cls,rtprio,nice,%cpuなどとする
- スケジューリングポリシーを変えるにはsched*(2)を使う
- 優先度とスケジューリングポリシースケジューリングされる
パイプ †
- 入力したものを出力するだけの存在、まさに「パイプ」
- これクソわかりやすいパイプの説明
- 要するにdupは開いてるファイルディスクリプタを入力して、閉じてるファイルディスクリプタのうち最小のものに帰る
シグナル †
- killコマンドで送れる
- プロセス番号とシグナル番号を指定すると、プロセスがシグナルをコールバック的にtrapできる(trap=シグナルのコールバック設定)。
- C言語では、signal(3)関数(デフォルトで無視する、みたいなsig = signal( SIGTSTP , SIG_IGN );という書き方もある)
- シェルスクリプトでは、trap 'command' [signal id...](これでEXITシグナルをtrapすると、プログラム終了時にメッセージを出すとかtmpファイルを消すとかができる)
- SIGKILLだけはtrap, 無視不能!(強制終了なので)
- シグナルは何と言うか実装指針であって、別にsigintを受け取って終了しないような実装をしてもよい(sigkillだけは特別!!)
- 例えば、ddコマンドはSIGUSR1を受け取って進捗状況を表示する
- kill -lで全シグナルをチェックできる。よく使うのは以下。
番号 | 名前 | 説明 | 0 | EXIT | プロセス終了時に、プロセスが自分自身に対して送出する | 1 | HUP | ハングアップシグナル(SIGnal HUng uP)。XWindow のクローズで発行される。また、慣例的にデーモンのリセットに使用される。端末で実行しているコマンドは、SIGHUPを受け取ると終了します。従って、X(X Window System)環境でコマンドを実行している最中に端末アプリケーションを終了すると、そのコマンドは終了します。また、ssh接続でコマンドを実行している最中に回線が切断された場合も、そのコマンドは終了します。これを防ぐのが「nohup」コマンドです。「nohup コマンド &」のように、コマンドnohupでコマンドをバックグラウンド実行させると、端末を終了させてもコマンドがSIGHUPを受け取らないようになり、その結果、コマンドは終了しなくなります。サーバプロセスの多くはSIGHUPを受け取るとプロセスを終了して再起動します。このため、SIGHUPシグナルは「設定ファイルの再読込」をさせたいときにも使われます。 | 2 | INT | Ctrl+C や Del キーを押したときに発生する割り込みシグナル(Ctrl-Cとkill 2は実はちがくて、Ctrl-Cはその子にも全部SIGINTを送る) | 3 | QUIT | Ctrl+\ を押したときに発生するクイットシグナル。**デフォルトはコアダンプする**。pingなど処理して殺せないものもある | 9 | KILL | プロセスを強制終了するためのキルシグナル。強制終了なので当然、trap はできない。 | 15 | TERM | プロセスを終了させるための終了シグナル。kill コマンドはデフォルトでこのシグナルを使用する。INTとTERMの違いは、ターミナルのCtrl-Cで発行できるかどうかくらいの違いで、たいして変わらない | 18 | CONT | プロセスに再開を通知(fg) | 19 | STOP | プロセスに中断を通知, **ハンドルできない!!** | 20 | TSTP | プロセスにサスペンドを通知する。(Ctrl+Z) |
- STOPとKILLは無視、ハンドルはできないので注意
- 基本Ctrl-CはSIGINTだが、全ての子プロセスに対してSIGINTを送っている。つまり、親だけではなく子も全部死ぬ。
- 一方、kill -SIGINTをすると、親だけ死ぬ。子は孤児となってinitプロセスに引き取られる
- 子プロセスがSTOP, CONT, EXITした時には、親プロセスにSIGCHLDが送られて、waitpidがreturnするらしい。
- プロセスの状態 状態遷移
- R TASK_RUNNING: TASK_RUNNING(実行中)
- S TASK_INTERRUPTIBLE: sleep, cin待ちなど
- D TASK_UNINTERRUPTIBLE: シグナルを処理することすらできないような大事なタスクをやってる。Dは非常に短い時間のみであることが期待されている。
- T TASK_STOPPED: SIGSTOPやSIGTSTPで止まった
- TASK_TRACED: デバッガで別プロセスに監視されているとこの状態になる
- Z EXIT_ZONBIE: EXITなことに注意。ゾンビ。プロセスに関する統計情報を親プロセスが収集できるようにするためだけに残されている。
- EXIT_DEAD: もう終わり。
- おまけ: TASK_KILLABLE killは重要なのでカーネル2.6.25からはこの状態が加わった。
- D Stateが長いとマジでヤバい
- 本当にリブートしか対処のしようがない。kill -KILLも効かない(uninterruptableなので)
- kill -KILLで殺せない場合
- 基本的にSIGKILLはinitプロセス以外を「いずれ」殺す(すぐに殺すとは言っていない)
- initプロセスは殺せない
- テープのようなデバイス待ち(ps D stateの時)→デバイスの処理を終了させてから殺す。デバイスの処理が終わるのを待つしか無い、終わらなそうなら殺せない。
- プロセスが、使えないリソースを待っている場合(NFS=ネットワークファイルシステムなどでハードリンクしようとした場合)→kill -QUITなら殺せるという情報が会ったが、そんなはずなくない?
- プロセスがゾンビ→rebootしか方法がない
- topコマンドでkを押すとkillコマンドみたいな感じでシグナルを送れる
ファイルシステム †
- 実は/とnull文字以外の文字は全て使えるが印字可能な文字だけを使いましょうね
- i-node
- i-node?
- ディレクトリは、ファイル名→iNodeを管理
- 1つのinodeに対して複数のファイル名を割り当てることができる(ハードリンク、lnの-sオプションなし版)
- シンボリックリンクはパスが書かれてるだけのただのファイル
- i-nodeの個数制限がある!
- ディスクは有り余っていても、i-nodeが枯渇してリソースフルになる可能性もある
- リテインカウントみたいなことができる
項目 | ハードリンク | ソフトリンク | 概要 | ファイルの実体につけた別名、実体はi-nodeへのポインタ | ファイル・フォルダの代理人ファイル、実体はただのパス | パーティションが | 違うと作れない | 違う場合でも作れる | フォルダ | フォルダに対して作れない(inodeはファイルに対する概念なので) | フォルダに対しても作れる(パスなので) | 削除時 | 全ハードリンクされたものが消されると消える | シンボリックリンクを消しても元のファイルは消えない(ただのパスなので) |
時間 †
- timeコマンド
- real, usr, sysという3つがある。
- realは実時間で、他のプロセスが立ち上がっていたりしたら多くなる(クロック時間)
- usrはまさにそのプロセスが使った、ユーザ空間での時間(ユーザCPU時間)
- sysはまさにそのプロセスが使った、システム空間での時間(システムCPU時間)
man †
- manのあとの数字は、とりまコマンド(1), システムコール(2), C言語関数(3), 設定ファイル(5), 管理者用コマンド(8)だけ覚えとく
- 特に5を忘れがち。例えばman crontabとするとcrontabコマンドが表示されるが、SEE ALSOにcrontab(5)と書いてあるのでそれを見ると良い
man 1 ls # コマンド
man 2 chmod # システムコール
man 3 sqrt # C言語の関数
man 3 errno # C言語の変数
man 5 crontab # 設定ファイル
man 5 passwd # /etc/passwd
man 8 syslogd
errno †
- じつはEACCESとかENOENTとかをerrnoに突っ込むとperrorの表示が変わる
- char* strerror(errno_t)みたいな関数もある(perrorのあとに出てくる文字列を返す関数)
- ちなみにperrorにargv[0]を渡すのが慣習らしい(パイプしまくった場合にどこでミスったかわかるので)
- errnoには致命的な奴と非致命的な奴がある
- 致命的なものはログはいて終了するしかないOAuth, basic auth
- 非致命的なものは、待って再試行(待つ時間をだんだん長く=エクスポーネンシャルバックオフ)をするのが典型的な回復方法。もちろん回復するとは限らないが
ユーザ・グループ †
- /etc/groupにグループが定義
- /etc/passwdにユーザが定義
- ルートユーザはユーザID 0
- 補助group idでは最低8個の補助的なグループがある。/etc/groupをみると、各グループに補助的に入っているユーザ名が羅列されている
- C言語ではgetuid, getgidを使ってユーザIDとかを取得する
oom-killer †
- Linuxにはメモリの内容が限界に達しようとすると、自動でメモリリソースを大きく消費しているプロセスをkillする仕組み
- たまに重要なシステムプロセスをkillして、サーバプロセスやXなどのプロセスがkillされることがある
- Oom-killerの優先度合いは/proc/<PID>/oom_adjの値を設定することでさだめることができる。-16から+15のあいだで指定できる、数字が高いほど優先順位が高くなる。-17にすることでOom-killerの監視対象から外すことができる。
シェルスクリプト †
TTL †
- データの寿命
- DNSキャッシュでは、フルサービスリゾルバのカンペの寿命 (s)
- パケットでは、ルータの通過回数
ネットワーク †
ドメイン †
- インターネット上に存在するコンピューターやネットワークを識別するための名前
- 人がIPが読みにくいというただそれだけの理由で生み出された存在
- 右が大きい。地区.市.県.国、みたいな
- 一番右からトップレベル・ドメイン、第二レベルドメイン、…
- トップドメインの分類
- 汎用トップレベルドメイン (gTLD)=どこの国の人でも使っていい、使用用途依存のドメイン
- 誰でも取得できるもの(.com)
- 条件を満たす必要があるもの(.govはアメリカ政府用とか)
- 国別コードトップレベルドメイン(ccTLD)=国依存のドメイン
ループバックアドレス
自分自身を示すIPアドレスのこと。
アドレスの始まりが127のものは、ループバックアドレス用として予約されている。
IPv4では127.0.0.1が使われている(ホスト名はlocalhost)。-トップレベル・ドメイン
リバースプロキシ †
- 目的は、負荷分散と身元の隠蔽
- 実体はapacheとかnginxとか
- 例えば、443ポートに来たHTTPSリクエストをビデオサーバにポートフォワーディングしたい場合、まずリバースプロキシが受け取る。そして、GETリクエストのURLをみて/videoserverだったら、ビデオサーバの8000番ポートにポートフォワーディングするなど。
HTTPサーバ †
- 代表的なのはApache, Nginx, IIS(Windows), GoogleWeb? Server(非公開)など
- Tomcatというのを聞くが、これはjavaのコンパイル済み実行ファイル(サーブレット)を動かすためのエミュレータみたいなもの(サーブレットコンテナ)なんだか、何故かWebサーバとしての機能も持ってしまっているもの。
- ちゃんとやるときはTomcatとApacheと並列させて動かすらしい
- Nginxはリバースプロキシの機能が付いている
- Nginxはスループット重視でロードバランサーとして動く
- Nginxを複数のApacheサーバにつなげておけば、割り振った先でphpによる動的コンテンツ生成などを行える
- ロードバランサはグローバルアドレスをもった仮想サーバとして機能する。
- クライアントからのリクエストを本物のwebサーバに中継することで、あたかもロードバランサがwebサーバのように振る舞う。
- メリット
- グローバルアドレスが節約出来る。
- DNSラウンドロビンのようにグローバルアドレスをwebサーバごとに割り振る必要がなくなる。
- 生きているwebサーバだけにアクセスがいく
- ロードバランサは必ずヘルスチェック(webサーバが生きているか確認)してからwebサーバを選択するので、1台でも生きているwebサーバがある限り稼働する。
- VRRPというルータの冗長化プロセスもあるらしい。
https †
- ローカルと、認証局に問い合わせの二段チェックをする
- サーバは証明書を誰かに発行してもらう必要がある
- HTTPSサーバは、初め証明書を誰かに買うなりなんなりしてもらわないといけない。
- 証明書を発行する権利がある人がいるので、その人から買うなり何なりする。
- let's encryptを使うとただで使えるが、何故か3ヶ月で執行するので更新する必要がある。
ステータスコード †
- ソフト404エラー
- ブラウザ上ではそのページが存在しない旨のメッセージが表示されてるのに、ステータスコードとしては404や410を返していない(200 OKが返されている)パターン
- GoogleBot?がクロールのリソースを無駄に消費することになりますので、存在しないページにアクセスしたときはステータスコードとして404もしくは410(gone)が返されるように正しく設定するべき
クッキー †
- https://wacul-ai.com/blog/access-analysis/access-analysis-basic/access-analysis-cookie/
- HTTPがステートレスであることを解決するために、サーバが初めに個々別に会員証を発行する方法
- 1回目の訪問時にクッキーをサーバが発行し、
- 2回目以降はクッキーを付与してサーバにアクセスする。すると、サーバからのHTTPリクエストを何回目のアクセスかによって変えることができる。
- セキュリティ・プライバシーの問題をはらむ
- あるサイトにアクセスした時、そこに埋め込まれた広告はHTTPリクエストを盗み見することができる
- 盗み見した内容をバックのサーバに貯めておくと、個人情報を集めることができてしまうらしい(?)
- クッキーとキャッシュ
- クッキー:会員証のような役割。次にアクセスしたときに「前はこれをやったね。次はこれ」と表示内容を個人に合わせて変えることができる。
- キャッシュ:ブラウザなどが、ウェブページの画像やデザイン情報を一時保管⇒次に同じページにアクセスしたときにサクッと表示してくれる仕組み。
- クッキーを消すと、アプリケーション側からみると「サーバ側が一時記憶喪失した」ように見える。
- キャッシュを消すと、通信が重くなるだけ。
パケット †
- パケットは以下のヘッダをもつ
- MAC層: -次の受取人=送信先MACアドレスなどをもつ
- データリンク層(2): MACアドレスで隣り合う通信機器との通信をする
- IP(3): 届け先が書いてある
- TCP/UDP(4): 荷物の番号付け・ポート番号など
- TCP/UDPでは、ポート番号を指定して、サーバのどのアプリケーションへ接続したいかを示す「ポート番号」がデフォルトで着いている
IP †
- A 10.0.0.0 255.0.0.0 10.0.0.0 - 10.255.255.255
- B 172.16.0.0 - 172.31.0.0 255.240.0.0 172.16.0.0 - 172.31.255.255
- C 192.168.0.0 255.255.0.0 192.168.0.0 - 192.168.255.255
ループバックアドレス
自分自身を示すIPアドレスのこと。
アドレスの始まりが127のものは、ループバックアドレス用として予約されている。
IPv4では127.0.0.1が使われている(ホスト名はlocalhost)。
TCP/UDP †
- TCPは検品
- パケットは小出しにするので、10個口のパケットが「1->8->3->4...->2」とへんな順番で届く可能性がある。これを整理し、ダブリ・破損・欠損を再配達依頼するのがTCP
- TCPとUDPはOSIのレイヤ4(トランスポートプロトコル)
- TCPは運送元・運送先を互いに認識するために、
- 3-Way Handshake (SYN,SYN-ACK,ACK) -> Establishedというスタイルを取る
- SYNchronize-ACKnowledgement
- TCPは荷物を小分けにして送る運送業者。順番が変わったりしても大丈夫。渋滞したら送るスピードを調整する
- 欠けて困るデータはTCPで送り、ちょっとくらい欠けても何とかなるデータはUDPで送る
- 印刷とか音楽のストリーミング配信とかはUDPですね。1ドット欠けたり、何万分の1秒途切れたりしてもそんなに気にはならない。むしろチンタラやって止まる方が困る
- TCPは1対1の通信で使えます。UDPは1対多の通信でも。
- TCPの理解が必要なのは、
- アプリケーションのパケットレベルのデバッグをする場合。 具体的には、tcpdump の出力を解析したりする場合。
- ネットワークの障害調査を行う場合
- ファイアーウォールの設定をする場合
- tcpdump
- どういう問題を解決したいか?
- 謎のパケットが飛びまくっていてクソ重い場合
- DHCPが二台会ってブロードキャストがなんかヤバイ時
- ナマのログだとヤバイので、Wiresharpとかを使ったほうが良い
- LISTENINGとは、要するに、「今私はサーバとして動いています」ということ
DNS †
- 2種類ある
- DNSキャッシュサーバ=フルサービスリゾルバは、「カンペを見て(キャッシュ)」「なければ他のDNSに聞きに行く」
- 初めに聞きに行くやつがDNSルートサーバ(トップレベル・ドメイン単位でしかみてない)
- 要するに社内の向きDNS
- 権威DNSは、「IPアドレスを返す」。こいつは他のDNSには聞きに行かない
- ゾーン
- ドメイン名の.区切りがなす木構造があって、この部分木のうち、「委任」が発生した部分を「ゾーン」と呼ぶ(管理者が同じとかいうケースもあるし、あまり定義が明確ではない?)。
- 各ゾーンに、別の管理者によって管理されたDNSサーバがある
- 例えばjpサーバはjp DNSで管理されていて、example.co.jpはwww.example2.jpを持っている場合、jpゾーンがwww.example2.jpを含むとは言わない。
- DNSポイズニング
- はじめの問い合わせの返答の数百ミリセカンドの間に質問番号を総当たりして嘘のIPを覚えさせる
- プライマリDNS, セカンダリDNS
- 権威DNSサーバさんは、普通、同じようなやつが2台同時に動いています。
- メインのやつがプライマリ、そうじゃないのがセカンダリ
- 人間から見るときの差は、セカンダリはプライマリからゾーンファイルの設定を転送してもらっているという点。
- マスターとかスレーブとかいうこともある
- 権威DNSサーバは、ゾーンファイルにしたがって、以下の4つ行う
- トンチンカンならエラーを返す
- 自分が知っているならそれを返す
- 知っているサーバを知っているならそれを返す
- 知らないなら知らないと言う
- よく思い浮かんでしまう疑問:グローバルIPアドレスと内部のIPアドレスがあるが、DNSは両方指定しないといけないんじゃないの?
- 答え:NASなりDNSがポートフォワーディングして、内部の適切なサーバに繋いでくれているからOK
名前 | やること | 備考 | A, AAAA | ホストに対するIPアドレス | Aは正引き | PTR | IPアドレスに対するホスト名 | PTRは逆引き | CNAME/ALIAS | ホスト名のエイリアス | | NS | 「こいつが知ってるよ」と上位のDNSサーバから下位のDNSサーバを教えるための情報(jpサーバはco.jpをNSレコードとして持っているなど)、自分が知っていれば自分の前を書く | これは委託権限のあるDNSで設定される | SOA | そのゾーンでのTTLとか色々な基本設定 | | MX | メールサーバのホスト名を指定. 優先度がある(数字が小さいと優先度高い) | なぜホスト名なのかIPでよくね(そのIp知らないケースもあるか) |
- わからないものが会った場合は、即刻(!)ルートサーバ(世界に13個しかない)に問い合わせる。ルートサーバは「jpとかcomとかが末尾に来たらこれに問い合わせろ」という謎のDNS設定がなされている。
検索方式 | やること | サーバの名前 | どういうやつ? | Recursive | ルートサーバに問い合わせ、DNS解決するまで責任を持って返答する。 | DNSキャッシュサーバ, Full-service Resolver | 要するに社内ネットワークの内向きDNSサーバ。ファイヤウォールの中 | Iterative | 自身が管理しているゾーン情報だけから返答する | 権威DNSサーバ, authoritative DNS server, DNSコンテンツサーバ | 要するに外向きDNSサーバ。ファイヤウォールの外 | Stub | Recursive DNSサーバにお願いをするだけ | クライアント | 普通のノートパソコンとか。Stubというのは要するにクライアント |
- WindowsのActive Directoryだと、ゾーンは三種類ある(しらんけど〜)
- Primary Zone
- Second Zone
- Stub Zone
DHCP †
- LANにコンピュータをつなげると、コンピュータがまず泣きわめく(?)
- DHCPでどうDNSを知るか
- /etc/resolve.confのnameserverはDHCPから持ってくる
- nameserverはIPである必要があるように思えるが、/etc/host.confか何かに既知としてあるならば別にこれでも良いね
HTTP/HTTPSサーバ †
- ブラウザはウェブサーバに依頼をしてウェブページを渡してくる
- コード
- 400 なんかよくわからんがおかしい(デバッグめんどい)
- 405 許可されていないメソッド(GET, POSTなど)でアクセスしようとしたから無理
- 500番台 Webサーバ側のエラーだからクライアントはどうしようもねえ
- HTTPリクエストメソッド(いっぱいあるがGET, POSTだけ覚えておけば困らない)
- GET
- POST
- PUT, DELETE, HEAD, CONNECT, OPTIONS, TRACE, LINK, UNLINK
- HTTPリクエスト->HTTPレスポンス
- HTTPリクエストは以下のようにできている。
- リクエストライン
- ヘッダ
- [改行]
- メッセージボディ(大事)
POST /search.html HTTP/1.1\r\n
Host: wa3.i-3-i.info\r\n
Connection: keep-alive\r\n
Content-Length: 38\r\n
Cache-Control: max-age=0\r\n
Origin: http://wa3.i-3-i.info\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: うんちゃら\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Referer: http://wa3.i-3-i.info/index.html\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: ja,en-US;q=0.8,en;q=0.6\r\n
\r\n
q=test&submitSearch=%E6%A4%9C%E7%B4%A2
- GETはURLにデータを明示的にくっつけてサーバに送る方式
- POSTはURLを変えずにデータをサーバに送る方式
- 具体的にはHTTPリクエストのボディ部にくっつくので、ブラウザの履歴とかにならない(それでもHTTPは盗み見可能なのでパスワードとかはHTTPSじゃないと送っちゃダメ)
- HTTPレスポンスは以下のようにできている。
- HTTPステータスライン(ステータスライン)
- HTTPレスポンスヘッダ(ヘッダ)
- [空行]
- HTTPレスポンスボディ(レスポンスボディ)
- GETとPOSTの差
- 「GETメソッドはPOSTメソッドと比べて渡せる情報量が少ない」
- 「GETメソッドは渡した値が履歴に残る」
- プロキシという仕組みではURLを記憶しておくので、場合によっては全然関係無い別の人にも渡した値を知られてしまいます
- 最悪の場合は、検索エンジンさんに載ってしまって、全世界の人に知られてしまうかもしれません。
HTTP/1.1 200 OK\r\n
Server: nginx\r\n
Date: Tue, 11 Jul 2017 09:23:07 GMT\r\n
Content-Type: text/html\r\n
Transfer-Encoding: chunked\r\n
Connection: keep-alive\r\n
\r\n
<!DOCTYPE html>\r\n
<html lang="ja">\r\n
<head>\r\n
\t<meta http-equiv="content-type" content="text/html; charset=UTF-8" />\r\n
\t<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">\r\n
\r\n
\r\n
\t<meta name="keywords" content="\350\276\236\345\205\270,IT,\347\224\250\350\252\236,\345\210\235\345\277\203\350\200\205">\r\n
\t<meta name="author" content="Makoto Sasaki">\r\n
\t<meta name="copyright" content="Copyright PCS">\r\n
\r\n
\t<meta name="application-name" content="\343\202\217\343\202\217\343\202\217IT\347\224\250\350\252\236\350\276\236\345\205\270"/>\r\n
\t<link rel="stylesheet" href="css/style.css?ver=00109">\r\n
\t<link rel="stylesheet" href="css/search.css?ver=00109">\r\n
\t<script src="./js/jquery-1.7.2.min.js?ver=00109"></script>\r\n
\t<script src="./js/common.js?ver=00109"></script>\r\n
</head>\r\n
<body>\r\n
(中略)
</body>\r\n
</html>\r\n
\r\n
- プロキシサーバ
- HTTPリクエスト・レスポンスを代行してくれるサーバ
- メリット
- 身元を隠せる
- キャッシュによりホームページアクセスが早くなる可能性(同じネットワーク上の他の人がそのURLを一回見たかも知れない。デメリットはTTLと更新タイミングによっては、最新版を持ってきてくれない可能性があること)
- ネットワーク上の人のアクセス記録を一元管理できる
- appachには意味不明な攻撃みたいなものを受けるとtrapというファイルを作ることがある。例えば、GETみたいに書くべきところに"is-3"とか書いてあるいみたいな意味不明な奴とか、IPと共にヘッダにホスト名がきちんと書いてあるはずなのに書いていないとか。
スプリングフレームワーク
Java
現行これが最強
HTTPリクエスト・レスポンス †
304はif-modified-since-headerより古かったから更新しなくて良いよというやつ。
chromeのdevtoolのNetworkでリクエストが見える。ステータスコードが薄くなっているのは、ブラウザのキャッシュから取ってきたという意味 (Provisional headers are shownは実際に取ってきた最後のリクエスト) どうやら、更新ボタンを押したその部分はちゃんと聞き直しに行くが、それが304とかだったら更新ボタンを押したページに依存するような部分はキャッシュから持ってくるっぽい。
APIの叩き方 †
- 基本なんか叩くときは、
- GETとか書いて
- URL書いて
- ボディ書いて
- ヘッダに認証書いて
- 投げる
RESTAPI †
- URLは動詞を含まず、複数形1/番号1/複数形2/番号2/複数形3/番号3のようにリソースを指定し、そこへの操作はHTTPリクエストで指示するという方法
- ルール
- 長くするな
- 同じURLにDELETEをかけても1レコードしか消すな
- PUTしないかぎりGETの返答を変えるな
- xmlかJSONで返せ。など
- 動詞部分はHTTPリクエストで指定
- GET → 取得
- POST → 新規作成
- PUT → 更新
- DELETE → 削除
デバッグ †
- デバッグ方法
- curlでHTTPリクエストを投げたり受け取ったりすることができるコマンド
- ブラウザでHTTPリクエストを投げることができるのがpostman。これはchrome拡張
ゲートウェイ †
- a path from your computer to other networks
繰り返しになりますが、デフォルトゲートウェイは「データのお届け先が分からないときの取りあえずの送り先」です。
それでは、なぜ「ネットワークの出入口」と説明されるのでしょうね。
その理由は
デフォルトゲートウェイに送られたデータは別のネットワークに流れていく
からです。
データの送り先が同じネットワークであれば、直接お届けできます。
わざわざデフォルトゲートウェイさんに送ってよこす必要は、ありません。
デフォルトゲートウェイさんに送ってきたということは、送り先は同じネットワーク内にない(他のネットワークにある)ことを意味します。
見方を変えれば
ネットワークから出ていくデータはデフォルトゲートウェイを通る
ルータはスペシフィックにネットワーク層(3)のルータで、機器そのもの。ゲートウェイはもう少し機器の役割的なもの。
zookeeper †
- 複数プロセスからAtomicにアクセスできるメモリ
- これを仮定するとかなりシステムデザインが楽になる。例えば、プロセスごとにまだ利用していないRangeをアサインする、みたいな処理ができるから。
ログ解析ツール †
VPS †
- 仮想専用サーバ
- 1台のコンピュータを複数の人で使うけど、利用者ごとのスペースは独立している形態
NAS †
- あるネットワークへの門番となるコンピュータがネットワークアクセスサーバ(NAS)
バーチャルホスト †
Etherealを使うと、自分が送ったパケットと受け取ったパケットの中身を、直接見ることができます。そのため、これまで絵に描いていたパケットの中身を、直接、確認することができます。
・すべてのやりとりが見えますか?
これまでに紹介したもの、例えば、ARPを使ったMACアドレスの取得、DNSの名前解決、Webサーバアクセスなどは、いずれも上位レイヤから下位レイヤまで、すべて見ることができます。
ARP †
- Address Resolution Protocol
- IPを入力して、送信先のMACアドレスを知る方法(L2は宛先MACアドレスがないと通信できないので)
- 同じネットワークにIPがいるなら:ARPで宛先のIPを叫び、MACを得る
- 同じネットワークにIPがいないなら:ゲートウェイのIPを叫び、MACを得る
LANケーブル †
- 要求伝送スピードに応じて、高周波になるので、ノイズ対策する必要があり、LANケーブルを交換する必要が出てくる可能性がある
- CAT 5, 6, 7(+e)などがある。
- クラスが上がると3倍ずつ値段が高くなる(cat5eで60yen/m)
- **CAT 5**だけはやめましょう(それ以外なら、光回線がボトルネックになるので、日用用途はどうでも…)
コマンド集 †
top †
- プロセスの状態を一覧するし続けるコマンド
- 用語
- load averageは、stateがRかDとなっているプロセスの数を、1, 5, 15分平均したもの(CPUコアがあって一個ドーンとプロセスがあるのでなければ、コア数で割ってよし。)
- %Cpu(s)とは、合計100パーセントで、以下の百分率が出る
- us ユーザプロセスの使用時間
- sy システムプロセスの使用時間
- ni 実行優先度を変更したユーザプロセスの使用時間
- id アイドル状態の時間
- wa I/Oの終了待ちをしている時間
- hi ハードウェア割込み要求での使用時間
- si ソフトウェア割込み要求での使用時間
- メモリ使用量
- total メモリの合計容量
- used 使用中のメモリ容量
- free 未使用のメモリ容量
- buffers バッファに使用されているメモリの容量
- プロセスごとの情報
- PID プロセスID
- USER プロセスを実行しているユーザ
- PR プロセスの優先度
- NI ナイス値(相対的優先度)-20(最高)~19(最低)
- VIRT プロセスの仮想メモリサイズ(要するに、確保したサイズ。Unixではmmapでファイルをマップしたり、mallocで確保はしたけど、アクセスしていないところには、実は物理メモリが割り当てられない!)
- RES プロセスが使用している物理メモリサイズ(要するに、アクセスしたサイズ)
- SHR プロセスが使用している共有メモリ
- S プロセスの状態
- %CPU CPU使用率
- %MEM 実メモリ使用率
- TIME+ プロセスの実行時間(秒)
- COMMAND 現在実行中のコマンド名
nslookup †
- 名前解決の問題解決用
- インタラクティブにできてうれしい
- nslookupでいうnon-authoritativeとは要するに「キャッシュされているからわかるよ」という意味
ps †
- -eo pid,pgid,command によって、プロセスID, プロセスグループID, コマンドのタプルが得られる。
- ps auxがよく使う(情報量マシマシ)
pgrep †
traceroute †
- IPパケットの、pingのTTLを1コずつ増やしていく
- どうやって送るか(L4の、ICMP/TCP/UDPのどれで送るか)はOS依存
- WindowsならICMP
- LinuxならばUDPのハイヤーポート33443
- LinuxでICMPでpingしたい場合(それしか開けていない可能性)、-Iオプションをつければよい(root権限必要)
- UDPハイヤーポート33443は、環境によってはファイアウォールなどで遮断されている可能性
- 何でtracerouteの逆引きが効かないんや
- わかること
- Pingが最終的な宛先に届かなくても、途中の経路までは届く場合を調べられる。自分側かあっち側か。自分側ならどこが怪しいかがわかる。
- 相手側の例としては、最終的な宛先のFirewallで拒否されている場合や、最終的な宛先の直前のルーティングが間違っている場合など
df †
df -h # サイズ
df -i # inode
バックアップ †
- いろんな種類のバックアップがある
- Normal Backup
- Copy Backup
- Differential Backup
- 最後に行われたフルバックアップからの差分を持つ
- 前回フルバックアップ+差分1回で復元可能なので、復元が楽
- Incremental backup
- O(tD)のデータ容量がかかるのでつらい
- 最後に行われたIncremental Backupからの差分を持つ(わかりやすい説明)
- 前回フルバックアップ+差分n回での復元が必要なので、復元がめんどい
- 一回の増分が失われただけで、それ以降のデータが復元できなくなる
- O(D)しかデータ容量がかからないので軽い
- Daily backup
- Full Backup
- 全データがバックアップされる。普通定期的に行われる(同期はどうするの?その間操作不能じゃん)
- アーカイブとは目的が異なる
- アーカイブの目的は安価なデバイスに長期的に保存するためのもの
- オンラインバックアップ
- システムを止めずにバックアップする方法
- ストレージのデータ更新時に非同期・リアルタイムにバックアップ(ディスク書き込みが終わったという判定は難しいので、衝突とか起きがち)
- キャッシュに似てるね
- オフラインバックアップ
- まあ止めてるのでね
- もうHDD障害があるもののバックアップ
- 熱で膨張したりするので、必ずファンで冷やしながら作業
- 木槌で叩くとモーターの軸が回っている段階で衝撃を加えて軸が運よく外れて、回転するという。ただ、またロックしてしまいますね、ヘッドを傷つける可能性もある当然バッドノウハウ
- RAIDとの違い
- **誤って書き換えた時にも直せるのがバックアップ**
- RAIDはディスクの経年劣化・部屋レベルのローカルな障害に対する頑健性を上げる
- バックアップは、物理障害、浸水、温度、災害、戦争、倒壊に対しての頑健性を上げる
RAID †
- RAID0
- ディスク遅いので、データを細切れにしてディスク並列化することで、ディスクIO読み書きのスループットを向上
- RAID1
- RAID5
- 三代以上のHDDを用意して、群的ハッシュH(A, B)を持ってきて、A B H(A, B)を保存する。一台壊れても、群的なので復元できる。
- RAID1+0
トラブルシューティング †
- **トラブルシューティングの重要なのは、どう考えているか。ちゃんとマインドマップを書くことだけが大事。**
- URL間違っていない?
- IPアドレスはります
- ping, tracerouteは、ICMPをブロックしてるのも多いから、あまりIP直だたきだけではだんていできない、なぜならIP直でつながらないのは普通、ホスト名とセットじゃないとtrapがあるので。この知識はでもサーバ側で得られるはずなので
- ネットワークの状態を把握
- とりまtraceroute、どこがミスってるか?
- まあそんなことはなさそうだがDNSなど、最近変えたとかでない限りは
- 他のサイトは?
- Windowsは?
- ネットワークは局所的?
- 内向き?外向き?
- ありがち問題
- Wifiつながらない(DHCP)
- ホームページが見れない
- ssh繋がらない
- ハードディスクフル
- i-nodeフル
- ウイルス
- ポートが空いていない
- 他のブラウザでは?(ブラウザがぶっ壊れている、どういう状況?)
- キャッシュ
- メモリフル
- ステータスコード
- 届く?ping
- 届かない→線抜けてないか?→traceroute。止まっている場所を見つけたら、(1) ルータ設定が間違っていて知らないと言われて (2 )
- 通信が上手く行っていないのは、ネットか、相手のサーバが動いていないかを切り分け
- リバースプロキシで多重化されている可能性
1.他のパソコンから、そのホームページを見ることができるか
→見られる:あなたのパソコンの中の何かがおかしい
→見られない:見ようとしたホームページがおかしい[END1]
2.自分のパソコンの他のブラウザから、そのホームページを見ることができるか
→見られる:エラーの出たブラウザがおかしい
→見られない:あなたのパソコンの中の何かがおかしい[END2]
3.ウィルスセキュリティソフトを無効にしたら見ることができるか
→見られる:原因はウィルスセキュリティソフト。解決、おめでとう[END3]
→見られない:ウィルスセキュリティソフトは悪くない
4.cookieや一時ファイルを消したら見ることができるか
→見られる:原因はcookieか一時ファイル。解決、おめでとう[END4]
→見られない:よく分からん[END5]
- この辺、dotファイル作りたい
- 400エラー->あなたのパソコンの中の何かがおかしい [label="他のパソコンから、そのホームページを見ることができる"]
- 400エラー->見ようとしたホームページがおかしい[END1] [label="他のパソコンから、そのホームページを見ることができない"]
- プリンターが動かない
- 変なパターンが印字されるんですが→どう考えてもプリンタドライバの問題。あとは他のひとができるかで、そうでなければプリンタが壊れている
- モニタが動かない
システムデザイン †
例: tinyURL †
Messageing/chat †
- Facebookでは暗号化されておらず全ての情報をキープ
- What's appでは暗号化されているが消える
聞いていること †
- Scalabilityとdurabilityなどを聞いている。
- 考えることは
- API
- Application
- Persistence Layer
- データはどうあるべきか?
- リクエストの個数の仮定(1000リクエスト/sなどが妥当)
- よく使うのは
- Cache
- Zookeeper
- DB
- Blob Server
- サムネをダウンロードしたい時
- ヒストリを持ってきたい時
もしサーバが死んだら?クライアントが死んだら? †
URLに情報を乗せると人にパッと渡せる †
考えるべきこと †
- Concurrency. Do you understand threads, deadlock, and starvation? Do you know how to parallelize algorithms? Do you understand consistency and coherence?
- Networking. Do you roughly understand IPC and TCP/IP? Do you know the difference between throughput and latency, and when each is the relevant factor?
- Abstraction. You should understand the systems you’re building upon. Do you know roughly how an OS, file system, and database work? Do you know about the various levels of caching in a modern OS?
- Real-World Performance. You should be familiar with the speed of everything your computer can do, including the relative performance of RAM, disk, SSD and your network.
- Estimation. Estimation, especially in the form of a back-of-the-envelope calculation, is important because it helps you narrow down the list of possible solutions to only the ones that are feasible. Then you have only a few prototypes or micro-benchmarks to write.
- Availability and Reliability. Are you thinking about how things can fail, especially in a distributed environment? Do know how to design a system to cope with network failures? Do you understand durability?
文脈の共有 †
- Websocket
- 双方向の通信を行うためのもの
- 一回確立されたら切るまで残る
- 繋いだ時点では単に"Heart-beating"しているだけ
- この接続情報はDistributed Cacheとかに格納されないといけない
- BOSH
- Long Pole HTTP
データベース †
- Relational SQLを使うかNo SQLを使うか?
- Relational SQLではput-if-abscentクエリができるので、get->does not exist->putによるノンアトミックなシステムデザインを防げる(MySQL Oracle)。put-if-abscentクエリがあるならばこれでよい。
- もしatomicにできないなら、put->getして、自分がputしたものと同じでないなら、成功するまですればよい。問題は、コリジョンがあろうがなかろうが2回の操作が必要に生る
ロードバランサ †
- ロードバランサの裏にあるサーバを選ぶ基準
- Zookeeperを使って、範囲限定サーバを指定
- number of connections
- average load
- てきとー
キャッシュ †
- App-Cache-DBのつながりの時、AppがDBに直接読み書きするのではなく、Cacheを用意することによって定数倍高速化するテク
- Cacheはメモリ、DBはディスクなので速度が1000倍くらい違うことが重要
- 方式
名前 | やること | メリット | デメリット | ライトスルー | 毎書き込み時、同期的にCache, DBに書き込み | 同じデータの読み書きが高速に行われる場合良い。実装楽。 | 毎書き込みのレイテンシ遅い | ライトアラウンド | 毎書き込み時、同期的にDBに書き込み。読込で失敗したらDBからキャッシュにのせる | ライトスルーよりはレイテンシ少ない。 | レイテンシ遅い。同じデータの読み書きが高速に行われる場合は悪い。 | ライトバック | 毎書き込み時、同期的にCacheに書き込む。暇を見つけて非同期的にDBに書き込む | 毎書き込みのレイテンシ早い。正常系のパフォ最強 | Cacheが落ちるとデータがロスるのでレプリカ作っておいて多重化しないといけない。実装大変 |
- Global Usageの場合、Content Delivery Network (CDN)
- キャッシュとして使う。クライアントに物理的に近いキャッシュサーバを選ぶ技術
- Distributed Cacheとして使うのはRedisがおおいらしい
Rate Limiting †
- APIの頻度制限をする必要がある
- これは当然ロードバランサに置く必要がある
分散 †
トレラントのための分散 †
まとめてデータを送る †
ネットワーク・Disk I/Oのボトルネック †
Windows †
- ウェブダブ
- Windowsの外にファイルシステムが出る唯一の方法
セキュリティ †
ファイアフォール †
- NASなり何なりで外部からのパケット・内部からの要求をチェックし、必要ならばブロックするための機構
- packet filtering firewall(高速、senderとreceiverとポートだけチェックなど)
- application firewall(低速とはいえ別に問題ない、payloadもチェックする)
- proxy firewall
- 最近はそれぞれのコンピュータにファイアフォールがあるらしい
- Windowsには「Windows ファイアウォール」
- macOSには「アプリケーションファイアウォール
- ubuntuは「iptables(ただし、デフォルト設定は何もしていないので、ufwというiptablesの設定を補助するツールを利用するのが普通)」
- packet filtering firewall
- static=IPアドレス、ポート番号を予め決めて、それ以外は外部からのアクセスができないようにする。内部から外部も、必要な
- dynamic=
- stateful packet inspection: 何やこれ
- application firewall
- プロキシサーバを立ててペイロードをチェックする
- プロキシサーバは全てのサーバについて建てる必要があるので、例えばHTTPプロキシ、FTPプロキシ、…と大量につくる必要があるので煩雑
トロイの木馬 †
- 有用なデータに偽装された悪意あるプログラム(バックドアなど)
生まれた疑問 †
そういや忘れていたけど †
- schedはめっちゃやったね
- 農業アプリでDB設計やったね
ログ †
まだまとめていない †
DNSは53 TCP/UDPをポートとして使うらしい。どうして?
DNSはiterativeとrecursiveという2つのクエリがあるらしいそれはなに
RAIDとは?リダンダントに管理するよ。RAID1だと2 or more disksがミラーされるよ。
network connectivity=到達可能性、はpingでやる
メールサーバとそのポートは?POP3(110), IMAP(143), HTTP(80). OutgoingはSMTP(25)
POP, IMAP
DHCP 67 68
DHCPはDORAプロセス=Discover, Ovver, Request Acknowledgementで動く
VM is emulated version of Operating System
Such has network topology, TCP/UDP uses, what the sticky bit is used for.
|