Session sessions in a single server will not share the problem, now the application deployment is distributed, or cluster deployment, so it is inevitable to face a problem,session sharing .
There are also a lot of solutions shared by the session,
Web server sticky requests, such as the use of Nginx request distribution, using Ip_hash load Balancing method, the client request will only be distributed to the same background server, so as to avoid session sharing problems. But the flaws are obvious.
Second, based on database storage (large site users, frequent DML data, high pressure on the db)
Third, cookie-based storage (security issues, although can be encrypted storage, but I feel that the sensitive data will never be placed on the client, do not trust ah O (∩_∩) o haha ~)
Four, the server built-in session replication domain (such as was provided under the session copy function, but this loss of server memory)
Five, based on NoSQL (Memcache, Redis can)
The HTTP request is stateless
To introduce a concept SessionID, thesession object creates a new session object when the client first accesses it. and generate a SessionID at the same time, And in this response, SessionID in response to the message back to the client browser memory or to rewrite the URL to send back to the client, to maintain the entire session
In other words, when the client requests the request, if the session is obtained, it assigns a jessionid by default, then responds to the client cookie through response, and then the client next request, by default, carries the Jessionid request to the server. The server gets this jessionid to differentiate between clients.
Clear these, you can start from the SessionID, to achieve the session information into Redis, summed up the next is about three points:
1. Implement the HttpSession interface and rewrite the methods we need to use, such as set get. Balabala a bunch of ...
2. Inherit Httpservletrequestwrapper, this class has the GetSession () method, we need to rewrite, to take the definition session
3. Implement filter to intercept client requests, get our custom request, and get session
Specific implementation:
1. Implement the HttpSession interface
public class Httpsessionwrapper implements HttpSession {protected final Logger Logger = Loggerfactory.getlogger (getcla SS ()));p rivate String sid = ";p rivate httpservletrequest request;private httpservletresponse response;private final Long CreationTime = System.currenttimemillis ();p rivate final Long lastaccessedtime = System.currenttimemillis ();p rivate Sessionmeta meta;public Httpsessionwrapper () {} public httpsessionwrapper (String Sid,sessionmeta Meta, httpservletrequ EST request,httpservletresponse response) {this.sid=sid; This.request=request; This.response=response; This.meta=meta;} Public Object getattribute (String name) {Logger.info (GetClass () + "getattribute (), Name:" +name); Jedis Jedis =null; Object obj =null; String jsonstr = null; try {Jedis =jedispoolstore.getinstance (). Getjedis (Meta.gethost (), Meta.getport ()); Jsonstr = Jedis.get (name); if (jsonstr!=null| | Stringutils.isnotempty (JSONSTR)) {Jedis.expire (name, Meta.getseconds ());Reset Expiration Time obj =json.parseobject (jsonstr, User.class); Anti-Sequence Object} if (Jedis! = null) {jedispoolstore.getinstance (). Returnjedis (Jedis); } return obj; catch (jsonexception je) {logger.error (Je.getmessage ()); if (null! = Jedis) jedispoolstore.getinstance (). Returnjedis ( Jedis); return JSONSTR;} catch (Exception e) {logger.error (E.getmessage ()); if (e instanceof jedisexception) {if (null! = Jedis) Jedispoolstore.getinstance (). Returnbrokenjedis (Jedis);} else {if (null! = Jedis) jedispoolstore.getinstance (). Returnjedis (Jedis);} throw new Httpsessionexception ("Session exception GetAttribute () name:" +name);}} public void SetAttribute (String name, Object value) {Logger.info (GetClass () + "SetAttribute (), Name:" +name); Jedis Jedis =null; try {Jedis =jedispoolstore.getinstance (). Getjedis (Meta.gethost (), Meta.getport ()); if (value instanceof string) {string value_ = (string) value; Jedis.set (Name,value_);//Ordinary String Object}else{Jedis.set (name,Json.tojsonstring (value));//Serialize Object} jedis.expire (name, Meta.getseconds ());//Reset Expiration time if (Jedis! = null ) {jedispoolstore.getinstance (). Returnjedis (Jedis); }} catch (Exception e) {logger.error (E.getmessage ()); if (e instanceof jedisexception) {if (null! = Jedis) jedispoolstore.g Etinstance (). Returnbrokenjedis (Jedis);} else {if (null! = Jedis) jedispoolstore.getinstance (). Returnjedis (Jedis);} throw new Httpsessionexception ("Session exception SetAttribute () Name:" +name+ ", Value:" +value);}} /** * Not Available * @deprecated * */public void invalidate () {Logger.info (GetClass () + "invalidate ()"); } public void RemoveAttribute (String name) {Logger.info (GetClass () + "RemoveAttribute (), Name:" +name); if (stringutils.isnotempty (name)) {Jedis Jedis =null; try {Jedis =jedispoolstore.getinstance (). Getjedis (Meta.gethost (), Meta.getport ()); Jedis.del (name); if (Jedis! = null) {jedispoolstore.getinstance ().Returnjedis (Jedis); }} catch (Exception e) {logger.error (E.getmessage ()); if (e instanceof jedisexception) {if (null! = Jedis) jedispoolstore.getinstance (). Returnbrokenjedis (Jedis); } else {if (null! = Jedis) jedispoolstore.getinstance (). Returnjedis (Jedis); } throw new Httpsessionexception ("Session exception RemoveAttribute () name:" +name); }}}/** * Not available * @deprecated * */Public Object GetValue (String name) {return Nu ll }/** * Not available * @deprecated * */Public enumeration Getattributenames () {return null; }/** * Not available * @deprecated * */public string[] GetValueNames () {return null; }/** * Not available * @deprecated * */public void Putvalue (String name, Object value) {}/** * Not available * @deprecated * */public void RemoveValue (String name) {} public long GetCreationTime () {R Eturn CreationTime; } public String GetId () {Logger.info (GetClass () + "getId ():" +sid); return SID; } public Long Getlastaccessedtime () {return lastaccessedtime; }/** * Not available * @deprecated * */Public ServletContext Getservletcontext () {return null; }/** * Not available * @deprecated * */public void setmaxinactiveinterval (int interval) {}/** * Not available * @deprecated * */public int getmaxinactiveinterval () {return 0; }/** * Not available * @deprecated * */Public Httpsessioncontext Getsessioncontext () {return null; }/** * Not available * @deprecated * * */public Boolean isnew () {Logger.info (GetClass () + "isnew ()"); return false; }}
2. Inheriting Httpservletrequestwrapper
/*** * * @author Xiaoshuai * */public class Definedhttpservletrequestwrapper extends httpservletrequestwrapper{Protec Ted Final Logger Logger = Loggerfactory.getlogger (GetClass ()); Private Httpsessionwrapper currentsession; private HttpServletRequest request; Private HttpServletResponse response; Private String sid = "";p rivate sessionmeta meta; Public Definedhttpservletrequestwrapper (HttpServletRequest request) {super (request); } public Definedhttpservletrequestwrapper (String SID, HttpServletRequest request) {super (request); This.sid = SID; Public Definedhttpservletrequestwrapper (String SID, Sessionmeta meta,httpservletrequest request, HTTPSERVL Etresponse response) {super (request); This.request = Request; This.response = response; This.sid = SID; This.meta=meta; } @Override Public HttpSession getsession (Boolean Create) {if (currentsession! = null) {return Currentsession; } if (!create) {return null; } currentsession = new Httpsessionwrapper (Sid,meta, request, response); return currentsession; } @Override Public HttpSession getsession () {return getsession (true); } }
3. Implement the filter
public class Sessionfilter implements filter{protected final Logger Logger = Loggerfactory.getlogger (GetClass ()); private static Sessionmeta meta = new Sessionmeta ();p rivate static final String host = "Host";p rivate static final string p ORT = "Port";p rivate static final String seconds= "seconds";p ublic void init (Filterconfig filterconfig) throws servletexception {logger.debug ("init filterconfig info"); Meta.sethost (Filterconfig.getinitparameter (host)); Meta.setport (Integer.parseint (Filterconfig.getinitparameter (port)); Meta.setseconds (Integer.parseint ( Filterconfig.getinitparameter (seconds)));} public void DoFilter (ServletRequest request, Servletresponse Response,filterchain chain) throws IOException, servletexception {//Get SessionID from the cookie, if this request is not SessionID, override to set a sessionidhttpservletrequest HttpRequest = for this request ( HttpServletRequest) Request; HttpServletResponse HttpResponse = (httpservletresponse) response; String sid = Cookiehelper.findcookieinfo (httprequest,cookiehelper.cookie_domain_naME); if (Stringutils.isempty (SID)) {try {sid =cookiehelper.savecookie (Sessionid.doids (), HttpResponse);} catch ( Exception e) {e.printstacktrace ();} } logger.info ("Jessionid:" +sid); Chain.dofilter (New Definedhttpservletrequestwrapper (Sid,meta,httprequest, HttpResponse), response);} public void Destroy () {}}
3. Configure Web. xml
<!--session Filter--><filter><filter-name>sessionfilter</filter-name><filter-class> Cn.session.filter.sessionfilter</filter-class><init-param><param-name>host</param-name ><param-value>10.1.193.1</param-value></init-param><init-param><param-name> port</param-name><param-value>6372</param-value></init-param><init-param>< param-name>seconds</param-name><param-value>1800</param-value></init-param></ filter><filter-mapping><filter-name>sessionfilter</filter-name><url-pattern>/*</ Url-pattern></filter-mapping>
First time generating SessionID access:
After the system logs in, save the user information to Redis:
About the security of this piece, because regardless of login system or not, SessionID will produce, this time will produce a problem, because the cookie can be modified, will produce a problem, hit the session to share ... Change to different SessionID to request the system ... One day it will hit.
So, that's what I'm dealing with here,
When the login is successful, a token token is generated, the rule is generated, a bunch of keys such as the system name +sessionid+userid+ fixed characters, generates an encrypted string, and puts in a cookie.
So when we get the current logged in user, decrypt token, get SessionID, and then take Redis user information. (remember here do not directly through the SessionID to take user information, there is a risk!!! )
The user does not log in successfully, and naturally does not have this token ...
Here is another problem, if users disable cookies????? So what ..... Next time you say this ...
The level is limited, if you have a better way, please contact me, exchange ..... ..... ............ tks!!!!
Session management for distributed applications-based on Redis