Performance, availability, scalability, scalability, security, and monitoring are some of the core elements of the site architecture

Source: Internet
Author: User
Tags message queue

Recently need to use Redis in C #, found on the Redis official website Servicestack.redis, finally in the test found that this is a pit, 4.0 has been charged, the latter had to find the final version of the 3 series, the final test found that there is still a bug or I will not use. There is no way, it is best to find the Stackexchange.redis, support asynchronous client, it is said that performance is better than Servicestack.redis, and it is said that the stack overflow is also used by this client, There are support 4.0 and 4.5 of the version, now I am in the use of the package class to provide you with reference (refer to some information on the Internet):

    Using DotNet.Log; <summary>///Stackexchangeredishelper The most important object in Stackexchange.redis is the Connectionmultiplexer class, which exists    In the Stackexchange.redis namespace.    This class hides the operation details of the Redis service, and the Connectionmultiplexer class does a lot of things, which are designed to be shared and reused across all calls. You should not create a connectionmultiplexer for each operation.    Connectionmultiplexer is thread-safe, it is recommended to use the following method. In all subsequent examples, it is assumed that you have instantiated a connectionmultiplexer class and that it will always be reused,///Now let's create a connectionmultiplexer instance. It is passed a connection string or a configurationoptions through Connectionmultiplexer.connect or Connectionmultiplexer.connectasync.    object to create the.    The connection string can be a node of multiple services separated by commas.     /////Connectionmultiplexer implementation of the IDisposable interface when we no longer need to be able to release it, here I deliberately do not use using to release him.    Simply speaking, creating a connectionmultiplexer is very expensive, and a good idea is that we always reuse a Connectionmultiplexer object. A complex scenario may contain a master-slave copy, in which case all addresses need to be specified in the connection string (it will automatically identify the primary server)//connectionmultiplexer Redis = connectionmultiplexer .    Connect ("server1:6379,server2:6379"); Assuming two primary servers are found here, two services will be ruled out and one is chosen as the primary server to solveThis is a very rare situation, and we should avoid it. ///There is a difference between the Servicestack.redis and the big one is that there is no default connection pool management. There is no connection pool naturally has its pros and cons, the greatest benefit is that waiting time to obtain the connection is not,///or because the connection pool inside the connection due to the lack of proper release and other reasons caused by infinite wait for the deadlock state. The downside is that some low-quality code can cause server resources to run out. However, the means to provide blocking and waiting for connection pooling are contrary to the author's design philosophy. Stackexchange.redis the use of pipelines and multiplexing techniques to achieve reduced connections//////reference: http://www.cnblogs.com/Leo_wl/p/4968537.html////    ///////2016.04.07 Version: 1.0 Songbiao primary key creation. <author>//<name>SongBiao</name>/<date>2016.04.07< /date>//</author>//</summary> public static class Stackexchangeredishelper {Priva Te static readonly string coonstr = configurationmanager.connectionstrings["Redisexchangehosts"].        ConnectionString;        private static Object _locker = new Object ();        private static connectionmultiplexer _instance = null; <summary>/////Use a static property to return a connected instance, as shown in the following. This allows the new connection to be initialized once the connectionmultiplexer is disconnectedInstance.                </summary> public static connectionmultiplexer Instance {get { if (_instance = = null) {lock (_locker) {i F (_instance = = NULL | |!_instance.                        isconnected) {_instance = Connectionmultiplexer.connect (COONSTR); }}}//Register the following event _instance.                connectionfailed + = muxerconnectionfailed; _instance.                Connectionrestored + = muxerconnectionrestored; _instance.                ErrorMessage + = Muxererrormessage; _instance.                Configurationchanged + = muxerconfigurationchanged; _instance.                Hashslotmoved + = muxerhashslotmoved; _instance.                Internalerror + = Muxerinternalerror;            return _instance;  }} static Stackexchangeredishelper () {      }//<summary>///</summary>//<returns></returns>        public static Idatabase Getdatabase () {return instance.getdatabase ();        }///<summary>///Here MergeKey is used to splice the Key prefixes, and different business modules use different prefixes. </summary>//<param name= "key" ></param>//<returns></returns> P        Rivate static string MergeKey (String key) {return basesysteminfo.systemcode + key; }///<summary>///For cache objects based on key///</summary>//<typeparam name= "T" ></ typeparam>//<param name= "key" ></param>///<returns></returns> public s            Tatic T get<t> (string key) {key = MergeKey (key); Return deserialize<t> (Getdatabase ().        Stringget (key)); }///<summary>///For cache objects based on key// </summary>//<param name= "key" ></param>//<returns></returns> Publ            IC Static Object Get (string key) {key = MergeKey (key); Return deserialize<object> (Getdatabase ().        Stringget (key));         }///<summary>//Set cache///</summary>//<param name= "key" ></param>            <param name= "value" ></param> public static void Set (string key, object value) {            Key = MergeKey (key); Getdatabase ().        Stringset (Key, Serialize (value)); }///<summary>///To determine if there is cache data for the key in the cache///</summary>//<param name= "key"            ;</param>//<returns></returns> public static bool Exists (string key) {            Key = MergeKey (key); Return Getdatabase ().  Keyexists (key);   can be called directly}///<summary>//Remove the cache of the specified key     </summary>//<param name= "key" ></param>//<returns></returns>            public static bool Remove (string key) {key = MergeKey (key); Return Getdatabase ().        Keydelete (key);         }//<summary>///asynchronous Setup///</summary>//<param name= "key" ></param>        <param name= "value" ></param> public static async Task Setasync (string key, Object value)            {key = MergeKey (key); Await Getdatabase ().        Stringsetasync (Key, Serialize (value)); }///<summary>///For cache objects based on key///</summary>//<param name= "key" ></pa        ram>//<returns></returns> public static async task<object> Getasync (string key)            {key = MergeKey (key); Object value = Await getdatabase ().            Stringgetasync (key);        return value;}///<summary>////</summary>//<param name= "key" ></param> <returns></returns> public static long Increment (string key) {key = Merg            EKey (key);            Three command modes//sync, synchronous mode blocks the caller directly, but obviously does not block other threads.            Async, the asynchronous pattern goes directly to the task model.            Fire-and-forget, is to send a command, and then completely do not care when the final time to complete the command operation. Instant Discard: By configuring the Commandflags to implement the Discard function, the method returns immediately if it is a string and returns null if it is an int 0. This operation will continue to run in the background, a typical usage page counter implementation: RET Urn Getdatabase ().        Stringincrement (key, Flags:CommandFlags.FireAndForget);         }///<summary>//to Decrement///</summary>//<param name= "key" ></param> <param name= "value" ></param>///<returns></returns> public static long            Decrement (string key, String value) {key = MergeKey (key); Return Getdatabase (). Hashdecrement (kEY, value, flags:CommandFlags.FireAndForget);        }///<summary>//Serialization objects///</summary>//<param name= "O" ></param>            <returns></returns> Static byte[] Serialize (object o) {if (o = = null)            {return null;            } BinaryFormatter BinaryFormatter = new BinaryFormatter ();  using (MemoryStream MemoryStream = new MemoryStream ()) {binaryformatter.serialize (MemoryStream,                O);                byte[] Objectdataasstream = Memorystream.toarray ();            return objectdataasstream; }}///<summary>//Deserialization object///</summary>//<typeparam name= "T" >& lt;/typeparam>//<param name= "stream" ></param>///<returns></returns> S Tatic T deserialize<t> (byte[] stream) {if (stream = = nulL) {return default (T);            } BinaryFormatter BinaryFormatter = new BinaryFormatter (); using (MemoryStream MemoryStream = new MemoryStream (stream)) {T result = (t) binaryformatter.des                Erialize (MemoryStream);            return result; }}////<summary>////</summary>//<param name= "Sender" >& lt;/param>//<param name= "E" ></param> private static void Muxerconfigurationchanged (object        sender, Endpointeventargs e) {loghelper.writeinfolog ("Configuration changed:" + E.endpoint); }///<summary>/////</summary>//<param name= "sender" in case of an error ></param >//<param name= "E" ></param> private static void Muxererrormessage (object sender, Rediserro Reventargs e) {loghelper.writeinfolog ("ErrorMessage: "+ e.message); }///<summary>//re-establish the error before the connection///</summary>//<param name= "Sender" >< /param>//<param name= "E" ></param> private static void Muxerconnectionrestored (Object Sende        R, Connectionfailedeventargs e) {loghelper.writeinfolog ("connectionrestored:" + e.endpoint); }///<summary>///Connection failed and you will not receive this notification if the reconnection is successful///</summary>//<param name= "s Ender "></param>//<param name=" E "></param> private static void muxerconnectionfailed ( Object sender, Connectionfailedeventargs e) {loghelper.writeinfolog ("Reconnect: Endpoint failed:" + e.endpoi        NT + "," + E.failuretype + (e.exception = = null? "": ("," + e.exception.message)); }//<summary>//Change the cluster///</summary>//<param name= "Sender" ></param&        Gt <paRam Name= "E" ></param> private static void Muxerhashslotmoved (object sender, Hashslotmovedeventargs e)        {Loghelper.writeinfolog ("Hashslotmoved:newendpoint" + E.newendpoint + ", oldendpoint" + e.oldendpoint); }///<summary>//Redis class Library error///</summary>//<param name= "Sender" >&  lt;/param>//<param name= "E" ></param> private static void Muxerinternalerror (object sender,        Internalerroreventargs e) {loghelper.writeinfolog ("internalerror:message" + e.exception.message);        }//Scene is different, the mode of selection will be different, you can follow your own system architecture reasonable choice of long connection or lazy. After the connection is established, a reference to the Redis Cache database is returned by calling the Connectionmultiplexer.getdatabase method.        The object returned from the Getdatabase method is a lightweight pass-through object that does not need to be stored.        <summary>///Use lazy to create a connection when the connection is really needed. Deferred loading technology//Configuration connection template in Microsoft Azure///</summary>//private static LAZY&LT;CONNECTIONMULTIPLEXER&G T Lazyconnection = NEW lazy<connectionmultiplexer> (() =//{////var options = Configurationoptions.parse (CONSTR); Options. ClientName = Getappname (); Only known at runtime////options.        Allowadmin = true;        return Connectionmultiplexer.connect (options);        Connectionmultiplexer muxer = Connectionmultiplexer.connect (COONSTR); Muxer.        connectionfailed + = muxerconnectionfailed; Muxer.        Connectionrestored + = muxerconnectionrestored; Muxer.        ErrorMessage + = Muxererrormessage; Muxer.        Configurationchanged + = muxerconfigurationchanged; Muxer.        Hashslotmoved + = muxerhashslotmoved; Muxer.        Internalerror + = Muxerinternalerror;        return muxer;        //}); #region as a message broker middleware that uses a more specialized message queue to handle this business scenario//<summary>////or message building as a message broker middleware, the important concept is that producers,        Consumer, message middleware. </summary>//<param name= "channel" ></param>//<param name= "message" ></param>///<returns></returns> public s            Tatic long Publish (string channel, String message) {Isubscriber sub = Instance.getsubscriber (); Return Sub.            Publish ("Messages", "Hello"); Return Sub.        Publish (channel, message); }///<summary>//For the consumer to receive the message and output///</summary>//<param name= "Channelfrom" &        gt;</param>//<returns></returns> public static void Subscribe (String channelfrom)            {Isubscriber sub = Instance.getsubscriber (); Sub.            Subscribe (Channelfrom, (channel, message) = {Console.WriteLine (string) message);        }); } #endregion///<summary>///Getserver method receives a endpoint class or a unique key-value pair that uniquely identifies a server///sometimes needs to be a single service The iserver can use all of the shell commands, for example:///DateTime Lastsave =Server.        Lastsave (); clientinfo[] Clients = server.        Clientlist ();        If the error is added after the connection string, allowadmin=true; </summary>//<returns></returns> public static IServer Getserver (string host, int PO            RT) {IServer Server = Instance.getserver (host, Port);        return server;        }//<summary>//Get all endpoints///</summary>//<returns></returns>            public static endpoint[] Getendpoints () {endpoint[] endpoints = instance.getendpoints ();        return endpoints; }    }}

Performance, availability, scalability, scalability, security, and monitoring are some of the most important elements of the site architecture

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.