Apache + Tomcat - ปัญหาเกี่ยวกับเซสชันที่ติดหนึบและการปรับสมดุลโหลด

ฉันกำลังประสบปัญหาบางอย่างกับ Apache mod_proxy_balancer เกี่ยวกับเซสชันที่ติดหนึบ

เราได้พัฒนาบริการเว็บเพื่อการพักผ่อนใน Java ซึ่งทำงานบน Tomcat แบ็กเอนด์จริงใช้การรักษาความปลอดภัย Acegi พร้อมการรับรองความถูกต้อง Auth Basic

สถาปัตยกรรมคือ (ขออภัยฉันเป็นผู้ใช้ใหม่ ฉันไม่สามารถโพสต์ภาพได้):

     --------------------
     |Java Reverse Proxy|
     --------------------
            |
     --------------------
     |Apache load balancer|
     --------------------               
            |
    --------|--------
    |               |
--------        --------    
|tomcat1|       |tomcat2|
--------        --------    

เรามี "Java Reverse Proxy" นี้เพื่อดำเนินธุรกิจต่างๆ นอกจากนี้ยังทำการรับรองความถูกต้อง Basic Auth บน Tomcat (Tomcat1, Tomcat2)

URL การโทรของผู้ใช้ปลายทางเช่น: http:///a/b?username=foo&password=bar&session=xxx

พร็อกซีย้อนกลับจะส่งคำขอไปยัง Apache โดยส่งข้อมูลประจำตัวเป็นโทเค็นการตรวจสอบสิทธิ์พื้นฐาน

ผู้ใช้ปลายทางมี URL ที่แตกต่างกันสามรายการ:

http://<java reverse proxy domain>/service1
http://<java reverse proxy domain>/service2
http://<java reverse proxy domain>/service3

เฉพาะ service1 และ service2 เท่านั้นที่ได้รับการคุ้มครองผ่าน Acegi service3 สามารถเข้าถึงได้โดยไม่เปิดเผยตัวตน (นี่เป็นข้อกำหนด)

เรามีการกำหนดค่าต่อไปนี้ใน Apache เพื่อดำเนินการโหลดบาลานซ์:

<Proxy balancer://cluster>
    Header set Cache-Control no-cache
    Header set Pragma no-cache
    BalancerMember http://xxx:9671 route=server1
    BalancerMember http://xxx:9672 route=server2
</Proxy>

ProxyPreserveHost On
ProxyPass / balancer://cluster/ stickysession=JSESSIONID
ProxyPassReverse / balancer://cluster/ stickysession=JSESSIONID

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

เพื่อรักษาสถานะเซสชันใน Tomcats แบ็กเอนด์ (tomcat1, tomcat2) พร็อกซีย้อนกลับ java จะได้รับเซสชันจากสตริงการสืบค้นและส่งไปยัง Tomcats ที่ได้รับมอบฉันทะเป็นคุกกี้ JSESSIONID

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

ตัวอย่างเช่น เมื่อฉันเรียกใช้บริการ 1 หรือ 2 ฉันจะได้รับบันทึก Apache ต่อไปนี้:

[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(280): proxy: BALANCER: Found value "3FB8F8135173BBBE78E5E4BBD6F5C8FB" for stickysession JSESSIONID
[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(1003): proxy: Entering byrequests for BALANCER (balancer://cluster)
[Wed Feb 22 10:48:52 2012] [debug] mod_proxy_balancer.c(1046): proxy: byrequests selected worker "http://xxx:9672" : busy 0 : lbstatus 1

ซึ่งถือว่าใช้ได้อย่างสมบูรณ์แบบ เนื่องจากการร้องขอมีจุดมุ่งหมายเพื่อกำหนดเป้าหมาย tomcat2

แต่เมื่อฉันโทรไปที่ service3 ฉันจะได้รับ:

[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(280): proxy: BALANCER: Found value "3FB8F8135173BBBE78E5E4BBD6F5C8FB" for stickysession JSESSIONID
[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(1003): proxy: Entering byrequests for BALANCER (balancer://cluster)
[Wed Feb 22 10:49:27 2012] [debug] mod_proxy_balancer.c(1046): proxy: byrequests selected worker "http://xxx:9671" : busy 0 : lbstatus 0

อย่างที่คุณเห็น แม้ว่าคุกกี้ JSESSIONID จะเหมือนกัน แต่ Apache จะส่งคำขอไปยัง Tomcat ที่ไม่ถูกต้อง (ในที่นี้คือ Tomcat1)

เป็นไปได้ไหมว่า url สำหรับ service3 ไม่ต้องการการรับรองความถูกต้อง Auth Basic ในขณะที่ service1 และ service2 ทำ

ฉันค่อนข้างแน่ใจว่าฉันได้ทำอะไรผิดไป แต่ฉันได้มองไปรอบ ๆ เป็นเวลานาน และฉันไม่สามารถทำงานได้

ความช่วยเหลือของคุณได้รับการชื่นชมอย่างมาก

ขอบคุณ


person benjamin.d    schedule 22.02.2012    source แหล่งที่มา


คำตอบ (3)


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

person Peter Cetinski    schedule 24.02.2012
comment
นั่นเป็นเรื่องจริง ตามตัวอย่างที่ฉันให้ไว้ ฉันลืม jvmRoute แต่แม้แต่การตั้งค่าใน server.xml ก็ไม่สามารถแก้ไขปัญหาได้ - person benjamin.d; 26.02.2012

บางทีมก็อาจจะช่วยได้ นี่คือการกำหนดค่าของฉันบนเว็บเซิร์ฟเวอร์:

<Proxy balancer://hybriscluster>
BalancerMember ajp://tomcatServer1:8009 route=tomcat1 keepalive=On ping=5 max=200 ttl=120
BalancerMember ajp://tomcatServer2:8009 route=tomcat2 keepalive=On ping=5 max=200 ttl=120
ProxySet stickysession=JSESSIONID|jsessionid lbmethod=byrequests timeout=60
</Proxy>

กำหนดค่าใน server.xml ของ tomcat Server 1:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"}">
person user1019100    schedule 26.09.2013

ฉันกำลังประสบปัญหาเดียวกันและแก้ไขได้โดยแก้ไขบรรทัดด้านล่าง -

ProxyPass /test balancer://mycluster stickysession=JSESSIONID|jsessionid scolonpathdelim=On
<Proxy balancer://mycluster>
BalancerMember http://192.168.1.2:80 route=node1
BalancerMember http://192.168.1.3:80 route=node2
</Proxy>

โปรดสังเกตการกำหนดค่า scolonpathdelim=On Reference - http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html

person Munish Chandel    schedule 16.04.2014