tencent cloud

Feedback

EdgeOne Implementation of Session Persistence Based on Client IP Addresses

Last updated: 2024-08-26 17:47:47
    It will take you about 10 minutes to study this document. By studying this document, you can understand:
    1. Why is session persistence based on client IP addresses necessary?
    2. Use cases for session persistence based on client IP addresses.
    3. The specific steps for implementing session persistence based on client IP addresses with EdgeOne edge functions and rule engines.

    Background

    
    With the rapid development of the Internet, enterprises are constantly expanding their businesses and deepening user experience. A single origin server gradually fails to meet the needs of handling a large number of concurrent requests. To enhance the availability and scalability of services, enterprises are beginning to adopt load balancing technology to distribute user requests to multiple backend origin servers for processing. However, in the early stages of business development, due to the relatively small number of users and relatively simple session management, session persistence based on client IP addresses is usually not required. As the business further develops, especially in the following scenarios, the demand for session persistence based on client IP addresses becomes particularly urgent:
    User login status persistence: In applications requiring user login, such as e-commerce websites and online banking, a session is created on the origin server after the user logs in to record user login status, shopping cart information, order details, and other information. If the user is assigned to different backend origin servers during browsing, the user needs to log in again due to the loss of session information, severely affecting user experience.
    Businesses with high data consistency requirements: In businesses with strict data consistency requirements, such as financial transactions and online payments, distributing sessions to different origin servers may lead to data inconsistency or loss, causing significant losses for both users and enterprises.
    Through EdgeOne edge functions and rule engines, the above-mentioned issues can be resolved. It can achieve session continuity and data consistency by ensuring that requests from the same client IP address are always forwarded to the same backend origin server. Specifically, edge functions map the clients to different origin server groups based on the client's IP addresses using a hash algorithm. The rule engine obtains the origin-pull request header defined in the edge function, and based on the value of this header, it ensures that the same client always returns to the same origin server group. This not only enhances user experience but also ensures the accuracy of business data.

    Use Cases

    By identifying the client's IP address to ensure that requests from the same client are directed to the same origin server, this feature is applicable to the following business scenarios:
    Financial services: Applications like online banking and stock trading need to ensure that all requests from a user throughout the transaction are processed by the same origin server to maintain transaction security and consistency.
    E-commerce websites: After a user logs in, all requests from the user are routed to the same origin server to maintain shopping cart information, user preference settings, and login status.

    Scenario

    Assume that you are a technical lead of a global application service, and you have integrated your site domain name example.com into EdgeOne. You expect to route requests according to the hash value of the user's IP address to the corresponding origin server, ensuring that regardless of the user's location, the same user's requests are always routed to the same origin server. This helps optimize cache efficiency, simplify session management, implement load balancing, deliver personalized services, and ensure data processing's legal compliance.
    In this scenario, you are dealing with millions of different users, whose requests need to be evenly distributed to the Chinese mainland origin server group and Singapore origin server group. At the same time, you expect requests from the same IP address to be always routed to the same origin server to achieve a consistent user experience and efficient resource usage. In this example, IP addresses that need to be forwarded to the Chinese mainland origin server group will have an origin-pull request header X-Forwarded-For-Origin:originGroup1 added by the edge function, and IP addresses that need to be forwarded to the Singapore origin server group will have an origin-pull request header X-Forwarded-For-Origin:originGroup2 added by the edge function.

    Directions

    Step 1: Connecting to EdgeOne

    Refer to Quick Start to complete site connection and domain name connection.

    Step 2: Creating and Configuring the Edge Function

    1. Log in to the EdgeOne console, select the site to be configured from the Site List, and enter the site management submenu.
    2. In the left navigation bar, click Edge Functions > Function Management.
    3. On the Function Management page, click Create function.
    4. On the template selection page, select Create Hello World, and then click Next.
    5. On the function creation page, enter the function name, description, and code. Below is sample code for session persistence based on client IP addresses:
    // Based on client IP addresses, return the clients to different origin server groups, i.e., with the same IP address, the same client returns to the same origin server.
    const ORIGIN_GROUPS = ["originGroup1", "originGroup2"];
    
    // Define the number of virtual nodes. If there are many origin server groups (ORIGIN_GROUPS), it is recommended to reduce the number of virtual nodes.
    const VIRTUAL_NODES_PER_GROUP = 15;
    const ORIGIN_HEADER_NAME = 'X-Forwarded-For-Origin';
    let virtualNodesHashesCache = null;
    
    // Define global variables to track the function invocation count.
    addEventListener("fetch", (event) => {
    handleRequest(event.request);
    });
    
    async function handleRequest(request) {
    // Obtain the client IP address through the EO-Client-IP header.
    const ip = request.headers.get("EO-Client-IP") || "";
    // If there are no hash values for virtual nodes in the cache, generate the hash values.
    if (!virtualNodesHashesCache) {
    virtualNodesHashesCache = await generateVirtualNodesHashes();
    }
    const group = await findSourceGroupForIp(
    ip,
    virtualNodesHashesCache.hashes,
    virtualNodesHashesCache.mapping
    );
    console.log(`Group: ${group}`);
    request.headers.set(ORIGIN_HEADER_NAME, group)
    
    return;
    }
    // Generate virtual nodes' hash values.
    async function generateVirtualNodesHashes() {
    const virtualNodesHashes = {};
    for (let group in ORIGIN_GROUPS) {
    for (let i = 0; i < VIRTUAL_NODES_PER_GROUP; i++) {
    const virtualNodeIdentifier = `${group}-VN${i}`;
    const hash = await md5(virtualNodeIdentifier);
    if (!virtualNodesHashes[hash]) {
    virtualNodesHashes[hash] = group;
    }
    }
    }
    
    const hashes = Object.keys(virtualNodesHashes).sort();
    return { hashes, mapping: virtualNodesHashes }; // Return the sorted array of hash values and mapping relationship.
    }
    
    // Map the client IP address to the virtual node and find the corresponding origin server group.
    async function findSourceGroupForIp(ip, hashes, mapping) {
    // Use the MD5 function to calculate the hash value of the IP address.
    const ipHash = await md5(ip);
    let closestHash = hashes.find((hash) => hash > ipHash) || hashes[0];
    // Based on the found hash value of the virtual node, obtain the corresponding origin server group name from the virtual node hash table.
    const selectedGroupName = mapping[closestHash];
    const selectedGroupIPs = ORIGIN_GROUPS[selectedGroupName];
    // Print logs that display the client IP address, hash value, closest virtual node hash value, and selected origin server group name.
    console.log(
    `IP: ${ip}, Hash: ${ipHash}, Closest Hash: ${closestHash}, Selected Group: ${selectedGroupName}`
    );
    // Return the selected origin server group name.
    return selectedGroupIPs;
    }
    
    function bufferToHex(arr) {
    return Array.prototype.map
    .call(arr, (x) => (x >= 16 ? x.toString(16) : "0" + x.toString(16)))
    .join("");
    }
    
    async function md5(text) {
    const buffer = await crypto.subtle.digest("MD5", TextEncoder().encode(text));
    return bufferToHex(new Uint8Array(buffer));
    }

    Step 3: Configuring and Deploying Trigger Rules for the Edge Function

    1. After editing the function, click Create and deploy. Once the function is deployed, you can directly click Add triggering rule to configure the trigger rules for the function.
    
    2. In the function trigger rules, configure the trigger conditions for the function. Based on the current scenario, you can configure multiple trigger conditions using AND logic.
    Here, configure the request HOST as example.com.
    When the request URL meets the above conditions, the edge function in Step 2 will be triggered, implementing session persistence based on client IP addresses.
    
    3. Click OK to activate the trigger rules.

    Step 4: Configuring the Rule Engine

    1. Log in to the EdgeOne console, select the site to be configured from the Site List, and enter the site management submenu.
    2. In the left navigation bar, click Site Acceleration to enter the global configuration page for the site. Then, click the Rule Engine tab.
    3. On the Rule Engine page, click Create rule, and then select Add blank rule.
    4. On the rule editing page, select HOST as the matching type to match requests for a specific domain name.
    Here, configure the request HOST as example.com.
    5. On the rule editing page, enable Client IP Header by referring to Obtaining Client IP Address.
    Here, configure the header name as EO-Client-IP.
    6. On the rule editing page, click +IF, and based on the request header values in edge function code, configure different origin server groups.
    Here, configure that when the HTTP request header X-Forwarded-For-Origin equals originGroup1, the request will be forwarded to the origin server group in the Chinese mainland for processing; when the HTTP request header X-Forwarded-For-Origin equals originGroup2, the request will be forwarded to the origin server group in Singapore for processing.
    
    7. Click Save and publish to activate the rule engine.

    Step 5: Verifying the Deployment Effect

    After testing, this example demonstrated good load balancing capabilities, with the load balancing proportion fluctuating around 50%, and it effectively maintained user session consistency, proving that the deployment effect met expectations.
    
    
    Contact Us

    Contact our sales team or business advisors to help your business.

    Technical Support

    Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

    7x24 Phone Support