เซสชันในสภาพแวดล้อมการปรับสมดุลโหลดแบบดั้งเดิม
โดยทั่วไป เราใช้เซสชันในหน่วยความจำ (ข้อมูลที่จัดเก็บไว้ใน RAM) ในแอปพลิเคชันเว็บทั้งหมด มันทำงานได้ดีในสภาพแวดล้อมโฮสติ้งแบบดั้งเดิมส่วนใหญ่ที่เราโฮสต์แอปพลิเคชันของเราใน VM เฉพาะหรือแผนโฮสติ้งที่ใช้ร่วมกันใดๆ
อย่างไรก็ตาม เมื่อปริมาณการรับส่งข้อมูลเพิ่มขึ้น เราวางแผนสำหรับการปรับสมดุลโหลดโดยการสร้างเว็บเซิร์ฟเวอร์หลายเครื่อง และควบคุมการรับส่งข้อมูลโดยใช้ Load Balancer ในสถานการณ์เหล่านี้ เซสชันจะไม่ทำงานเนื่องจากการร้องขอ (เกี่ยวข้องกับเซสชันเดียว) จะถูกให้บริการโดยเซิร์ฟเวอร์หลายเครื่อง (เซิร์ฟเวอร์เดียวกันที่ให้บริการคำขอของเซสชันเดียวก็เป็นไปได้เช่นกัน แต่ไม่แนะนำ) วิธีแก้ไขคือไปจัดเก็บเซสชันใน SQL Server ซึ่งสามารถเข้าถึงได้ผ่านเว็บเซิร์ฟเวอร์ทั้งหมดของสภาพแวดล้อม Load Balancing
เซสชันในสภาพแวดล้อมปรับขนาดอัตโนมัติของ Azure
แทนที่จะอภิปรายเชิงทฤษฎีเกี่ยวกับเรื่องนี้ เรามาดูการสนทนาเชิงปฏิบัติโดยตรงโดยการพัฒนาโปรแกรมขนาดเล็กที่ใช้เซสชันและดูว่าเซสชันทำงานอย่างไรใน Azure
มาสร้างเว็บไซต์กัน (คุณสามารถสร้างแอปพลิเคชัน MVC ได้เช่นกัน) ด้วยหน้าเว็บต่อไปนี้และปรับใช้แอปพลิเคชันตามที่แสดงในบทความก่อนหน้าของฉัน
- บริการแอป Azure - กำหนดค่าแอปพลิเคชันที่มีอยู่จาก Visual Studio
เข้าสู่ระบบ.aspx
หน้านี้ยอมรับเพียงชื่อผู้ใช้และรหัสผ่าน ที่ปุ่ม "เข้าสู่ระบบ" ให้คลิกปุ่ม สร้างเซสชันและจัดเก็บค่าของชื่อผู้ใช้ที่เข้าสู่ระบบในเซสชัน และเปลี่ยนเส้นทางผู้ใช้ไปที่ "Default.aspx"
โปรดทราบว่าหน้านี้ยังแสดงที่อยู่ IP “10.202.116.91” ของเครื่องเสมือนที่โฮสต์เว็บไซต์อยู่
ป>
ค่าเริ่มต้น.aspx
หน้านี้แสดงข้อความต่อไปนี้ตามค่าในเซสชัน
หากเซสชันมีค่าบางอย่าง ระบบจะแสดงข้อความ “ผู้ใช้ที่เข้าสู่ระบบในฐานะผู้ดูแลระบบ คุณอยู่ใน 10.202.116.91” ดังที่แสดงในภาพหน้าจอด้านล่าง
ป>
หากเซสชันไม่มีค่าใด ๆ จะแสดงข้อความ “เซสชันเป็นโมฆะ คุณอยู่ใน 10.202.116.91” ดังที่แสดงในภาพหน้าจอด้านล่าง
ป>
โปรดทราบว่า IPAddress ของเซิร์ฟเวอร์ทั้งใน Login.aspx และ Default.aspx จะเหมือนกัน คำขอทั้งหมดกำลังถูกส่งไปยังเซิร์ฟเวอร์เดียวกัน
นอกจากนี้ ตามการจับภาพหน้าจอด้านล่าง เซสชันจะถูกเก็บรักษาไว้โดยใช้คุกกี้ชื่อ “ASP.NET_SessionID” สิ่งนี้น่าจะคุ้นเคยกับพวกเราส่วนใหญ่

สมมติว่าปริมาณการเข้าชมเว็บไซต์ของเราเพิ่มขึ้น และเราต้องการขยายเป็นสองอินสแตนซ์ ดำเนินการต่อและเพิ่มจำนวนอินสแตนซ์เป็นสอง
หมายเหตุ: โปรดทราบว่าคุณไม่สามารถเพิ่มจำนวนอินสแตนซ์ในระดับฟรีและระดับที่ใช้ร่วมกันได้ บริการแอปของคุณควรอยู่ในระดับ "พื้นฐาน", "มาตรฐาน" หรือ "พรีเมียม"

เข้าสู่หน้าเข้าสู่ระบบอีกครั้งและเข้าถึงได้หลายครั้งโดยการรีเฟรชหน้า การรีเฟรชเพจหลายครั้งจะไม่เปลี่ยนที่อยู่ IP
คุณจะสังเกตเห็นว่าเว็บเซิร์ฟเวอร์เดียวกันกำลังให้บริการเพจต่างๆ แม้ว่าเราจะเปิดใช้งานการปรับขนาดเป็นสองอินสแตนซ์ แต่บริการแอปยังคงให้บริการตามคำขอจากเซิร์ฟเวอร์เดียว
นี่อาจเป็นปัญหาในสถานการณ์จริงเนื่องจากเซิร์ฟเวอร์เดียวกันกำลังให้บริการตามคำขอ แม้ว่า Load Balancing จะเปิดใช้งานอยู่และเซิร์ฟเวอร์อื่นๆ ไม่ได้ใช้งานอย่างถูกต้องก็ตาม
สาเหตุที่คำขอทั้งหมดได้รับการตอบสนองก็เนื่องมาจากคุกกี้ ARR ดังที่แสดงด้านล่าง สำหรับข้อมูลเพิ่มเติม โปรดดูที่นี่

ในแง่ง่าย คุกกี้นี้มีข้อมูลเซิร์ฟเวอร์ที่ให้บริการคำขอเริ่มต้น ดังนั้นคำขอที่ตามมาทั้งหมดจากเซสชันเดียวกันจะได้รับบริการโดย VM เดียวกัน
มาปิดการใช้งานคุณสมบัติคุกกี้ ARR กันโดยไปที่การตั้งค่าแอปพลิเคชันของบริการแอพดังที่แสดงด้านล่าง

ปิด "ARR Affinity" ดังที่แสดงในภาพหน้าจอด้านบน และคลิกที่ปุ่ม "บันทึก" เพื่อบันทึกการเปลี่ยนแปลง โปรดเริ่มบริการแอปใหม่เพื่อล้างเซสชันทั้งหมด
จากนี้ไปโปรดระมัดระวังกันหน่อย สองสามย่อหน้าต่อไปนี้ค่อนข้างน่าสับสน
สำคัญ
การปิด ARR Affinity จะปิดกระบวนการสร้างคุกกี้ คุกกี้ ARRAffinity ดังนั้น เมื่อปิดใช้งานคุกกี้ คำขออาจถูกส่งไปยังเซิร์ฟเวอร์ที่มีอยู่ ดังนั้นจึงไม่มีการรับประกันว่าเซสชันต่างๆ จะได้รับการดูแลอย่างเหมาะสม เซสชันจะทำงานเฉพาะเมื่อมีการให้บริการคำขอจากเซิร์ฟเวอร์เดียวกัน หากคำขอใด ๆ ได้รับการให้บริการโดยเซิร์ฟเวอร์อื่น (แทนที่จะเป็นที่จัดเก็บเซสชัน) เซสชันจะเป็นโมฆะ
ตอนนี้ กลับมาที่ Web App แล้วไปที่หน้าเข้าสู่ระบบและสังเกตเห็น IPAddress ใหม่ “10.202.174.84” (ในกรณีของคุณ ในตอนแรกคุณอาจเห็น IPAddress เหมือนเดิม การรีเฟรชหน้าจะเปลี่ยน IPAddress ในกรณีของฉัน ฉันรีเฟรชหน้าสองครั้งเพื่อรับ IPAddress ใหม่ดังที่แสดงด้านล่าง)

การคลิกที่ปุ่มเข้าสู่ระบบจะไม่รับประกันว่าแบบฟอร์มจะถูกโพสต์ไปที่ 10.202.174.84 อาจโพสต์ข้อมูลไปยังเซิร์ฟเวอร์อื่นซึ่งในกรณีของฉันคือ “10.202.116.91”
ในกรณีของฉัน เมื่อฉันคลิกที่ปุ่ม “เข้าสู่ระบบ” ของการจับภาพหน้าจอด้านบน ระบบจะพาฉันไปยังหน้าเริ่มต้นด้วยค่าต่อไปนี้

- ที่อยู่ IP คือ 10.202.174.84 (ที่อยู่เดียวกันในหน้าเข้าสู่ระบบของฉัน)
- เซสชันเป็นโมฆะ เหตุผลก็คือ เมื่อคลิกเข้าสู่ระบบ คำขออาจไปยังอินสแตนซ์อื่น (“10.202.116.91”) ที่เซสชันของฉันถูกจัดเก็บไว้
- รีเฟรชเพจสองสามครั้ง
โปรดสังเกตสิ่งต่อไปนี้
- เซสชันมีค่าบางอย่างเป็น "ผู้ดูแลระบบ"
- ที่อยู่ IP คือ 10.202.116.91
ดังนั้น ข้อสรุปที่นี่คือ "เซสชัน" จะไม่ทำงานตามที่คาดไว้ใน Azure App Service เมื่อคุณกำหนดค่า Load Balancer โดยใช้คุณลักษณะการปรับขนาดอัตโนมัติ
มาที่นี่พระผู้ช่วยให้รอด ผู้ให้บริการแคช Redis ด้านล่างนี้คือคำจำกัดความจากเว็บไซต์ทางการของ Azure
Azure Redis Cache ขึ้นอยู่กับแคช Redis แบบโอเพ่นซอร์สยอดนิยม ช่วยให้คุณเข้าถึงแคช Redis เฉพาะที่ปลอดภัย ซึ่งจัดการโดย Microsoft และเข้าถึงได้จากแอปพลิเคชันใดๆ ภายใน Azure
ด้านล่างนี้เป็นขั้นตอนที่จำเป็นในการทำให้เซสชันของเราทำงานได้ตามที่คาดไว้
- สร้าง Redis Cache จาก Azure Management Portal
- กำหนดค่าแอปพลิเคชันเพื่อใช้ Azure Redis Cache
- ใช้เซสชัน
สร้างแคช Redis จากพอร์ทัลการจัดการ Azure
มาเริ่มต้นสร้าง Redis Cache โดยใช้ Azure Management Portal ดังที่แสดงด้านล่าง
ระบุรายละเอียดของ Redis Cache ดังที่แสดงด้านล่าง
คลิกที่ปุ่ม "สร้าง" ของการจับภาพหน้าจอด้านบน จะใช้เวลาสองสามนาทีในการสร้าง Redis Cache
กำหนดค่าแอปพลิเคชันเพื่อใช้ Azure Redis Cache
มากำหนดค่าแอปพลิเคชันให้ใช้ Redis Cache ที่เราเพิ่งสร้างขึ้น
ดังที่แสดงในภาพหน้าจอด้านบน ให้ไปที่ Package Manager Console แล้วพิมพ์คำสั่ง “Install-Package StackExchange.Redis” แล้วคลิก “Enter”
ตอนนี้เราได้ติดตั้งแพ็คเกจที่จำเป็นเรียบร้อยแล้ว (โปรดทราบว่ากรอบงาน .NET ของคุณควรเป็น 4 หรือสูงกว่า)
ในการใช้แอสเซมบลี เราต้องเพิ่มเนมสเปซต่อไปนี้ในหน้า Login.aspx และหน้า Default.aspx ก่อน
การใช้ StackExchange.Redis;
มาเพิ่มคลาสใหม่ชื่อ "RedisConnection" ให้กับโปรเจ็กต์ โปรดดูโครงการที่แนบมา
ในการเชื่อมต่อกับ Redis Cache เราจำเป็นต้องส่งข้อมูลต่อไปนี้ไปยังฟังก์ชัน ConnectionMultiplexer.Connect ไปคว้าพวกมันจากพอร์ทัลกันเถอะ

- URL แคช Redis
- กุญแจ
กรุณาอย่าบันทึกคีย์ในรหัส เพื่อให้สิ่งต่าง ๆ ง่ายขึ้น ฉันกำลังจัดเก็บคีย์ไว้ในซอร์สโค้ด โปรดดูหน้านี้ซึ่งมีข้อมูลเกี่ยวกับวิธีการจัดเก็บข้อมูลประจำตัว
ตอนนี้เราพร้อมแล้วกับคลาสที่สามารถใช้เพื่อเชื่อมต่อกับ Redis Cache มาใช้คลาสเพื่อสร้างเซสชันใน Redis Cache กันดีกว่า
เปิดไฟล์ Login.aspx.cs ของคุณและแทนที่บรรทัดโค้ดต่อไปนี้
Session["login"] = this.txtUsername.Text.Trim();
ด้วย.
IDatabase cache = RedisConnection.Connection.GetDatabase();
cache.StringSet("login", this.txtUsername.Text.Trim());
เปิด Default.aspx.cs และแทนที่บรรทัดโค้ดต่อไปนี้
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"]);
}
}
มาปรับใช้โค้ดกับ Azure App Service และตรวจสอบการเปลี่ยนแปลงและนำทางไปยังหน้าเข้าสู่ระบบดังที่แสดงด้านล่าง
ป>
สังเกตที่อยู่ IP มันคือ 10.202.174.84 ตอนนี้คลิกที่ปุ่ม "เข้าสู่ระบบ" คุณจะถูกนำไปที่หน้า Default.aspx ดังที่แสดงด้านล่าง
ป>
โปรดสังเกตว่าในการจับภาพหน้าจอด้านบน แม้ว่า IPAddress จะแตกต่างออกไป แต่เรายังคงเห็นชื่อผู้ใช้ “ผู้ดูแลระบบ” ได้ เนื่องจากขณะนี้เซสชันถูกจัดเก็บไว้ในตำแหน่งแบบกระจาย “Redis Cache” ซึ่งสามารถเข้าถึงได้จากทั้งสองอินสแตนซ์
ตอนนี้ ให้รีเฟรชหน้าหลายครั้ง คุณจะสังเกตเห็นว่าที่อยู่ IP มีการเปลี่ยนแปลง แต่ไม่ใช่ค่าของชื่อผู้ใช้
แค่นั้นแหละ. เราได้เรียนรู้วิธีจัดเก็บเซสชันในสภาพแวดล้อมการปรับสมดุลโหลด คุณสามารถจัดเก็บข้อมูลประเภทใดก็ได้ใน Redis Cache
หวังว่าคุณจะสนุกกับการอ่านบทความนี้ ความคิดเห็นของคุณได้รับการชื่นชมจริงๆ