For the current site, in order to meet the high availability, high concurrency, high load, a Web server is not enough, the future Web application server should be a clustered environment, they use some tools to synchronize data, when the 1 into multiple servers, there is a problem we have to consider , session mechanism, we all know that the session is used to store the user's credential information, persisted to the server, this security is guaranteed (than the cookie stored in the client), and when your Web application server is more than one (load balancing between multiple), This session mechanism has a problem, because you can not achieve from one server to the other server memory (cache) sharing, which is also unsafe, so, after the advent of the cache middleware, there is a new technology followed, that is, the session middleware, The more mature components are stackexchange.redis+redissessionstateprovider, the session mechanism implemented using Redis, It stores session data on a Redis server (which can be a redis cluster), where data between multiple Web application servers is unique and does not need to be synchronized.
The implementation steps are described below
1 Installing Redis cache Stackexchange.redis with NuGet
2 Installing the Redissession service with NuGet Redissessionstateprovider
3 after adding redissession from NuGet, it writes the following in your config file, mainly the session persistence setting
<sessionstateMode= "Custom"CustomProvider= "Mysessionstatestore"> <providers> <!--either use ' connectionString ' and provide-parameters as String OR use ' host ', ' Port ', ' AccessKey ', ' SSL ', ' connection Timeoutinmilliseconds ' and ' operationtimeoutinmilliseconds '. - <!--' throwOnError ', ' retrytimeoutinmilliseconds ', ' databaseId ' and ' applicationname ' can is used with both options. - <!-- <add name=" Mysessionstatestore "host =" 127.0.0.1 "[String] Port = "" [number] AccessKey = "" [String] SSL = "false" [true|false] throwOnError = " True "[true|false] retrytimeoutinmilliseconds =" [number] DatabaseId = "0" [number] ApplicationName = "" [String] connectiontimeoutinmilliseconds = "OPERATIONTIMEOUTINM" [number] Illiseconds = "$" [number] connectionString = "<valid Stackexchange.redis connection String>" [string] Loggingclassname = "<assembly qualified class name that contains logging method specified below>" [Strin G] Loggingmethodname = "<logging method should is defined in Loggingclass. It should is public, static, does not take any parameters and should has a return type of system.io.textwriter.> "[Str ing]/> - <Addname= "Mysessionstatestore"type= "Microsoft.Web.Redis.RedisSessionStateProvider"Host= "127.0.0.1"AccessKey=""SSL= "false" /> </providers> </sessionstate>
4 download is a new version of the Redis server, can be Windows edition, I use 2.6.13, the lower version of Redis will be the eval command unrecognized problem
5 processing complete, you can test your session, the default expiration time is 1200 seconds
The front desk uses the session without any difference
PublicActionResult testsession () {session["username"] ="Zzl"; session["Test"] ="Hello world!"; returnContent ("finish ..."+ session["Test"]); }
The way that we can implement different functional strategies without modifying the code is our IOC, the control inversion technology (also the category of dependency Injection di), which is the inevitable outcome of the development of programming language to a certain stage, that is, the solution of complex business response!
Below is the user's extension to Rediscache, let it support complex types, default support for simple types, if you want to support complex types, you need to add a "serializable" attribute to the type, because we store in Redis, are stored in the form of binary byte array.
/// <summary> ///extension to Rediscache, allowing it to support complex types,///The redisvalue type can use a byte array directly, so///when you call the Get helper method, it serializes the object into a byte stream and then caches the object. ///when the item is retrieved, the item is re-serialized to the object and then returned to the calling program. /// </summary> Public Static classsamplestackexchangeredisextensions { Public StaticT get<t> ( ThisIdatabase Cache,stringkey) { returnDeserialize<t>(Cache. Stringget (key)); } Public Static ObjectGet ( ThisIdatabase Cache,stringkey) { returndeserialize<Object>(Cache. Stringget (key)); } Public Static voidSet ( ThisIdatabase Cache,stringKeyObjectvalue) {Cache. Stringset (Key, Serialize (value)); } Static byte[] Serialize (Objecto) {if(O = =NULL) { return NULL; } BinaryFormatter BinaryFormatter=NewBinaryFormatter (); using(MemoryStream MemoryStream =NewMemoryStream ()) {binaryformatter.serialize (MemoryStream, O); byte[] Objectdataasstream =Memorystream.toarray (); returnObjectdataasstream; } } StaticT deserialize<t> (byte[] stream) { if(Stream = =NULL) { return default(T); } BinaryFormatter BinaryFormatter=NewBinaryFormatter (); using(MemoryStream MemoryStream =NewMemoryStream (Stream)) {T result=(T) binaryformatter.deserialize (MemoryStream); returnresult; } } }
The methods for storing and reading complex types are as follows
Cache. Set ("zzllist"newnew1" occupied ", Addtime =var o = cache. Get ("zzllist");
Core components of my heart (pluggable AOP) ~ Distributed session Components