Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

Sessions ใน Traditional Load Balancing Environments

โดยทั่วไป เราใช้ In-memory Sessions (Data เก็บใน RAM) ใน Web Applications ทั้งหมด มันทำงานได้ดีใน Traditional Hosting Environments ส่วนใหญ่ ที่เรา Host Application ใน Dedicated VM หรือ Shared Hosting Plans

อย่างไรก็ตาม เมื่อ Traffic โต เราวางแผน Load Balancing โดยสร้าง Multiple Web Servers และควบคุม Traffic ด้วย Load Balancers ใน Scenario นี้ Session ไม่ทำงาน เพราะ Requests (ที่เกี่ยวกับ Single Session เดียว) จะ Served โดย Multiple Servers (Same Server Serving Requests ของ Single Session ก็เป็นไปได้ แต่ไม่แนะนำ) Solution คือ ไปเก็บ Sessions ใน SQL Server ที่ Accessible ข้าม Web Servers ทั้งหมดใน Load Balancing Environment

Sessions ใน Azure Auto-scale Environment

แทน Theoretical Discussion เรามา Practical Discussion โดยพัฒนา Program เล็กที่ใช้ Sessions และดู Sessions ทำงานใน Azure ยังไง

สร้าง Website (MVC Application ก็ได้) กับ Web Pages ต่อไป และ Deploy ตามบทความก่อนหน้าของผม

  • Azure App Service - Configure Existing Application From Visual Studio

Login.aspx

หน้านี้รับ Username และ Password กด "Login" สร้าง Session เก็บ Username ที่ Login และ Redirect ไป "Default.aspx"

โปรดสังเกต หน้านี้แสดง IP Address "10.202.116.91" ของ VM ที่ Host Website

Default.aspx

หน้านี้แสดง Messages ตามค่าใน Session

ถ้า Session มีค่า แสดง "Logged in user as admin. You are in 10.202.116.91" ตามภาพ

ถ้า Session ไม่มีค่า แสดง "Session is NULL. You are in 10.202.116.91" ตามภาพ

สังเกตว่า IP Address ของ Server ใน Login.aspx และ Default.aspx เหมือนกัน All Requests ถูก Redirect ไป Server เดียวกัน

และตามภาพ Session Maintained โดย Cookie ชื่อ "ASP.NET_SessionID" ควรคุ้นเคยกับส่วนใหญ่

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

สมมติ Traffic โต เราอยาก Scale เป็น 2 Instances เพิ่ม Instance Count เป็น 2

Note: โปรดสังเกต ไม่สามารถเพิ่ม Instance Count ใน Free และ Shared Tiers ได้ App Service ต้องอยู่ใน "Basic", "Standard" หรือ "Premium" Tiers

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

เข้าหน้า Login อีกครั้ง และ Refresh หลายครั้ง Refresh กี่ครั้งก็ตาม IP Address ไม่เปลี่ยน

สังเกตว่า Web Server เดียวกัน Serving Pages 雖然เรา Enable Scaling 2 Instances App Service ยัง Serve Requests จาก Server เดียว

นี่อาจเป็นปัญหาใน Real-world เพราะ Server เดียว Serve Requests แม้ Load Balancing Enabled และ Servers อื่นไม่ถูก Utilize ให้เต็มที่

เหตุผลคือ ARR Cookie ตามภาพด้านล่าง สำหรับ Info เพิ่มเติม ดูที่นี่

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

Simple Terms: Cookie นี้มี Server Info จาก Initial Request Served โดย Server ใด ทำให้ Subsequent Requests จาก Session เดียว Served โดย VM เดียวกัน

Disable ARR Cookie Feature โดยไปที่ App Service Application Settings

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

ปิด "ARR Affinity" ตามภาพ และ Save Restart App Service เพื่อ Clear Sessions

โปรดระมัดระวัง Paragraphs ถัดไป Confusing 一点

Important

ปิด ARR Affinity จะ Disable การสร้าง ARRAffinity Cookie ดังนั้นเมื่อ Cookie Disabled Requests อาจส่งไป Server ใดก็ได้ที่ Available ไม่มี Guarantee Sessions Maintained Properly Sessions ทำงาน ONLY เมื่อ Requests Served จาก Same Server ถ้า Request ใด Served โดย Another Server (แทน Server ที่ Session Stored) Session จะเป็น NULL

กลับไป Web App ไปหน้า Login สังเกต IP Address ใหม่ "10.202.174.84" (ใน Case ของคุณ อาจเห็น IP เดิม Refresh จะเปลี่ยน ใน Case ผม Refresh 2 ครั้ง ได้ IP ใหม่)

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

กด "Login" บนภาพข้างบน NOT Guarantee Post ไป 10.202.174.84 อาจ Post ไป Server อื่น "10.202.116.91" ใน Case ผม

ตอนกด "Login" บนภาพข้างบน มันพาไป Default Page ด้วยค่า:

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

  • IP Address 10.202.174.84 (เหมือน Login Page)
  • Session is NULL เหตุผล: กด Login Request อาจไป Instance อื่น ("10.202.116.91") ที่ Session เก็บไว้
  • Refresh หน้าหลายครั้ง
    การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

โปรดสังเกต:

  • Session มีค่า "admin"
  • IPAddress 10.202.116.91

Conclusion: "Sessions" ไม่ทำงาน As Expected ใน Azure App Service เมื่อ Configure Load Balancer ด้วย Auto-scaling

นี่คือ Savior: Redis Cache Provider ตาม Definition จาก Azure Official Website

Azure Redis Cache Based on Popular Open-source Redis Cache ให้ Access to Secure, Dedicated Redis Cache, Managed by Microsoft Accessible จาก Application ใดๆ ใน Azure

Steps Required ทำ Sessions Work As Expected:

  • Create Redis Cache จาก Azure Management Portal
  • Configure Application ใช้ Azure Redis Cache
  • Use Sessions

Create Redis Cache จาก Azure Management Portal

เริ่มสร้าง Redis Cache ด้วย Azure Management Portal

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

ใส่รายละเอียด Redis Cache

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

กด "Create" ใช้เวลาสองนาทีสร้าง Redis Cache

Configure Application ใช้ Azure Redis Cache

Configure Application ใช้ Redis Cache ที่เพิ่งสร้าง

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

ตามภาพ Package Manager Console พิมพ์ "Install-Package StackExchange.Redis" Enter

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

ตอนนี้ Install Required Packages เรียบร้อย (Note: .NET Framework ควร 4 หรือ Higher)

เพื่อใช้ Assemblies เราต้อง Add Namespace ต่อไปไปทั้ง Login.aspx และ Default.aspx

Using StackExchange.Redis;

เพิ่ม Class ใหม่ชื่อ "RedisConnection" ใน Project Refer Attached Project

เพื่อ Connect Redis Cache เราต้อง Pass Info ต่อไปให้ ConnectionMultiplexer.Connect Function Grab จาก Portal

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

การจัดการ Session อย่างมีประสิทธิภาพบน Azure App Service ด้วย Redis Cache ใน Load-balanced Setups

  • Redis Cache URL
  • Keys

โปรดอย่า Save Keys ใน Code เพื่อ Simplicity ผมเก็บ Keys ใน Source Code โปรดดูหน้านี้สำหรับ Info ว่าเก็บ Credentials ยังไง

ตอนนี้ Ready Class สำหรับ Connect Redis Cache มาใช้สร้าง Session ใน Redis Cache

เปิด Login.aspx.cs แทนที่ Code:

Session["login"] = this.txtUsername.Text.Trim();

ด้วย:

IDatabase cache = RedisConnection.Connection.GetDatabase();
cache.StringSet("login", this.txtUsername.Text.Trim());

เปิด Default.aspx.cs แทนที่ Code:

protected void Page_Load(object sender, EventArgs e) {
    if (Session["login"] == null) {
        Response.Write("Session is NULL. You are in " + Request.ServerVariables["LOCAL_ADDR"]);
    } else {
        Response.Write("Logged in user is " + Session["login"] + ". You are in " + Request.ServerVariables["LOCAL_ADDR"]);
    }
}

ด้วย:

protected void Page_Load(object sender, EventArgs e) {
    IDatabase cache = RedisConnection.Connection.GetDatabase();
    string strLoginValue = cache.StringGet("login");
    if (strLoginValue == null) {
        Response.Write("Session is NULL. You are in " + Request.ServerVariables["LOCAL_ADDR"]);
    } else {
        Response.Write("Logged in user is " + strLoginValue + ". You are in " + Request.ServerVariables["LOCAL_ADDR"]);
    }
}

Deploy Code ไป Azure App Service Review Changes ไปหน้า Login

สังเกต IPAddress คือ 10.202.174.84 กด "Login" จะไป Default.aspx

สังเกตในภาพข้างบน 雖然 IPAddress ต่างกัน แต่ยังเห็น Username "admin" เพราะ SessionsStored ใน Distributed Location "Redis Cache" Accessible สำหรับ Both Instances

Refresh หลายครั้ง IP Addresses เปลี่ยน แต่ Username ไม่เปลี่ยน

That's it เราเรียนรู้ Store Sessions ใน Load Balancing Environment คุณสามารถ Store Data ใดๆ ใน Redis Cache

Hope you enjoyed reading the article Your Feedback Really Appreciated