ใช้การจัดการเซสชันแบบกระจายในฤดูใบไม้ผลิ
บทความนี้ส่วนใหญ่ใช้เซสชันกระจายในฤดูใบไม้ผลิและใช้ REDIS เพื่อคงอยู่เซสชัน ด้วยวิธีนี้เมื่อแอปพลิเคชันถูกปรับใช้ไม่จำเป็นต้องกำหนดค่าการกระจายในคอนเทนเนอร์เช่นเรซินและ Tomcat ซึ่งสะดวกสำหรับการเพิ่มเซิร์ฟเวอร์โหนดใหม่สำหรับการขยายคลัสเตอร์ เซสชันไม่ได้ขึ้นอยู่กับเซิร์ฟเวอร์ของแต่ละโหนดและสามารถรับได้โดยตรงจาก Redis นี่คือรหัสหลักของฟังก์ชั่น:
1. ก่อนกำหนดค่าใน web.xml
เพิ่มไปยัง interceptor:
<!-การเริ่มต้นเซสชันการกระจาย-> <filter> <silter-name> DistributedSessionFilter </filter-name> <silter-class> DistributedSessionFilter </filter-class> <int-Param> <!-จำเป็นต้องใช้กุญแจ 2 วิธี 1 สอดคล้องกับถั่วรูปแบบคือถั่ว: คีย์ 2 Strings, รูปแบบเช่น: Affffrfgv-> <param-name> key </param-name> <param-value> xxxxxxxxx </param-value> </init-param> <init-Param> <! <param-value> ถั่ว: redispersistent </param-value> // distributedBaseInterface ซึ่งสอดคล้องกับอินเทอร์เฟซนี้ดำเนินการการดำเนินงานการคงอยู่ของเซสชัน </init-param> <init-Param> <! <Tilter-Name> DistributedSessionFilter </filter-name> <url-pattern>*. ทำ </url-pattern> </ตัวกรองการแมป> <!-ปลายเซสชันแจกจ่าย->
2. การใช้งาน interceptor รหัสหลักมีดังนี้
ส่วนใหญ่มีหมวดหมู่ต่อไปนี้:
1. DistributedSessionFilter ใช้ตัวกรอง:
นำเข้า java.io.ioexception; นำเข้า java.util.hashmap; นำเข้า java.util.map; นำเข้า Javax.servlet.filter; นำเข้า javax.servlet.filterchain นำเข้า javax.servlet.filterconfig; javax.servlet.servletResponse; นำเข้า Javax.servlet.http.httpservletRequest; นำเข้า Javax.servlet.http.httpservletResponse; นำเข้า org.springframework.web.context.webapplication org.springframework.web.context.support.webapplicationContextUtils; คลาสสาธารณะ DistributedSessionFilter ใช้ตัวกรอง {logger สุดท้ายคงที่ logger log = loggerFactory.getLogger (DistributedSessionFilter.Class); สตริงส่วนตัว Cookiename; // ส่วนใหญ่เป็นการดำเนินการเพื่อจัดการเซสชันส่วนตัว DistributedSessionAnager DistributedSessionManager; คีย์สตริงส่วนตัว;}วิธีการเริ่มต้นเมื่อคอนเทนเนอร์เริ่ม:
@Override เป็นโมฆะสาธารณะ init (filterConfig config) พ่น servletexception {webApplicationContext WAC = webApplicationContextUtEs.getRequiredWebapplicationContext (config .getServletContext ()); String key = config.getInitParameter ("key"); String cookiename = config.getInitParameter ("cookiename"); String cachebean = config.getInitParameter ("CacheBean"); // รับชื่อถั่วการกำหนดค่าคือ "ถั่ว:" สตริง redisbeanstr = cachebean.substring (5); DistributedBaseInterface DistributedCache = (DistributedBaseInterface) wac.getBean (Redisbeanstr); // รับคีย์มี 2 วิธีการกำหนดค่า 1 สอดคล้องกับถั่วและรูปแบบคือถั่ว: คีย์ 2 สตริงถ้า (key.startswith ("ถั่ว:")) {this.key = (สตริง) wac.getBean (key.substring (5)); } else {this.key = key; } this.cookiename = cookiename; this.distributedSessionManager = DistributedSessionManager.getInstance (DistributedCache); // การจัดการข้อยกเว้นจะถูกละเว้น - - -ทำการสกัดกั้นคำขอจริง:
@Override โมฆะสาธารณะ Dofilter (ServletRequest ServletRequest, ServletResponse ServletResponse, FilterChain FilterChain) พ่น ServleTexception, iOexception {DistributeDhttpServletRequestWrapper distreq = null; ลอง {// คำขอการประมวลผล distreq = createDistributedRequest (servletRequest, servletResponse); FilterChain.dofilter (Distreq, ServletResponse); } catch (throwable e) {// ละเว้น - - } ในที่สุด {if (distreq! = null) {ลอง {// หลังจากประมวลผลคำขอให้ประมวลผลเซสชัน (ส่วนใหญ่บันทึกเซสชันเซสชัน) ข้อตกลงใด ๆ } catch (throwable e2) {// ละเว้น - - }}}}} // คำขอกระจายส่วนตัว DistributedHttpServletRequestWrapper createDistributedRequest (ServletRequest ServletRequest, servletResponse servletResponse) โยน ioException, servletexception httpservletResponse response = (httpservletResponse) servletResponse; String usersId = cookieutil.getCookie (cookiename, คำขอ); String realsId = distributedSessionManager.getActualSID (ผู้ใช้, คำขอ, คีย์); if (stringutil.isblank (realsId)) {ถ้า (stringutil.isnotblank (usersid)) {log.info ("usersId [{}] การตรวจสอบล้มเหลว", usesId); } // เขียนสตริงคุกกี้ [] UsersIdarr = DistributedSessionManager.createUsersid (คำขอ, คีย์); UsersId = UsersIdarr [0]; Cookieutil.SetCookie (Cookiename, UsersID, คำขอ, การตอบกลับ); actureSid = usersidarr [1]; } actualSid = "sid:" + realsid; DistributedhttpsessionWrapper distsession = null; ลอง {map <string, object> allattribute = distributedSessionManager.getSession (realsid, request.getSession () .getMaxinactiveInterval ()); distsession = ใหม่ distributedhttpsessionWrapper (realsid, request.getSession (), allattribute); } catch (throwable e) {// เกิดข้อผิดพลาด, ลบบันทึกข้อมูลแคชข้อผิดพลาด (e.getMessage (), e); แผนที่ <สตริงวัตถุ> allattribute = new hashmap <string, object> (); distsession = ใหม่ distributedhttpsessionWrapper (realsid, request.getSession (), allattribute); DistributedSessionManager.removesession (distsession); } DistributedhttpservletRequestWrapper requestWrapper = ใหม่ DistributedhttpservletRequestWrapper (คำขอ, distsession); return requestwrapper; } // การดำเนินการเซสชั่นโมฆะส่วนตัวข้อตกลง AFTERREQUEST (DistributeDhttpsessionWrapper เซสชัน) {ถ้า (เซสชัน == null) {return; } if (session.changed) {distributedSessionManager.savesession (เซสชัน); } อื่นถ้า (session.invalidated) {distributedSessionManager.removesession (เซสชัน); } else {distributedSessionManager.expire (เซสชัน); -2. DistributedSessionManager ส่วนใหญ่เกี่ยวข้องกับเซสชันกระจายรหัสหลัก:
คลาส DistributedSessionManager {ป้องกันการบันทึกสุดท้าย logger สุดท้าย = loggerFactory.getLogger (DistributedSessionManager.class); แบบคงที่แบบคงที่ส่วนตัวอินสแตนซ์ = null; // Redis จัดการอินเทอร์เฟซเซสชันและดำเนินการส่วนตัว DistributedBaseInterface DistributedBaseInterface; ไบต์คงที่ส่วนตัว [] ล็อค = ไบต์ใหม่ [1]; Private DistributedSessionManager (DistributedBaseInterface DistributedBaseInterface) {this.distributedBaseInterface = DistributedBaseInterface; } สาธารณะแบบคงที่ DistributedSessionManager getInstance (DistributedBaseInterface redis) {ถ้า (อินสแตนซ์ == null) {ซิงโครไนซ์ (ล็อค) {ถ้า (อินสแตนซ์ == null) {อินสแตนซ์ = ใหม่ distributedSessionManager (redis); }}} ส่งคืนอินสแตนซ์; } // รับแผนที่สาธารณะเซสชัน <String, Object> getSession (String SID, int second) {string json = this.distributedBaseInterface.get (sid, วินาที); if (stringutil.isnotblank (json)) {return jsonutil.unserializeMap (JSON); } ส่งคืน hashmap ใหม่ <string, object> (1); } // บันทึกเซสชันโมฆะสาธารณะ savesession (DistributeDhttpsessionWrapper เซสชัน) {แผนที่ <สตริงวัตถุ> map = เซสชัน allattribute; if (maputil.isempty (แผนที่)) {return; } string json = jsonutil.serializeMap (แผนที่); this.distributedBaseInterface.set (session.getId (), json, session.getMaxinactiveInterval ()); } // ลบเซสชันโมฆะสาธารณะลบ (DistributedhttpsessionWrapper เซสชัน) {DistributedBaseInterface.del (session.getId ()); } โมฆะสาธารณะ Expire (DistributeDhttpsessionWrapper) {DistributedBaseInterface.expire (session.getId (), session.getMaxinactiveInterval ()); } /** * สร้าง SID ของคุกกี้ * /สตริงสาธารณะ [] createUsersId (คำขอ httpservletRequest, คีย์สตริง) {// ... } สตริงสาธารณะ getactualsid (สตริงผู้ใช้ usersid, httpservletrequest, คีย์สตริง) {// ... }}}}}}}}}}}}}}3. DistributeDhttpsessionWrapper ใช้ httpsession และดำเนินการบรรจุภัณฑ์เซสชันแบบกระจายรหัสหลัก:
ชั้นเรียนสาธารณะ DistributedhttpsessionWrapper ใช้ httpsession {orgisession ส่วนตัว httpsession; สตริงส่วนตัว SID; บูลีนเปลี่ยน = เท็จ; บูลีนไม่ถูกต้อง = เท็จ; แผนที่ <สตริงวัตถุ> allattribute; Public DistributedhttpsessionWrapper (String SID, เซสชัน httpsession, แผนที่ <สตริง, วัตถุ> allattribute) {this.orgisession = เซสชัน; this.sid = sid; this.allattribute = allattribute; } @Override สตริงสาธารณะ getId () {return this.sid; } @Override โมฆะสาธารณะ setAttribute (ชื่อสตริง, ค่าวัตถุ) {change = true; allattribute.put (ชื่อ, ค่า); } @Override วัตถุสาธารณะ getAttribute (ชื่อสตริง) {return allattribute.get (ชื่อ); } @Override การแจงนับสาธารณะ <String> getAttributeNames () {set <string> set = allattribute.keyset (); Iterator <String> iterator = set.iterator (); ส่งคืน myenumeration ใหม่ <String> (ตัววนซ้ำ); } คลาสส่วนตัว myenumeration <t> ใช้การแจงนับ <t> {iterator <t> iterator; myenumeration สาธารณะ (ตัววนซ้ำ <t> iterator) {super (); this.iterator = iterator; } @Override บูลีนสาธารณะ HasmoreElements () {return iterator.hasnext (); } @Override Public T NextElement () {return iterator.next (); }} @Override โมฆะสาธารณะเป็นโมฆะ () {this.invalidated = true; } @Override โมฆะสาธารณะ RemoveAttribute (ชื่อสตริง) {change = true; allattribute.remove (ชื่อ); } @Override สาธารณะยาว getCreationTime () {return orgisession.getCreationTime (); } @Override สาธารณะยาว getLaScessedTime () {return orgisession.getLastaccessedTime (); } @Override สาธารณะ int getMaxinactiveInterval () {return orgisession.getMaxinactiveInterval (); } @Override สาธารณะ servletContext getServletContext () {return orgisession.getServletContext (); } @Override วัตถุสาธารณะ getValue (String arg0) {return orgisession.getValue (arg0); } @Override สตริงสาธารณะ [] getValuenames () {return orgisession.getValuenames (); } @Override บูลีนสาธารณะ isNew () {return orgisession.isnew (); } @Override โมฆะสาธารณะ putValue (String arg0, Object Arg1) {orgisession.putValue (arg0, arg1); } @Override โมฆะสาธารณะ removeValue (String arg0) {orgisession.removevalue (arg0); } @Override โมฆะสาธารณะ setMaxInactiveInterval (int arg0) {orgisession.setMaxInactiveInterval (Arg0); } @Override สาธารณะ httpsessionContext getSessionContext () {return orgisession.getSessionContext (); -4. DistributeDhttpservletRequestWrapper ใช้ httpservletrequestwrapper ห่อเซสชันที่ประมวลผลและคำขอดั้งเดิมรหัสหลัก:
คลาสสาธารณะ DistributedhttpservletRequestWrapper ขยาย javax.servlet.http.httpservletrequestwrapper {ส่วนตัว httpservletrequest orgirequest; เซสชั่นส่วนตัว DistributedhttpsessionWrapper; สาธารณะ DistributedhttpservletRequestWrapper (คำขอ httpservletRequest, เซสชัน DistributeDhttpsessionWrapper) {super (คำขอ); if (session == null) {// การจัดการข้อยกเว้น - } if (request == null) {// การจัดการข้อยกเว้น - } this.orgirequest = คำขอ; this.session = เซสชัน; } สาธารณะ DistributedhttpsessionWrapper GetSession (Boolean สร้าง) {orgirequest.getSession (สร้าง); เซสชั่นกลับ; } สาธารณะ DistributedhttpsessionWrapper getSession () {return session; -5. นอกจากนี้กำหนดอินเทอร์เฟซ DistributedBaseInterface เพื่อจัดการเซสชันลงใน REDIS สำหรับการดำเนินการต่อเนื่อง:
อินเทอร์เฟซสาธารณะ DistributedBaseInterface { / ** * รับข้อมูลแคชตามคีย์ * @param คีย์ * @param วินาที * / สตริงสาธารณะรับ (คีย์สตริง, วินาทีในวินาที); / ** * อัปเดตข้อมูลแคช * @param คีย์ * @param json * @param วินาที */ ชุดโมฆะสาธารณะ (คีย์สตริง, สตริง JSON, int วินาที); / *** ลบแคช* คีย์ @param*/ โมฆะสาธารณะ del (คีย์สตริง); / ** * ตั้งค่าข้อมูลที่หมดอายุ * @param คีย์ * @param วินาที */ โมฆะสาธารณะ Expire (คีย์สตริง, วินาที int);หมายเหตุ: บทความนี้ใช้วิธี REDIS ในการจัดการเซสชันในฤดูใบไม้ผลิเท่านั้นและมีวิธีการใช้งานอื่น ๆ อีกมากมายเช่นการกำหนดค่าในคอนเทนเนอร์ ฯลฯ และออกแบบอัลกอริทึมการกำหนดเส้นทางเพื่อให้เซสชันพึ่งพาเซิร์ฟเวอร์โหนดต่างๆใน กลุ่ม,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, - - -
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น