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)

    View full-size slide

  2. 自己紹介
    松久裕保(@hmatsu47)
    ● https://qiita.com/hmatsu47
    ● 現在のステータス:
    ○ 名古屋で Web インフラのお守り係をしています
    ○ 現在は自社サービスのセキュリティ強化中
    ○ ついでに MySQL HeatWave をのんびり検証中
    ○ #pgunconf ゆるふわ勢
    2

    View full-size slide

  3. 本日のネタ
    ● Cloudflare Workers、TCP ソケットで作成可能な
    connect()API を発表
    https://www.infoq.com/jp/news/2023/07/cloudflare-workers-connect-api/
    3

    View full-size slide

  4. 本日のネタ
    ● 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  7. 余談:最近の CDN
    ● エッジロケーションのサーバーレス環境は当たり前に
    ○ AWS : Lambda@Edge・CloudFront Functions
    ○ Fastly : Compute@Edge
    ○ Akamai : EdgeWorkers
    7

    View full-size slide

  8. Cloudflare Workers に connect()API が実装された
    ● 何ができる?
    ○ Workers から直接 TCP ベースの接続が可能
    ■ 従来は HTTP(S) ベースか Cloudflare 内のサービスの接続のみ可能
    ● Cloudflare 外のデータベースへの接続が可能に
    ○ PostgreSQL(TCP:5432)の外部データベース接続をサポート
    ■ node-postgres(pg)を使用
    ■ ポート番号自体は変更可能
    8

    View full-size slide

  9. やってみた
    ● 前掲「Connect to PostgreSQL (beta)」のサンプル
    ○ RNAcentral の「Public Postgres database」に接続
    RNAcentral: The non-coding RNA sequence database
    https://rnacentral.org/help/public-database
    9

    View full-size slide

  10. 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

    View full-size slide

  11. 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

    View full-size slide

  12. 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"

    View full-size slide

  13. 2. コードを記述
    13
    import { Client } from 'pg';
    export interface Env {
    DB_URL: string;
    }
    export default {
    async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise {
    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;
    },
    };

    View full-size slide

  14. 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

    View full-size slide

  15. 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: ********-****-****-****-************

    View full-size slide

  16. 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"
    },
    (後略)

    View full-size slide

  17. デモ(時間があれば)
    ● SQL 文を書き換えて再デプロイしてみます
    17

    View full-size slide

  18. 注意事項
    ● Cloudflare Workers には実行時間制限がある
    ○ 無料プラン(リクエストあたり)CPU 時間:10 ミリ秒
    ○ 有料プラン(同上)実時間:30 秒
    ■ CPU 時間≠実時間(実際の実行時間)
    ■ CPU 時間に DB からのレスポンス待ち
    時間は含まない模様
    https://www.cloudflare.com/ja-jp/plans/developer-platform/
    18

    View full-size slide

  19. 注意事項
    ● 処理が遅いとエッジロケーションで実行する意味がない
    ○ おそらく DB から取得したデータをキャッシュすることになる?
    ■ KV や Durable Objects に入れる?
    ■ ものによっては D1(エッジロケーションの分散 SQLite)に入れる?
    https://www.publickey1.jp/blog/23/cloudflaresqlitecloudflare_d110.html
    ● DB のアクセス許可範囲を正しく設定する
    ○ DB をパブリック IP アドレスで公開する必要があるので
    19

    View full-size slide

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

    View full-size slide