কম্পিউটার

ক্লাউডফ্লেয়ার ওয়ার্কার এবং সার্ভারলেস রেডিস দিয়ে আপনার ওয়েব সাইটের জন্য আপনার নিজস্ব ওয়েটিং রুম তৈরি করুন

এই ব্লগ পোস্টে, আমরা আপনার ওয়েবসাইটের জন্য একটি ওয়েটিং রুম পৃষ্ঠা বাস্তবায়ন করব।

কেন?

আপনার ওয়েবসাইটে ভিজিটরের উচ্চ সংখ্যা সাধারণত একটি ভাল জিনিস কিন্তু সবসময় নয়। আকস্মিক উচ্চ ট্র্যাফিক সহজেই আপনার অ্যাপ্লিকেশনগুলিকে আচ্ছন্ন করতে পারে যা আপনার পরিষেবাগুলিকে সম্পূর্ণভাবে ব্যাহত করতে পারে। ওয়েটিং রুম হল একটি সমাধান যা আপনাকে ট্র্যাফিক নিয়ন্ত্রণ করতে এবং ট্র্যাফিক বৃদ্ধির সময় আপনার সংস্থানগুলিকে রক্ষা করতে সহায়তা করে। ক্লাউডফ্লেয়ার ওয়েটিং রুম একটি ভাল সমাধান কিন্তু এটি শুধুমাত্র ব্যবসা এবং এন্টারপ্রাইজ অ্যাকাউন্টের জন্য উপলব্ধ। চিন্তা করবেন না, এই ব্লগে আমরা ক্লাউডফ্লেয়ার ওয়ার্কারস এবং আপস্ট্যাশ রেডিস ব্যবহার করে যেকোন ধরনের ওয়েব সাইটের জন্য একটি ওয়েটিং রুম তৈরি করব৷

কিভাবে?

ওয়েটিং রুম নিয়ন্ত্রণ করার জন্য দুটি প্যারামিটার আছে।

  • সর্বোচ্চ সেশনের সময়কাল :একজন দর্শক কতক্ষণ ওয়েব সাইটে নিষ্ক্রিয় থাকতে পারেন?
  • সর্বোচ্চ ওয়েবসাইট ক্ষমতা :ওয়েবসাইটটি একই সময়ে কতজন দর্শকদের অনুমতি দিতে পারে?

যখন একজন ভিজিটর আমাদের ওয়েবসাইটে প্রবেশ করে, তখন আমরা একটি অনন্য কী তৈরি করব (যেমন একটি সেশন কী) এবং এটি রেডিসে রাখব। আমরা এই কীটি রেডিস-এ একটি মেয়াদ শেষ হওয়ার সাথে রাখব যা হল সর্বোচ্চ সেশনের সময়কাল . ওয়েবসাইটটিতে ভিজিটর আসার আগে, আমরা রেডিসের ডিবিসাইজ পরীক্ষা করব। সাইজ যদি **ওয়েবসাইটের সর্বোচ্চ ক্ষমতার চেয়ে বেশি হয়, তাহলে আমরা ভিজিটরকে ওয়েটিং রুমে ফরোয়ার্ড করব। ওয়েটিং রুম একটি স্ট্যাটিক এইচটিএমএল কিন্তু প্রতি 30 সেকেন্ডে রিফ্রেশ হয়। অর্থাৎ, প্রতি 30 সেকেন্ডে একবার, ভিজিটরকে ওয়েবসাইটটিতে প্রবেশের অনুমতি দেওয়া যেতে পারে যদি উপলব্ধতা থাকে।

আমরা যে অনন্য কী তৈরি করেছি তাও একটি কুকি হিসাবে ভিজিটরের অনুরোধে লেখা হয়। তাই একই ভিজিটরের অনুরোধে একই কী থাকবে। ধারণক্ষমতা পূর্ণ হলে ওয়েবসাইটের ভিতরে ভিজিটর ইতিমধ্যেই একটি সেশন আছে কিনা তা পরীক্ষা করার জন্য এটি প্রয়োজন। তাই রেডিস কীস্পেসে আপনার কী বিদ্যমান থাকা পর্যন্ত ধারণক্ষমতা পূর্ণ থাকলেও একজন ভিজিটর হিসেবে আপনাকে ওয়েবসাইটে প্রবেশ করার অনুমতি দেওয়া হয়। আপনি যদি সর্বোচ্চ সেশনের সময়কালের চেয়ে বেশি সময় নিষ্ক্রিয় থাকেন, তাহলে আপনার কী Redis থেকে মুছে ফেলা হবে। এবং আপনি একটি অনুরোধ পাঠানোর সময় ক্ষমতা পূর্ণ হলে আপনাকে ওয়েটিং রুমে ফরোয়ার্ড করা হবে।

আমরা ক্লাউডফ্লেয়ার ওয়ার্কার্সে এই যুক্তিটি বাস্তবায়ন করব। আমরা Upstash একটি Redis স্টোর হিসাবে ব্যবহার করব। এখন এই প্রযুক্তিগত সিদ্ধান্তের পটভূমি ব্যাখ্যা করা যাক।

কেন ক্লাউডফ্লেয়ার কর্মীরা?

ওয়েটিং রুম বাস্তবায়ন আপনার ওয়েবসাইটে সমস্ত অনুরোধ বাধা দেবে। তাই এর কর্মক্ষমতা ওভারহেড ন্যূনতম হওয়া উচিত। ক্লাউডফ্লেয়ার ওয়ার্কাররা ক্লাউডফ্লেয়ার এজ অবকাঠামো ব্যবহার করে, তাই এটি আপনাকে বিশ্বব্যাপী ন্যূনতম বিলম্ব দেয়। এছাড়াও AWS Lambda এর বিপরীতে, এতে কোল্ড স্টার্ট সমস্যা নেই। এটি একটি সার্ভারবিহীন প্রযুক্তি তাই স্কেলেবিলিটিও কোন সমস্যা নয়।

কেন Upstash Redis?

প্রতিটি নতুন দর্শককে অনুমতি দেওয়ার আগে আপনাকে ওয়েবসাইটের বর্তমান আকার পরীক্ষা করতে হবে। ক্লাউডফ্লেয়ার ওয়ার্কাররা স্টেটলেস তাই আপনাকে এই তথ্যটি বাহ্যিকভাবে রাখতে হবে। কম লেটেন্সি সহ রেডিস হল সেরা পছন্দ। কিন্তু Redis অফারগুলির জন্য TCP ভিত্তিক সংযোগ প্রয়োজন যা Cloudflare শ্রমিকদের দ্বারা সমর্থিত নয়। Upstash হল একমাত্র Redis অফার যা বিল্ট-ইন REST API সহ। এছাড়াও গ্লোবাল রেপ্লিকেশনের জন্য ধন্যবাদ এটি আপনাকে সারা বিশ্বে কম লেটেন্সি দেয়।

ধাপে ধাপে বাস্তবায়ন

আমরা নিচে ধাপে ধাপে প্রকল্পটি বাস্তবায়ন করব। আপনি যদি প্রজেক্টটি ক্লোন করতে চান এবং সরাসরি আপনার ওয়েব সাইটের জন্য ওয়েটিং রুম সেট আপ করতে চান, তাহলে আপনি সোর্স কোডের রিডমিতে ধাপগুলি অনুসরণ করতে পারেন৷

1 প্রকল্প সেটআপ

র্যাংলার ব্যবহার করে একটি প্রকল্প তৈরি করুন।


wrangler generate waiting-room

তারপর নির্ভরতা ইনস্টল করুন:


npm install cookie upstash@redis

2 wrangler.toml

আপডেট করুন

প্রকার আপডেট করুন:

type = "webpack"

আপনার Cloudflare অ্যাকাউন্ট আইডি সেট করুন। আপনার অ্যাকাউন্ট আইডি খুঁজতে এটি চেক করুন।

account_id = "REPLACE_HERE"

এই ভেরিয়েবল যোগ করুন:

[vars]
UPSTASH_REDIS_REST_TOKEN = "REPLACE_HERE"
UPSTASH_REDIS_REST_URL = "REPLACE_HERE"
TOTAL_ACTIVE_USERS = 10
SESSION_DURATION_SECONDS = 30

আপনাকে Upstash কনসোল থেকে একটি গ্লোবাল ডাটাবেস তৈরি করতে হবে। আপনাকে শুধু কনসোল থেকে REST টোকেন এবং URL কপি এবং পেস্ট করতে হবে। Redis ডাটাবেস প্রাথমিকভাবে খালি থাকা উচিত এবং শুধুমাত্র এই অ্যাপ্লিকেশন দ্বারা ব্যবহার করা উচিত।

আপনার নিজের প্রয়োজনীয়তার উপর নির্ভর করে আপনার TOTAL_ACTIVE_USERS এবং SESSION_DURATION_SECONDS সেট করা উচিত৷

3 index.js

Index.js হল Cloudflare Workers বাস্তবায়ন ফাইল। তাই আমরা এর ভিতরে সমস্ত যুক্তি রাখব। নিচের কোডটি কপি করে পেস্ট করুন:

import { parse } from "cookie";
import { Redis } from "@upstash/redis/cloudflare";

const redis = Redis.fromEnv();

addEventListener("fetch", (event) => {
  event.respondWith(
    handleRequest(event.request).catch(
      (err) => new Response(err.stack, { status: 500 })
    )
  );
});

const COOKIE_NAME_ID = "__waiting_room_id";
const COOKIE_NAME_TIME = "__waiting_room_last_update_time";

const init = {
  headers: {
    Authorization: "Bearer " + UPSTASH_REDIS_REST_TOKEN,
  },
};

async function handleRequest(request) {
  const { pathname } = new URL(request.url);
  if (!pathname.startsWith("/favicon")) {
    const cookie = parse(request.headers.get("Cookie") || "");
    let userId;

    if (cookie[COOKIE_NAME_ID] != null) {
      userId = cookie[COOKIE_NAME_ID];
    } else {
      userId = makeid(8);
    }

    const size = await redis.dbsize();
    console.log("current capacity:" + size);
    // there is enough capacity
    if (size < TOTAL_ACTIVE_USERS) {
      return getDefaultResponse(request, cookie, userId);
    } else {
      // site capacity is full
      const user = await redis.get(userId);
      if (user === "1") {
        // the user has already active session
        return getDefaultResponse(request, cookie, userId);
      } else {
        // capacity is full so the user is forwarded to waiting room
        return getWaitingRoomResponse(userId);
      }
    }
  } else {
    return fetch(request);
  }
}

async function getDefaultResponse(request, cookie, userId) {
  // uncomment below to test the function with a static html content
  // const newResponse = new Response(default_html)
  // newResponse.headers.append('content-type', 'text/html;charset=UTF-8')

  const response = await fetch(request);
  const newResponse = new Response(response.body, response);

  const now = Date.now();
  let lastUpdate = cookie[COOKIE_NAME_TIME];
  if (!lastUpdate) lastUpdate = 0;
  const diff = now - lastUpdate;
  const updateInterval = (SESSION_DURATION_SECONDS * 1000) / 2;
  if (diff > updateInterval) {
    await redis.setex(userId, SESSION_DURATION_SECONDS, 1);
    newResponse.headers.append(
      "Set-Cookie",
      `${COOKIE_NAME_TIME}=${now}; path=/`
    );
  }

  newResponse.headers.append(
    "Set-Cookie",
    `${COOKIE_NAME_ID}=${userId}; path=/`
  );
  return newResponse;
}

async function getWaitingRoomResponse(userId) {
  const newResponse = new Response(waiting_room_html);
  newResponse.headers.set("content-type", "text/html;charset=UTF-8");
  return newResponse;
}

function makeid(length) {
  let result = "";
  const characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

const waiting_room_html = `
<title>Waiting Room</title>
<meta http-equiv='refresh' content='30' />

<style>*{box-sizing:border-box;margin:0;padding:0}body{line-height:1.4;font-size:1rem;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif;padding:2rem;display:grid;place-items:center;min-height:100vh}.container{width:100%;max-width:800px}p{margin-top:.5rem}</style>

<div class='container'>
  <h1>
    <div>You are now in line.</div>
    <div>Thanks for your patience.</div>
  </h1>
  <p>We are experiencing a high volume of traffic. Please sit tight and we will let you in soon. </p>
  <p><b>This page will automatically refresh, please do not close your browser.</b></p>
</div>
`;

const default_html = `
<title>Waiting Room Demo</title>

<style>*{box-sizing:border-box;margin:0;padding:0}body{line-height:1.4;font-size:1rem;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif;padding:2rem;display:grid;place-items:center;min-height:100vh}.container{width:100%;max-width:800px}p{margin-top:.5rem}</style>

<div class="container">
  <h1>
    <div>Waiting Room Demo</div>
  </h1>
    <p>
              Visit this site from a different browser, you will be forwarded to the waiting room when the capacity is full.
    </p>
  <p>  Check <a href={"https://github.com/upstash/waiting-room"} style={{"color": "blue"}}>this project </a> to set up a waiting room for your website.</p>
</div>
`;

উপরের কোডে, আপনি waiting_room_html সম্পাদনা করতে পারেন পরিবর্তনশীল এটি ওয়েটিং রুম পৃষ্ঠার স্ট্যাটিক এইচটিএমএল।

handleRequest পদ্ধতি আপনার ওয়েবসাইটের উপলব্ধতার উপর নির্ভর করে getDefaultResponse বা getWaitingRoomResponse প্রদান করে।

4 স্থানীয়ভাবে চালান

স্থানীয়ভাবে ওয়েটিং রুম পরীক্ষা করার জন্য, ধারণক্ষমতা 1, সেশনের সময়কাল 30 সেকেন্ডে সেট করার অর্থ হতে পারে। তারপর চালান


wrangler dev

এখন Chrome এ https://127.0.0.1:8787/ খুলুন, আপনি দেখতে পাবেন:

ক্লাউডফ্লেয়ার ওয়ার্কার এবং সার্ভারলেস রেডিস দিয়ে আপনার ওয়েব সাইটের জন্য আপনার নিজস্ব ওয়েটিং রুম তৈরি করুন

এবং তারপর Safari (বা Chrome ছদ্মবেশী) তে একই url খুলুন, আপনি দেখতে পাবেন:

ক্লাউডফ্লেয়ার ওয়ার্কার এবং সার্ভারলেস রেডিস দিয়ে আপনার ওয়েব সাইটের জন্য আপনার নিজস্ব ওয়েটিং রুম তৈরি করুন

30 সেকেন্ডের বেশি অপেক্ষা করুন। আপনি দেখতে হবে ওয়েটিং রুমের পৃষ্ঠাটি রিফ্রেশ হবে এবং ওয়েবসাইটে প্রবেশ করবে।

আমাদের স্থানীয় একটি বাস্তব ওয়েবসাইটে ফরওয়ার্ড করে না তাই আমরা ক্লাউডফ্লেয়ারের 404 পৃষ্ঠা দেখতে পাই, এটা ঠিক আছে৷

5 প্রকাশ করুন

আপনার সিএফ ওয়ার্কার্স ফাংশন এর সাথে স্থাপন করুন:


wrangler publish

এটি আপনাকে একটি ইউআরএল দেবে:https://waiting-room.upsdev.workers.dev/

এখন আমাদের কর্মীকে আপনার ওয়েবসাইটে রুট করা যাক। প্রথমে আপনার ডোমেনের নেমসার্ভারগুলিকে ক্লাউডফ্লেয়ারের দিকে নির্দেশ করা উচিত। এটা যাচাই কর. তারপর, আপনাকে একটি রুট হিসাবে আপনার ডোমেন যোগ করতে হবে এবং CF ওয়ার্কার্স ড্যাশবোর্ডে আপনার ওয়ার্কার্স ফাংশন নির্বাচন করতে হবে৷

ক্লাউডফ্লেয়ার ওয়ার্কার এবং সার্ভারলেস রেডিস দিয়ে আপনার ওয়েব সাইটের জন্য আপনার নিজস্ব ওয়েটিং রুম তৈরি করুন

উপসংহার

ক্লাউডফ্লেয়ার ওয়ার্কার এবং আপস্ট্যাশ রেডিসকে ধন্যবাদ আমাদের অ্যাপ্লিকেশন কোড স্পর্শ না করেই আমরা সফলভাবে একটি ওয়েটিং রুম তৈরি করেছি। আমরা বিশ্বাস করি এটি কিভাবে শক্তিশালী এজ ফাংশন আপস্ট্যাশের সাথে একত্রিত হয় তার আরেকটি সূচক।

উন্নতি করার কিছু আছে:

  • প্রতীক্ষার আনুমানিক সময়:আমরা গড় অপেক্ষার সময় গণনা করতে এবং দেখাতে পারি।
  • ন্যায্য এবং অর্ডারকৃত সারি:বর্তমানে অপেক্ষমাণ দর্শকরা এলোমেলোভাবে সাইটে প্রবেশ করে যখন উপলব্ধতা থাকে। আমরা একটি সারি রাখতে পারি এবং দর্শকদের একটি ক্রমানুসারে যেতে দেওয়ার চেষ্টা করতে পারি।

উপরের উভয় উন্নতির জন্যই আরও বেশি অবস্থা রাখা এবং আরও দূরবর্তী কল করা প্রয়োজন। এজন্য আমরা সেগুলি এড়িয়ে যেতে পছন্দ করেছি। যদি আপনার ব্যবহারের ক্ষেত্রে কঠোরভাবে এগুলোর প্রয়োজন হয়, তাহলে আপনি ক্লাউডফ্লেয়ার দলের তাদের এন্টারপ্রাইজ সলিউশনের কাজ থেকে অনুপ্রাণিত হতে এই ব্লগটি পরীক্ষা করতে পারেন।

সোর্স কোড চেক করুন।

টুইটার বা ডিসকর্ডে আপনার চিন্তা আমাদের জানান।


  1. ফ্লটার, সার্ভারলেস ফ্রেমওয়ার্ক এবং আপস্ট্যাশ (REDIS) সহ ফুলস্ট্যাক সার্ভারলেস অ্যাপ - পার্ট 2

  2. ফ্লটার, সার্ভারলেস ফ্রেমওয়ার্ক এবং আপস্ট্যাশ (REDIS) সহ ফুলস্ট্যাক সার্ভারলেস অ্যাপ - পার্ট 1

  3. ক্লাউডফ্লেয়ার ওয়ার্কার এবং সার্ভারলেস রেডিস দিয়ে আপনার ওয়েব সাইটের জন্য আপনার নিজস্ব ওয়েটিং রুম তৈরি করুন

  4. ক্লাউডফ্লেয়ার কর্মীদের সাথে রেডিস @ এজ