rust-server - 背景
歴史的経緯
Webサーバーの発展
- 最初のWebサーバー
- Tim Berners-Lee が開発 - プロセスベース(prefork)
- モジュールシステム - イベント駆動アーキテクチャ
- 高い並行性 - Node.js, Go
- 非同期I/OHTTPプロトコル
HTTP/1.1 リクエスト:
GET /path HTTP/1.1
Host: example.com
User-Agent: curl/7.64.1
Accept: */*
HTTP/1.1 レスポンス:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13
Hello, World!
コンピュータサイエンス的な意味
サーバーアーキテクチャ
| モデル |
説明 |
例 |
| プロセス/接続 |
接続ごとにfork |
Apache prefork |
| スレッド/接続 |
接続ごとにスレッド |
Java Servlet |
| イベント駆動 |
単一スレッド+非同期 |
Node.js |
| ハイブリッド |
イベント+ワーカープール |
Nginx |
C10K問題
10,000の同時接続を処理する問題:
- 1接続 = 1スレッド → メモリ枯渇
- 解決策:
- イベント駆動(epoll, kqueue)
- 軽量スレッド/コルーチン
- 接続プーリング
TCP接続の状態
クライアント サーバー
| SYN |
|------------>|
| SYN+ACK |
|<------------|
| ACK |
|------------>|
| (確立) |
|<----------->|
| FIN |
|------------>|
| ACK |
|<------------|
実践での活用
リバースプロキシ
インターネット → Nginx → Rustサーバー
→ Rustサーバー
→ Rustサーバー
- ロードバランシング
- TLS終端
- 静的ファイルキャッシュ
RESTful API
// RESTful なルート設計
GET /users # 一覧取得
GET /users/:id # 詳細取得
POST /users # 作成
PUT /users/:id # 更新
DELETE /users/:id # 削除
実世界とのギャップ
本番環境の考慮事項
単純な実装で見落としがちなもの:
- TLS/SSL(HTTPS)
- 圧縮(gzip, brotli)
- キャッシュヘッダー
- CORS
- レート制限
- graceful shutdown
- アクセスログ
- メトリクス
パフォーマンス
// 最適化のポイント
// 1. バッファプール
// 毎回アロケートしない
let mut buf = BUF_POOL.get();
// 2. sendfile
// カーネルでファイル転送
#[cfg(unix)]
fn send_file(socket: &TcpStream, file: &File) {
// sendfile システムコール
}
// 3. TCP_NODELAY
socket.set_nodelay(true)?;