八百万のOSS

ミソラボ

毎回1つまたは複数のOSSを取り上げて、それについてエンジニアであるcatatsuyとへんてこで技術的なところも深掘りながら話をしていく番組です。 https://yaoyorozu-oss.henteko07.com/

  1. 4日前

    #24 ログローテートで何が起きている?ファイルディスクリプタとinodeの仕組み

    CloudWatch Logsのようなクラウドのログ機能も、裏側ではログファイルを読み取り、別のサーバーへ送る仕組みが動いています。今回はFluentdを入口に、Linuxのファイル操作とログローテートの仕組みをcatatsuyが解説します。 まずはファイルディスクリプタとinodeの基本から。`read()`によるファイルポジションの更新、並行処理での`pread()`の利用、複数プロセスからログを書き込む際の`O_APPEND`と`write()`の関係を説明します。 続いてログローテートの仕組みを掘り下げます。ファイルを`mv`してもinodeは変わらず、開いたままのファイルディスクリプタは古いファイルを参照し続けます。Fluentdの`in_tail`はどうやってローテートを検知するのか。inotifyによるファイル監視がログの書き込み頻度によってCPU負荷を高める問題や、`enable_stat_watcher`による対策も紹介します。さらに、nginxが`USR1`シグナルでログを開き直す理由や、logrotateの`create`と`nocreate`の違いも解説します。 logrotateの`O_EXCL`によるファイル作成にも触れ、最後はFluentdの不具合をcronの`touch`で回避した結果、ログファイルの所有者がrootになり、アプリケーションが書き込めなくなった実際の障害を紹介します。 普段は意識しないLinuxのファイル操作が、ログ収集や運用上の問題にどうつながるのかを掘り下げる回です。 ## 関連リンク - catatsuy「logrotateの設定とファイルのアクセスモードについて」(2018年): https://catatsuy.medium.com/logrotateの設定とファイルのアクセスモードについて-f9719352dada - Fluentd: https://www.fluentd.org/ - Fluentd(GitHub): https://github.com/fluent/fluentd - Fluentd in_tail(rotate_wait / enable_stat_watcher): https://docs.fluentd.org/input/tail - Fluentdのログローテート検知時のwatcher修正: https://github.com/fluent/fluentd/pull/1598 - Fluent Bit: https://fluentbit.io/ - logrotate: https://github.com/logrotate/logrotate - logrotateのファイル作成処理(O_EXCL): https://github.com/logrotate/logrotate/blob/1aba3764602a0a013ac3fb1ee57ed547dff03f88/logrotate.c#L600-L614 - logrotate(8): https://man7.org/linux/man-pages/man8/logrotate.8.html - Debianのnginxパッケージのlogrotate設定: https://sources.debian.org/src/nginx/1.26.3-3+deb13u7/debian/nginx-common.nginx.logrotate/ - nginxのシグナル制御(USR1): https://nginx.org/en/docs/control.html - open(2): https://man7.org/linux/man-pages/man2/open.2.html - write(2): https://man7.org/linux/man-pages/man2/write.2.html - pread(2): https://man7.org/linux/man-pages/man2/pread.2.html - inotify(7): https://man7.org/linux/man-pages/man7/inotify.7.html - Go os.SameFile: https://pkg.go.dev/os#SameFile - Go os.File.ReadAt: https://pkg.go.dev/os#File.ReadAt - Amazon CloudWatch Logs: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html ───────────── YouTube: https://youtu.be/vcakJioDvIs Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  2. 10月13日

    #23 curlで覗くDNSとHTTP/3の仕組み

    APIを叩くとき、レスポンスを確認するとき、エンジニアなら誰もが一度は使うcurl。でも `curl -V` の出力をじっくり読んだことはありますか? 今回は、HTTP/3やECHの挙動確認のためにcurlを自前でビルドしているcatatsuyが、普段何気なく使っているcurlの裏側を掘り下げます。 HTTP/3対応のcurlをビルドしようとすると、nghttp3やngtcp2、TLSライブラリなど、さまざまなOSSが登場します。当時の公式手順ではquictlsが使われていましたが、BoringSSL互換のAPIを持つLibreSSLでも動くはずだと考えて試したところ、問題なく利用できました。依存ライブラリを毎回ビルドするのは面倒なのでHomebrewのFormulaで自動化しました。その後、ECHの検証のためにOpenSSL 4系へ移行し、OpenSSL 4.0.0では動かなかったHTTP/3とECHの組み合わせが、4.0.2では動くようになっていた話も紹介します。 普段使いのcurlにも意外な落とし穴があります。以前はTLS 1.1を指定する挙動だった `--tlsv1.1` が、TLS 1.1以上を使う指定に変わり、TLS 1.2で通信できてしまった経験を紹介します。TLS 1.1に限定するには `--tls-max 1.1` も必要です。また、`--resolve` を使えばHostヘッダーやSNIを維持したまま、接続先IPアドレスだけを差し替えられます。さらに、IPv6で問題が起きていてもIPv4へのフォールバックによって通信できてしまうHappy Eyeballsや、非同期DNSライブラリのc-aresなど、一見単純なHTTPリクエストの裏側にある仕組みを見ていきます。 特に深掘りするのが、HTTPSレコードを使ったHTTP/3接続です。HTTP/2で通信した後、レスポンスに含まれるAlt-SvcヘッダーでHTTP/3の接続先を知る流れを紹介します。curlでも `--alt-svc` を使えば、その情報をファイルに保存して次回の接続に利用できます。一方、DNSのHTTPSレコードでHTTP/3対応を知ることができれば、最初からHTTP/3で接続できるはず。ところが実際には、たまにHTTP/3で接続できても、その後は何度試してもHTTP/2になってしまう。しばらく悩んだ末に分かった原因は、OSのDNSキャッシュでした。検証した環境では、A/AAAAレコードをgetaddrinfo経由でOSのDNSキャッシュから素早く取得できる一方、HTTPSレコードはc-aresで別途問い合わせていたため、HTTP/3の情報が届く前にHTTP/2で接続していたのです。DNSキャッシュを消すと再びHTTP/3で接続できるようになるという、キャッシュが効くことで新しいプロトコルが選ばれにくくなる現象でした。 最後は、curlの接続処理からWebアプリケーションの安定性の話へ。libcurlの接続タイムアウトはデフォルトで300秒、通信全体のタイムアウトはデフォルトで制限なし。PHPのcURL拡張やGuzzleを使っていても、外部APIの障害によってPHP-FPMのワーカープロセスが外部APIの応答待ちで埋まり、自分のサービスまで応答できなくなる可能性があります。`--connect-timeout` と `--max-time` の違いから、外部通信のタイムアウト設計まで話を広げます。 ## 関連リンク - curl: https://curl.se/ - curl HTTP/3ビルド手順(HTTP3 with curl): https://curl.se/docs/http3.html - curl HTTPSレコード対応ドキュメント: https://github.com/curl/curl/blob/master/docs/HTTPSRR.md - curl ECHドキュメント: https://github.com/curl/curl/blob/master/docs/ECH.md - curl man page(--resolve / --tls-max / --alt-svc / --connect-timeout / --max-time): https://curl.se/docs/manpage.html - curl Alt-Svc: https://curl.se/docs/alt-svc.html - libcurl: https://curl.se/libcurl/ - libcurl CURLOPT_CONNECTTIMEOUT: https://curl.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html - libcurl CURLOPT_TIMEOUT: https://curl.se/libcurl/c/CURLOPT_TIMEOUT.html - catatsuy/homebrew-tap(HTTP/3・ECH対応curlのFormula): https://github.com/catatsuy/homebrew-tap - Homebrew: https://brew.sh/ - nghttp2: https://nghttp2.org/ - nghttp3: https://github.com/ngtcp2/nghttp3 - ngtcp2: https://github.com/ngtcp2/ngtcp2 - c-ares: https://c-ares.org/ - OpenSSL: https://www.openssl.org/ - LibreSSL: https://www.libressl.org/ - BoringSSL: https://boringssl.googlesource.com/boringssl/ - quictls: https://github.com/quictls/quictls - RFC 8305 Happy Eyeballs Version 2: https://www.rfc-editor.org/info/rfc8305/ - Happy Eyeballs Version 3(Internet-Draft): https://datatracker.ietf.org/doc/draft-ietf-happy-happyeyeballs-v3/ - RFC 7838 HTTP Alternative Services(Alt-Svc): https://www.rfc-editor.org/info/rfc7838/ - RFC 9460 SVCB and HTTPS Resource Records: https://www.rfc-editor.org/info/rfc9460/ - RFC 9849 TLS Encrypted Client Hello(ECH): https://www.rfc-editor.org/info/rfc9849/ - RFC 8484 DNS Queries over HTTPS(DoH): https://www.rfc-editor.org/info/rfc8484/ - getaddrinfo(3): https://man7.org/linux/man-pages/man3/getaddrinfo.3.html - PHP cURL: https://www.php.net/manual/ja/book.curl.php - Guzzle Request Options(connect_timeout / timeout): https://docs.guzzlephp.org/en/stable/request-options.html - Go net/http: https://pkg.go.dev/net/http ───────────── YouTube: https://youtu.be/sYigIRmcQSg Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  3. 10月6日

    #22 HTTPSでも見えているドメイン名 — ECHとインターネットの未来

    ECH(Encrypted Client Hello)は、TLSのClientHelloをInnerとOuterに分け、実際のSNIなどを含むClientHelloInnerを暗号化する仕組みです。ただ、いざ自分のサーバーで有効にしようとすると、思っていたよりずっと奥が深い世界が待っていました。 前半では、なぜHTTPSでもドメイン名が見えていたのかをSNIから振り返り、ESNIがなぜうまくいかなかったのか、ClientHelloInner/Outer、GREASE ECHといった現在のECHの仕組みまで整理します。暗号化すれば検閲できなくなるわけではなく、中国やロシアでは残された情報を使ったブロックも実際に行われています。 後半はいよいよ運用編です。DNSのHTTPSリソースレコードでECHConfigListを配る仕組み、ECH keyを定期的にローテーションするとDNS cacheとの間で世代がずれる問>題を扱います。複数世代の鍵から復号候補を絞る1 byteのconfig_id、古いECHConfigを持ったclientへ最新のECHConfigListを返せるretry_configs、さらにnginxのssl_ech_fileでは最初に指定した鍵だけがretry用になるという暗黙的な挙動まで掘り下げます。 OpenSSLでECH keyを生成し、nginxで実際に設定すると何が必要なのか。DNSが広告するECHConfigと各Edgeに配置されたprivate keyをどう同期させるのか。CloudflareのようにDNSとTLS Edgeの両方を持つ事業者では、この複雑な仕組みをどう自動化しているのかも考えます。 最後は、サブドメインでテナントを分けるサービスではECHが何を隠せるのか、企業ネットワークのDNSやSNI監視とはどうぶつかるのか、そしてプライバシーを高めよ>うとすると、なぜ大規模なDNS・CDN事業者が有利になるのかまで話が広がります。 ECHの仕様を追っていくと、TLSだけではなく、DNS、CDN、検閲、そしてこれからのインターネットの構造まで見えてきます。インフラやCDN、TLSの運用に関わる人はぜひ本編で。 ## 関連リンク - RFC 9849 TLS Encrypted Client Hello(ECH): https://www.rfc-editor.org/info/rfc9849/ - RFC 9848 Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings: https://www.rfc-editor.org/info/rfc9848/ - RFC 6066 TLS Extensions(SNI): https://www.rfc-editor.org/info/rfc6066/ - RFC 9460 SVCB and HTTPS Resource Records: https://www.rfc-editor.org/info/rfc9460/ - RFC 8484 DNS Queries over HTTPS(DoH): https://www.rfc-editor.org/info/rfc8484/ - RFC 7858 DNS over TLS(DoT): https://www.rfc-editor.org/info/rfc7858/ - nginx ngx_http_ssl_module(ssl_ech_file): https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ech_file - OpenSSL openssl ech: https://docs.openssl.org/4.0/man1/openssl-ech/ - Cloudflare ECH Protocol: https://developers.cloudflare.com/ssl/edge-certificates/ech/ - GFW Report — ESNI Blocking: https://gfw.report/blog/gfw_esni_blocking/en ───────────── YouTube: https://youtu.be/gMfsXOksIPc Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  4. 9月29日

    #21 スマートフォンPush通知の配信基盤 — APNs/FCMとGaurun

    アプリを開いていないのに、スマートフォンに通知が届く。普段は当たり前に使っているこの仕組みは、裏側ではどう動いているのでしょうか。今回はメルカリが公開し、すでにGitHub上でアーカイブされたGo製のプッシュ通知サーバー「Gaurun」を入口に、元メンテナのcatatsuyがスマートフォンのプッシュ通知の仕組みを掘り下げます。 話はまず、iPhoneやAndroidにプッシュ通知が届く仕組みから。端末がAppleやGoogleのサーバーと張り続けているコネクションの話や、APNsが5223番、FCMが5228番というHTTPSとは別のポートを使っている話をhentekoが素朴に掘り下げます。そこからAPNsへ。HTTP/2しか話せずHTTP/1.1にフォールバックしない、コネクションを維持しながら大量の通知を送る必要がある、100万人に送るなら基本的には100万の配送先を扱う必要がある、といった独特の事情から、PHPのWebアプリケーションから直接大量のプッシュ通知を送るのが厳しく、Gaurunのような専用サーバーが必要だった背景が見えてきます。 さらに話はGoのHTTP/2実装まで降りていきます。APNsの証明書認証のためにTLSClientConfigを設定するとHTTP/2が自動で有効にならず、golang.org/x/net/http2を明示的に使う必要があった時代がありました。しかしGo本体にもHTTP/2の実装がbundleされているため、異なるバージョンのHTTP/2実装が同居し、実際の障害につながります。最終的にはGo 1.13で追加されたForceAttemptHTTP2によって、Gaurunからgolang.org/x/net/http2への直接依存を外せるようになりました。Appleの証明書更新とJWTを使ったトークンベース認証など、「プッシュ通知を送る」裏側にある実装と運用の面倒さも語られます。 後半は「今から作るなら」の話。現在はFCMからAPNsへ通知を送ることもでき、Topicを使えば大量のfan-outまでGoogle側に任せられます。Gaurunが自前で担っていた仕事のかなりの部分を、今ではFCMがManaged Serviceとして引き受けています。 実はcatatsuy自身も、GaurunをFCM HTTP v1 APIに対応させるPull Requestを出していました。しかし当時はLegacy APIがまだ使えており、急いで移行する理由が薄かったためclose。その後Legacy APIは終了し、Gaurunもアーカイブされました。外部サービスのAPIの変化によって、OSSの役割がどう変わっていくのかという話にもつながります。 さらに、既存のAPNs tokenをFCM側へ移す仕組み、registration tokenからFIDへの移行、中国のグレートファイアウォールといった少し厄介なケースまで掘り下げます。 プッシュ通知を実装したことがある人はもちろん、「そもそもスマートフォンの通知ってどうやって届いているの?」という人にも聞いてほしい回です。 ## 関連リンク - Gaurun (mercari/gaurun): https://github.com/mercari/gaurun - gaurunとGoのHTTP/2事情について: https://engineering.mercari.com/blog/entry/2019-12-13-110000/ - Gaurun FCM HTTP v1 API 対応 PR #109: https://github.com/mercari/gaurun/pull/109 - Gaurun ForceAttemptHTTP2 対応 PR #130: https://github.com/mercari/gaurun/pull/130 - Gaurun APNs トークンベース認証対応 PR #138: https://github.com/mercari/gaurun/pull/138 - Apple Push Notification service (APNs) - Sending notification requests to APNs: https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns - APNs - Establishing a token-based connection: https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns - APNs - Establishing a certificate-based connection: https://developer.apple.com/documentation/usernotifications/establishing-a-certificate-based-connection-to-apns - Firebase Cloud Messaging (FCM): https://firebase.google.com/docs/cloud-messaging - FCM HTTP v1 API リファレンス: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages - FCM トピックメッセージング: https://firebase.google.com/docs/cloud-messaging/topic-messaging - Firebase Admin SDK: https://firebase.google.com/docs/admin/setup - Instance ID API(APNs トークンの FCM トークンへのインポート): https://developers.google.com/instance-id/reference/server - golang.org/x/net/http2: https://pkg.go.dev/golang.org/x/net/http2 - Go net/http Transport(ForceAttemptHTTP2): https://pkg.go.dev/net/http#Transport - Go: https://go.dev/ - nginx: https://nginx.org/ ───────────── YouTube: https://youtu.be/l5N_fS0527g Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  5. 9月15日

    #20 Honoはなぜ速い?ルーター8個とファストパスの裏側 | yusukebe

    Hono を使っていると「速いフレームワーク」だとなんとなく知っている人は多いはず。でもその速さは、どこから生まれているのでしょうか。今回は Hono の作者 yusukebe さんをゲストに迎え、henteko と catatsuy がベンチマークの裏側を根掘り葉掘り聞いていきます。 Hono には過去のものも含めると 8 個ものルーターが存在し、その筆頭が usualoma さんの 2 回目のプルリクで入った RegExpRouter だったという話から、コアだけを徹底的に小さくしてアダプターやミドルウェアで機能を足すレイヤー設計、Express との Hello World 比較、ベンチマークを「マーケティング」として捉える視点まで。さらに Headers オブジェクトの生成コストを避ける「ファストパス」の考え方、Response.json を採用したのに戻すことになった理由、Bun・Node.js・Deno でベンチ結果がまるで違う現実、bombardier と Elysia 作者のベンチマークを指標にしている理由など、パフォーマンスにこだわる人ほど唸る話が続きます。 聞きどころは、Cloudflare Workers 向けに作ったのに、なぜベンチマークの基準が Bun になったのかという意外な経緯。フレームワークの速さがどう作られるかを知りたいエンジニアにおすすめの回です。 ## 関連リンク - Hono: https://hono.dev/ - Hono(GitHub): https://github.com/honojs/hono - Hono ルーターの解説: https://hono.dev/docs/concepts/routers - Hono ベンチマーク: https://hono.dev/docs/concepts/benchmarks - Hono テストガイド(app.request): https://hono.dev/docs/guides/testing - Hono CLI: https://github.com/honojs/cli - ax(yusukebe 作の AI 時代の curl): https://github.com/yusukebe/ax - usualoma(GitHub): https://github.com/usualoma - Cloudflare Workers: https://developers.cloudflare.com/workers/ - workerd: https://github.com/cloudflare/workerd - Bun: https://bun.sh/ - Deno: https://deno.com/ - JSR: https://jsr.io/ - Hono on JSR: https://jsr.io/@hono/hono - Node.js: https://nodejs.org/ - Fastly Compute: https://www.fastly.com/products/compute - Express: https://expressjs.com/ - Koa: https://koajs.com/ - koa-compose: https://github.com/koajs/compose - Elysia: https://elysiajs.com/ - Bun HTTP Framework Benchmark(Elysia 作者による): https://github.com/SaltyAom/bun-http-framework-benchmark - bombardier: https://github.com/codesenberg/bombardier - autocannon: https://github.com/mcollina/autocannon ───────────── YouTube: https://youtu.be/wsxqCjicT4Q Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  6. 9月8日

    #19 lsが返ってこない!libcの壁をgetdents64で突破した自作lls

    lsは万能だと思っていませんか?実は数千万ファイルが入ったディレクトリでは、lsもrsyncも歯が立たなくなります。今回はcatatsuyがその壁を突破するために作ったGo製CLI「lls」を紹介。かつてオンプレのファイルサーバーに眠っていた3100万ファイルのリストを出し切り、AWSへの移行を可能にした自作ツールの中身を、hentekoが「なぜlsを再実装したのか」から順番に解きほぐしていきます。 前半はllsに近づくための遠回り。システムコールとは何か、なぜCはlibcを介して呼ぶのか、glibcとmusl libcの違い、Goがlibcのレイヤーごと再実装している話、Goのブートストラップ問題(1.4はCで書かれた最後のGo)、そしてCの配列とGoの配列とスライスの違いまで、システムプログラミングの土台を丁寧に積み上げます。後半でようやく本題。libcのreaddirはgetdents64を小さなバッファで何度も呼ぶため終わらないこと、llsはgetdents64を直接呼び出して5MBのバッファで読み切ること、inode番号0のエントリや「.」「..」の扱い、Cの終端文字をGoの文字列に変換する処理など、実装の勘所を具体的に語ります。さらにCとGoのエラー処理の違い(errnoと多値返却)、getdents64がLinux専用ゆえの開発の不便さも。 「readdirにバッファサイズを渡せればこんなことしなくて済んだのに」というcatatsuyの嘆きと、Hacker Newsに初投稿した顛末も聞きどころ。低レイヤーは自分に関係ないと思っているWebエンジニアにこそ聞いてほしい回です。 ## 関連リンク - lls(catatsuy): https://github.com/catatsuy/lls - ファイルが多すぎてlsが打てなくなったディレクトリでファイル名のリストを出すllsを作りました(Zenn): https://zenn.dev/catatsuy/articles/e5f3bc7944f9fe - llsとcachectlから学ぶ、Goでシステムプログラミングをする方法(Zenn): https://zenn.dev/catatsuy/articles/e15714f8e253d8 - 旧ストレージ廃止大作戦−2900万超のファイルリストを取得する(PR TIMES 開発者ブログ): https://developers.prtimes.com/2021/09/15/decommissioning_old_storage_list_a_dir_29million/ - You can list a directory containing 8 million files! But not with ls: http://be-n.com/spw/you-can-list-a-million-files-in-a-directory-but-not-with-ls.html - Hacker News(上記記事のスレッド): https://news.ycombinator.com/item?id=28191639 - Show HN: lls(catatsuyの投稿): https://news.ycombinator.com/item?id=28344386 - getdents(2) man page: https://man7.org/linux/man-pages/man2/getdents.2.html - readdir(3) man page: https://man7.org/linux/man-pages/man3/readdir.3.html - open(2) man page: https://man7.org/linux/man-pages/man2/open.2.html - Go syscall パッケージ: https://pkg.go.dev/syscall - golang.org/x/sys/unix: https://pkg.go.dev/golang.org/x/sys/unix - Go のソースからのビルド(ブートストラップ): https://go.dev/doc/install/source - Go Slices: usage and internals: https://go.dev/blog/slices-intro - GNU C Library (glibc): https://www.gnu.org/software/libc/ - musl libc: https://musl.libc.org/ - Alpine Linux: https://alpinelinux.org/ ───────────── YouTube: https://youtu.be/WWZdM-it9t4 Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  7. 9月1日

    #18 AIがなければ成立しない?週1技術ポッドキャストの作り方

    毎週1本、50分超えの技術ポッドキャストを趣味で出し続ける——それを可能にしているものは何なのか。 今回はいつものOSS紹介ではなく、「八百万のOSS」自体を題材に、17回続けてきた制作の裏側をhentekoとcatatsuyが分析する特別回です。テーマはChatGPTと壁打ちしながらアジェンダを生成し、GitHubのURLを渡して調査。さらにCodexにはソースコードを渡して深掘りしています。 収録は自作ツールで各自ローカル録音、編集はAIサービスで無音カットとレベリングをして約1時間、予告編動画も約20分で完成。さらにXの告知投稿は、月5,000円のVPS上のcronからCloudflare Workersへ移行して運用コストをゼロにしました。「AIが出る前だったら考えられなかった番組」と2人が言い切る理由がよくわかる構成です。10年前に同じ番組をやろうとしたらどうなっていたか、という思考実験も面白いポイント。 一方で、「ここだけは絶対にAIに任せない」と2人が口を揃える部分も語られます。AI時代に人間がジャッジすべきものは何か、その答えは本編で。 AIを活用した個人プロジェクトの続け方に興味がある人、これからポッドキャストを始めてみたい人に特におすすめの回です。 ## 関連リンク - OpenAI Codex(公式ドキュメント): https://developers.openai.com/codex/ - Claude Code: https://claude.com/product/claude-code - Cloudflare Workers: https://workers.cloudflare.com/ - fukabori.fm: https://fukabori.fm/ - Go Conference: https://gocon.jp/ - YAPC::Japan: https://yapcjapan.org/ ───────────── YouTube: https://youtu.be/A3e_qP_Vlko Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

  8. 8月25日

    #17 PHPを書いていたはずが、ずっとCを読んでいた

    ドキュメントを読んでも納得できないとき、あなたはどこまで潜りますか? 今回はリスナーのポヨヨンさんから届いた「PHP が C 言語のラッパーであるという話を詳しく知りたい」というお便りに、catatsuy が自身の経験を総動員して答えるお便り回です。 `fopen()`のモード文字がPHPのstream実装で`open()`へ渡すフラグに変換され、OSへ処理が委ねられる仕組みをCのソースコードで確かめるところから始まります。さらに、Webアプリケーションの根幹なのにCで実装されていて読み解くのが難しいPHPのセッションやRedis拡張にも触れながら、「マルチプロセスではメモリを共有できないはずなのに」を飛び越えてくるAPCuと共有メモリセグメントの正体へ。ISUCON本のわずか数行を書くために、APCuのC実装を数時間かけて読んだ経験も振り返ります。 後半では、PHP 5.6から7への移行期にmemcache拡張からmemcached拡張へ乗り換えたところ、同じmemcachedサーバーに保存した値を正しく読めなくなった実運用トラブルを紹介します。memcachedのflagsはサーバーが解釈しないクライアント向けの領域であり、二つの拡張がそれぞれ異なる型情報や圧縮情報を記録していました。どちらも仕様に沿って実装されているのに、ライブラリを交換すると互換性問題が表面化する。その原因を突き止めるため、またCのコードへ潜っていきます。 最後は、AIを使ったコードリーディングと、普段使うライブラリの実装まで同じ言語のまま降りやすいGoとの違いにも話が広がります。 言語の内部実装に興味がある人にぜひ聞いてほしい回です。 ## 関連リンク - PHP: https://www.php.net/ - PHPの通常ファイル用stream実装(plain_wrapper.c): https://github.com/php/php-src/blob/271f689482c8efdaa8b2b5ac11e8172c25335bdd/main/streams/plain_wrapper.c - PHPのセッション実装(ext/session): https://github.com/php/php-src/tree/271f689482c8efdaa8b2b5ac11e8172c25335bdd/ext/session - APCu: https://pecl.php.net/package/APCu - APCu(GitHubリポジトリ): https://github.com/krakjoe/apcu - memcached: https://memcached.org/ - memcached protocol: https://github.com/memcached/memcached/blob/master/doc/protocol.txt - PECL memcache: https://pecl.php.net/package/memcache - php-memcached(PHP の memcached 拡張): https://github.com/php-memcached-dev/php-memcached - phpredis(PHPのRedis拡張): https://github.com/phpredis/phpredis - Redis: https://redis.io/ - gomemcache(bradfitz 作の Go 用 memcached クライアント): https://github.com/bradfitz/gomemcache - gorilla/sessions(Go のセッションライブラリ): https://github.com/gorilla/sessions - Go: https://go.dev/ - 達人が教えるWebパフォーマンスチューニング(ISUCON本): https://gihyo.jp/book/2022/978-4-297-12846-3 ───────────── YouTube: https://youtu.be/3BVO99h3Iqo Web: https://yaoyorozu-oss.henteko07.com/ X: https://x.com/yaoyorozu_oss

評価とレビュー

4
5段階評価中
4件の評価

番組について

毎回1つまたは複数のOSSを取り上げて、それについてエンジニアであるcatatsuyとへんてこで技術的なところも深掘りながら話をしていく番組です。 https://yaoyorozu-oss.henteko07.com/

その他のおすすめ