Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cloudflare Workers から PostgreSQL に接続可能になったので試してみた

hmatsu47
August 07, 2023

Cloudflare Workers から PostgreSQL に接続可能になったので試してみた

第 43 回 PostgreSQL アンカンファレンス@オンライン 2023/8/7

hmatsu47

August 07, 2023
Tweet

More Decks by hmatsu47

Other Decks in Technology

Transcript

  1. Cloudflare Workers から PostgreSQL に接続可能になったので 試してみた 第 43 回 PostgreSQL

    アンカンファレンス@オンライン  2023/8/7 まつひさ(hmatsu47)
  2. 自己紹介 松久裕保(@hmatsu47) • https://qiita.com/hmatsu47 • 現在のステータス: ◦ 名古屋で Web インフラのお守り係をしています

    ◦ 現在は自社サービスのセキュリティ強化中 ◦ ついでに MySQL HeatWave をのんびり検証中 ◦ #pgunconf ゆるふわ勢 2
  3. 本日のネタ • Connect to databases(Cloudflare Docs) https://developers.cloudflare.com/workers/databases/connecting-to-databases/ • Connect to

    PostgreSQL (beta)(Cloudflare Docs) https://developers.cloudflare.com/workers/databases/connect-to-postgres/ ※まだベータリリースなので使い方が予告なく変わる可能性があります 4
  4. Cloudflare Workers とは? • Cloudflare の一般的なイメージ ◦ CDN • Cloudflare

    自身が表現する事業のコアドメイン ◦ ウェブサイトのセキュリティーとパフォーマンス改善 • Cloudflare Workers ◦ エッジロケーションのサーバーレス環境 ◦ ユーザーに近い場所でサーバーサイド JS を実行(SSR など) 5
  5. Cloudflare Workers とは? • Cloudflare の一般的なイメージ ◦ CDN • Cloudflare

    自身が表現する事業のコアドメイン ◦ ウェブサイトのセキュリティーとパフォーマンス改善 • Cloudflare Workers ◦ エッジロケーションのサーバーレス環境 ◦ ユーザーに近い場所でサーバーサイド JS を実行(SSR など) 6
  6. Cloudflare Workers に connect()API が実装された • 何ができる? ◦ Workers から直接

    TCP ベースの接続が可能 ▪ 従来は HTTP(S) ベースか Cloudflare 内のサービスの接続のみ可能 • Cloudflare 外のデータベースへの接続が可能に ◦ PostgreSQL(TCP:5432)の外部データベース接続をサポート ▪ node-postgres(pg)を使用 ▪ ポート番号自体は変更可能 8
  7. やってみた • 前掲「Connect to PostgreSQL (beta)」のサンプル ◦ RNAcentral の「Public Postgres

    database」に接続 RNAcentral: The non-coding RNA sequence database https://rnacentral.org/help/public-database 9
  8. 0. 事前準備 • 詳細は省略します ◦ Cloudflare にサインアップ ◦ Node.js 16.13.0

    以降と npm・Wrangler をインストール ◦ Cloudflare dashboard で Worker を作成 ◦ Worker project を TypeScript で作成 ◦ node-postgres(pg)8.11.0 以降をインストール ▪ npm・yarn などで pg と @types/pg をインストール 10
  9. 1. DB 接続用の環境変数をセット • 秘匿する情報は secret にセット ◦ 例) •

    それ以外は wrangler.toml の [vars] に記述 ◦ 例) 11 [vars] DB_USERNAME = "postgres" # Set your password by creating a Secret so it is not stored as plain text DB_HOST = "ep-aged-sound-175961.us-east-2.aws.neon.tech" DB_PORT = "5432" DB_NAME = "neondb" wrangler secret put DB_PASSWORD
  10. 1. DB 接続用の環境変数をセット • 今回は公開情報なので wrangler.toml に DB_URL を記述 ※今回のサンプルはこちらの

    GitHub リポジトリにあります https://github.com/hmatsu47/cloudflare-workers-pg-connect 12 name = "pg-test" main = "src/index.ts" compatibility_date = "2023-08-01" # Ensure you enable Node.js compatibility to your project node_compat = true [vars] DB_URL = "postgres://reader:[email protected]:5432/pfmegrnargs"
  11. 2. コードを記述 13 import { Client } from 'pg'; export

    interface Env { DB_URL: string; } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { const url = new URL(request.url); if (url.pathname === '/favicon.ico') return new Response(null, { status: 404 }); const client = new Client(env.DB_URL); await client.connect(); // Query the RNA database! const result = await client.query({ text: 'SELECT * FROM rnc_database LIMIT 10', }); console.log(JSON.stringify(result.rows)); const resp = Response.json(result.rows); // Clean up the client, ensuring we don't kill the worker before that is completed. ctx.waitUntil(client.end()); return resp; }, };
  12. 2. コードを記述 • 個別のパラメーターを指定する場合 ◦ 例) 14 // 環境変数取得用interface部分 export

    interface Env { DB_USERNAME: string; DB_PASSWORD: string; DB_HOST: string; DB_PORT: number; DB_NAME: string; } // 接続パラメーター指定部分 const client = new Client({ user: env.DB_USERNAME, password: env.DB_PASSWORD, host: env.DB_HOST, port: env.DB_PORT, database: env.DB_NAME }) // TLS接続はこちらを参照 // https://developers.cloudflare.com/workers/databases/connect-to-postgres/#ssl-modes
  13. 3. Cloudflare Workers にデプロイ 15 npx wrangler deploy ⛅ wrangler

    3.4.0 ------------------ ▲ [WARNING] Enabling Node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details. Your worker has access to the following bindings: - Vars: - DB_URL: "postgres://reader:NWDMCE5xdipIjRrp@hh..." Total Upload: 352.86 KiB / gzip: 70.51 KiB Uploaded pg-test (1.40 sec) Published pg-test (0.40 sec) https://pg-test.【アカウント名】.workers.dev ←デプロイ先のURL Current Deployment ID: ********-****-****-****-************
  14. 4. 動作確認 16 curl 【デプロイ先のURL】 | jq % Total %

    Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3116 100 3116 0 0 766 0 0:00:04 0:00:04 --:--:-- 780 [ { "id": "5", "timestamp": "2017-05-17T00:00:00.000Z", "userstamp": "RNACEN", "descr": "VEGA", "current_release": 98, "full_descr": "VEGA", "alive": "N", "for_release": null, "display_name": "VEGA", "project_id": "PRJEB4568", "avg_length": null, "min_length": null, "max_length": null, "num_sequences": "0", "num_organisms": "0" }, (後略)
  15. 注意事項 • Cloudflare Workers には実行時間制限がある ◦ 無料プラン(リクエストあたり)CPU 時間:10 ミリ秒 ◦

    有料プラン(同上)実時間:30 秒 ▪ CPU 時間≠実時間(実際の実行時間) ▪ CPU 時間に DB からのレスポンス待ち 時間は含まない模様 https://www.cloudflare.com/ja-jp/plans/developer-platform/ 18
  16. 注意事項 • 処理が遅いとエッジロケーションで実行する意味がない ◦ おそらく DB から取得したデータをキャッシュすることになる? ▪ KV や

    Durable Objects に入れる? ▪ ものによっては D1(エッジロケーションの分散 SQLite)に入れる? https://www.publickey1.jp/blog/23/cloudflaresqlitecloudflare_d110.html • DB のアクセス許可範囲を正しく設定する ◦ DB をパブリック IP アドレスで公開する必要があるので 19
  17. まとめ • Cloudflare Workers:エッジロケーション JS 実行環境 • Cloudflare Workers が

    connect()API を実装 • PostgreSQL への接続がサポートされたのでやってみた • Workers には実行時間制限がある点に注意 • データ取得後のキャッシュ戦略が重要になりそう • DB のセキュリティ設定に気を付けるべし 20