เหตุใดจึงไม่สามารถแบ่งปันข้อมูลเซสชันได้


11

ฉันได้เห็นนักพัฒนาหลายคนกำลังมองหาทางออกสำหรับปัญหานี้: การเข้าถึงข้อมูลเซสชั่นจากสงครามที่แตกต่างกัน (แม้ในภายใน EAR เดียวกัน) - นี่คือตัวอย่างบางส่วน: วิธีใดที่จะแบ่งปันสถานะเซสชันระหว่างแอปพลิเคชันต่างๆ , เซสชันการเข้าถึงของเว็บแอปพลิเคชันอื่น , ไฟล์ WAR ที่แตกต่างกัน, ทรัพยากรที่แชร์ , Tomcat: วิธีการแบ่งปันข้อมูลระหว่างสองแอปพลิเคชัน , อะไรแอตทริบิวต์ crossContext ทำใน Tomcat? เปิดใช้งานการแชร์เซสชันหรือไม่ และอื่น ๆ ...

จากทั้งหมดที่ฉันค้นหามีวิธีแก้ปัญหาเฉพาะบางอย่างขึ้นอยู่กับคอนเทนเนอร์ แต่อย่างใด ' ตรงกันข้ามกับข้อมูลจำเพาะ ' ฉันยังได้ดูข้อมูลจำเพาะ Java EE โดยไม่มีโชคในการหาคำตอบ

นักพัฒนาบางคนพูดถึงการมีเพศสัมพันธ์ระหว่างเว็บแอปพลิเคชัน แต่ฉันมักจะไม่เห็นด้วย อะไรคือเหตุผลที่ทำให้ WARs อยู่ใน EAR เดียวกันหากไม่ได้มีเพศสัมพันธ์? ตัวอย่างเช่น EJB สามารถเข้าถึงได้แบบโลคัล (แม้ว่าจะอยู่ใน EJB JAR อื่นภายใน EAR เดียวกัน)

โดยเฉพาะอย่างยิ่งหนึ่งใน WAR ของฉันจัดการกับการตรวจสอบและการอนุญาตและฉันต้องการแบ่งปันข้อมูลนี้กับ WAR อื่น ๆ (ใน EAR เดียวกัน) ฉันจัดการเพื่อแก้ไขปัญหาที่คล้ายกันก่อนหน้านี้โดยการบรรจุ WARs เป็น JARs และวางลงในโครงการสงครามเอกพจน์ (WEB-INF / lib) แต่ฉันไม่ชอบโซลูชันนี้ (ต้องใช้ความพยายามอย่างมากในการตั้งชื่อเซิร์ฟเล็ตและอื่น ๆ )

และไม่มีวิธีตอบคำถามแรก (และที่สำคัญที่สุด): ทำไม WAR ไม่สามารถแบ่งปันข้อมูลเซสชันได้


1
ไม่แน่ใจว่าทำไมสิ่งนี้จึงถูก downvote นอกเหนือจากนั้นอาจเหมาะสำหรับ SO
NateDSaint

3
"ตามข้อกำหนดข้อกำหนดเซิร์ฟเล็ต 2.3 API ผู้จัดการเซสชันสนับสนุนการกำหนดขอบเขตโดยเว็บโมดูลเท่านั้นเฉพาะเซิร์ฟเล็ตในเว็บโมดูลเดียวกันเท่านั้นที่สามารถเข้าถึงข้อมูลที่เชื่อมโยงกับเซสชันเฉพาะ" สิ่งนี้สามารถเห็นได้อีกในHttpSession - "ข้อมูลเซสชันถูกกำหนดขอบเขตเฉพาะเว็บแอปพลิเคชันปัจจุบัน (ServletContext) ดังนั้นข้อมูลที่เก็บไว้ในบริบทหนึ่งจะไม่สามารถมองเห็นได้โดยตรงในอีกบริบทหนึ่ง" - การทำเช่นนั้นขัดต่อข้อกำหนด

(ดีกว่าลิงค์ปัจจุบันสำหรับHttpSession )

@MichaelT ขอบคุณ แต่ก็ยังไม่ตอบว่าทำไม
rvcoutinho

@NateDSaint แม้ว่าคำถามจะเกี่ยวข้องกับเทคโนโลยีเฉพาะ แต่ฉันเชื่อว่ามันเป็นคำถามแนวความคิดมากกว่า จากนั้นฉันตัดสินใจเลือกโปรแกรมเมอร์
rvcoutinho

คำตอบ:


7

ปฏิบัติกับ EAR เสมือนเครื่องเลียนแบบเสมือน

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

ในทำนองเดียวกับที่กระบวนการหนึ่งในเครื่องเสมือนไม่สามารถส่งผลกระทบต่อกระบวนการอื่นได้เช่นเดียวกับ EAR สงครามทั้งหมดถูกแยกออกเพื่อปกป้องสถานะภายในของพวกเขา

ปรับการรับรองความถูกต้อง

โดยทั่วไปเว็บแอปพลิเคชันจะต้องไร้สัญชาติมีขนาดเพียงพอ การมีข้อมูลจำนวนมากในเซสชันเป็นรูปแบบการต่อต้านที่ป้องกันสิ่งนี้ สิ่งนี้นำไปสู่ความขัดแย้งระหว่างลักษณะไร้สัญชาติของ HTTP และความต้องการที่จะรักษาประสบการณ์ผู้ใช้ที่รวดเร็วและปรับแต่งได้ การรับรองความถูกต้องเป็นกรณีการใช้งานแบบคลาสสิคและแพร่หลายใน chatty APIs ที่ต้องการคำขอที่ได้รับการรับรองความถูกต้องจำนวนมากเพื่อส่งมอบการทำงานของผู้ใช้ปลายทาง

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

การมุ่งเน้นที่การเข้าถึงแคชของข้อมูลที่เกี่ยวข้องอย่างรวดเร็วจะให้ผลลัพธ์ที่ปรับขนาดได้มากกว่าโซลูชันการแชร์เซสชันที่ซับซ้อนและเปราะบาง


ขอบคุณ @GaryRowe นี่คือคำตอบที่ฉันต้องการ อย่างไรก็ตามนั่นเป็นสิ่งที่นักพัฒนาจะต้องตัดสินใจใช่ไหม
rvcoutinho

คำถามอื่น: คุณคิดว่า JBoss Cache อาจเป็นทางออกที่ดีหรือไม่? คุณเคยรู้จัก Apache Shiro (และการรวมกลุ่มเซสชัน) หรือไม่? แล้วมันล่ะ?
rvcoutinho

@rvcoutinho ผู้พัฒนาแอปพลิเคชั่นตัดสินใจว่ากระบวนการต่างๆได้รับการจัดการในเคอร์เนล Linux หรือไม่? มันเป็นกรอบคำถามที่คล้ายกัน - ใช่คุณสามารถทำได้ แต่มันจะยากมากและอาจทำให้คุณเจ็บปวดมากกว่าการใช้ทางเลือกอื่น
Gary Rowe

2
@rvcoutinho ฉันไม่ได้ใช้ Apache Shiro (aka Apache Security) แต่ฉันคิดว่ามันจะเป็นทางออกที่ดีสำหรับปัญหาความปลอดภัยที่ใช้ร่วมกัน พิจารณาการผสานรวมกับ OpenID และ OAuth2 อย่างแน่นอนแทนที่จะใช้โปรโตคอลของคุณเองเพื่อให้ได้สิ่งเดียวกัน JBoss Cache นั้นมาจากทางเข้าของตัวเองในทางตันที่ถูกแทนที่ด้วย Infinispan ซึ่งดูค่อนข้างซับซ้อน คุณอาจต้องการดูที่เว็บไซต์ของTwelve-Factor Appเพื่อดูโซลูชันที่ปรับขนาดได้ง่ายขึ้น
Gary Rowe

2

มันเป็นสิ่งที่ฉันคิดว่าขาดฟังก์ชั่นการทำงานจากข้อกำหนด JEE EAR - ความสามารถในการแบ่งปันเซสชันทางเว็บผ่านคลังเก็บเว็บหลายแห่งที่ผูกไว้ภายใน EAR

เซิร์ฟเวอร์แอปเช่น Weblogic มีการใช้งานที่ไม่ได้มาตรฐานสำหรับฟังก์ชั่นนี้


นั่นคือความคิดเห็นของฉันจนถึงตอนนี้ ฉันพยายามเข้าใจว่าทำไมตัวเลือกดังกล่าวถึงเกิดขึ้น
rvcoutinho

1

AFAIKS ไม่มีเหตุผลที่แท้จริงว่าทำไมคุณถึงต้องการทำเช่นนี้ WAR เป็นเว็บแอปพลิเคชันที่มีอยู่ในตัวพร้อมด้วยขอบเขต (เฉพาะแอปพลิเคชันเว็บ) (เช่นขอบเขตเซสชัน) หากคุณต้องการแบ่งปันฟังก์ชั่นการใช้งาน (รหัส Java, หน้า JSP, ไฟล์ CSS) ระหว่าง WAR หลาย ๆ ตัวคุณมีตัวเลือกที่เหมาะสมกว่าในการบรรจุเป็นไฟล์ JAR และปรับใช้ในเซิร์ฟเวอร์แอปพลิเคชันของคุณ แพ็คเกจ WAR เป็นโซลูชันบรรจุภัณฑ์ที่มีความซับซ้อนมากขึ้นและแพคเกจที่ออกแบบมาเพื่อแค็ปซูลสิ่งที่แตกต่างจาก "รหัสทั่วไป / ฟังก์ชันการทำงาน" แบบธรรมดา JAR เป็นรูปแบบที่เรียบง่ายกว่าและได้รับการออกแบบมาสำหรับบรรจุภัณฑ์และรหัสการใช้งานร่วมกัน เหตุใดคุณจึงต้องการใช้บรรจุภัณฑ์ที่ซับซ้อนและไม่ได้ออกแบบมาเพื่อการแบ่งปันบางสิ่งบางอย่างเมื่อคุณมีรูปแบบแพคเกจที่เรียบง่ายกว่าและเหมาะกว่าที่มีอยู่แล้ว


ฉันเห็นด้วยกับคุณ. แต่เมื่อมันมาถึงทรัพยากรทั่วไปเท่านั้น แต่สำหรับแอปพลิเคชันลงชื่อเข้าใช้ครั้งเดียวฉันจะต้องแบ่งปันข้อมูลเฉพาะเซสชัน (เกี่ยวกับผู้ใช้ที่เข้าสู่ระบบ) และฉันไม่เห็นเหตุผลว่าทำไมสิ่งนี้จึงขัดกับสเป็ค
rvcoutinho

2
เนื่องจากขอบเขตเซสชันไม่ได้ถูกสร้างขึ้นเพื่อแบ่งปันข้อมูลผู้ใช้ปัจจุบันระหว่างแอปพลิเคชันต่างๆ และเนื่องจาก SSO มีความหมายมากกว่าการตรวจสอบคุณลักษณะขอบเขตเซสชัน คุณสามารถสร้างและทำรหัสแพ็คเกจนอกสงครามของคุณ (ซึ่งจะไม่ขึ้นอยู่กับสงครามของคุณ แต่ให้ทำสงครามขึ้นอยู่กับมัน) ซึ่งจะเข้าถึงคุณลักษณะขอบเขตเซสชันหากคุณต้องการ (เช่นตัวกรอง) แต่ทางออกที่ดีกว่า IMHO เพื่อให้แอปพลิเคชันด้านหน้าแยกต่างหากหรือการกำหนดค่าเซิร์ฟเวอร์ที่เกี่ยวข้องกับการรับรองความถูกต้องและให้สิทธิ์การเข้าถึงแอปพลิเคชันอื่น (สงครามปรับใช้)
Shivan Dragon

ฉันจะเห็นด้วยกับคุณอีกครั้ง แต่ข้อกำหนดคุณสมบัติ JavaEE (โดยใช้ JAAS) เก็บข้อมูลผู้ใช้เป็นส่วนหนึ่งของ HttpSession ซึ่งตรงข้ามกับวิธีนี้ หนึ่งในเหตุผลที่ฉันได้พิจารณาใช้ชิโร่ (มันรักษาเซสชั่นมุมฉาก) แทน
rvcoutinho

อย่างไรก็ตามขอขอบคุณสำหรับการตอบกลับ ฉันยังไม่มีคำตอบที่ชัดเจนสำหรับคำถามของฉัน แต่สิ่งที่คุณพูดมีความเกี่ยวข้อง +1
rvcoutinho

@rvcoutinho ดีนั่นเป็นความเห็นของฉันในเรื่องนี้ขอโทษที่ไม่มีประโยชน์กับคุณมากกว่านี้
Shivan Dragon

0

ฉันคิดว่าสิ่งนี้ทำขึ้นโดยมีวัตถุประสงค์เพื่อหลีกเลี่ยงแอปพลิเคชันเว็บอื่น ๆ ที่เขียนทับข้อมูลเซสชันของผู้อื่นโดยไม่ตั้งใจ อาจเป็นประโยชน์ในกรณีของคุณ แต่โดยทั่วไปคุณไม่ต้องการให้ผู้ใช้ทำให้แอพเสียหายหรือเพิ่มสิทธิ์ของพวกเขาเพียงเพราะพวกเขาใช้เว็บแอปสองตัวในเวลาเดียวกัน การแบ่งปันข้อมูลระหว่างแอปบนเว็บไม่ใช่เรื่องยาก เพียงสร้างคลาสด้วย HashMap แบบคงที่ใช้ GUID เป็นคีย์และถ่ายโอนเป็นส่วนหนึ่งของพารามิเตอร์ URL หรือ HTTP


ขอบคุณ ที่จริงแล้วฉันไม่ได้พูดถึงการแบ่งปันเซสชันทั้งหมดระหว่างทุกแอปพลิเคชัน แต่ข้อมูลเซสชันที่เฉพาะเจาะจง (เป็นข้อมูลผู้ใช้) เมื่อจำเป็น บางทีฉันอาจจะไม่ชัดเจน ข้อเสนอแนะใด ๆ ในการทำให้ชัดเจนยิ่งขึ้น?
rvcoutinho
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.