"Go" uses Redis's pub/sub to implement JMS-like message persistence

Source: Internet
Author: User
Tags message queue stub

http://blog.csdn.net/canot/article/details/52040415

About the individual's understanding of the pub/sub mechanism provided by Redis in the previous blog, it also mentions the idea of how to avoid one of the biggest flaws in Redis's pub/sub-The Persistence of messages (http://blog.csdn.net/canot/ article/details/51975566). This article is primarily about the code implementation of its ideas (Redis's pub/sub message persistence):

The implementation of the most core listener in the PUB/SUB mechanism:

Import Redis.clients.jedis.Jedis;Import Redis.clients.jedis.JedisPubSub;Import Redis.clients.util.RedisInputStream;PublicClassPubsublistenerExtendsjedispubsub {Private String clientId;Private Handlerredis Handlerredis;An ID must be created when generating the PubsublistenerPublicPubsublistener (String cliendid, Jedis Jedis) {This.clientid = Cliendid; Jedis.auth ("XXXX"); Handlerredis =New Handlerredis (Jedis); }@OverridePublicvoidOnMessage (String channel, String message) {if ("Quit". Equals (message)) {This.unsubscribe (channel); } handlerredis.handler (channel, message); }Really deal with the place of acceptancePrivatevoidMessage (string channel, String message) {SYSTEM.OUT.PRINTLN ("Message receive:" + Message +", Channel:" + Channel +"..."); }@OverridePublicvoidOnpmessage (string pattern, string channel, String message) {TODO auto-generated Method Stub}@OverridePublicvoidOnsubscribe (String Channel,int subscribedchannels) {Save subscribers in a "subscription active collection" Handlerredis.subscribe (channel); System.out.println ("Subscribe:" + channel);@OverridePublicvoidOnunsubscribe (String Channel,int subscribedchannels) {handlerredis.ubsubscribe (channel); System.out.println ("Unsubscribe:" + channel);@OverridePublicvoidOnpunsubscribe (String pattern,int subscribedchannels) {TODO auto-generated Method Stub}@OverridePublicvoidOnpsubscribe (String pattern,int subscribedchannels) {TODO auto-generated Method Stub} class Handlerredis {Private Jedis Jedis;PublicHandlerredis (Jedis Jedis) {This.jedis = Jedis; }PublicvoidHandler (string channel, String message) {int index = Message.indexof ("/");if (Index <0) {Message not valid, discardReturn } Long Txid = long.valueof (message.substring (0, index)); String key = ClientId +"/" + channel;while (true) {String LM = Jedis.lindex (Key,0);Get the first messageif (lm = =NULL) {Break }int li = Lm.indexof ("/");If the message is not valid, delete and processif (Li <0) {String result = Jedis.lpop (key);Delete current Messageis emptyif (result = =NULL) {Break } message (channel, LM);Continue } Long Lxid = long.valueof (lm.substring (0, Li));Get the Txid of a messageResidual messages before direct consumption of TXIDif (Txid >= lxid) {jedis.lpop (key);Deletes the current message message (channel, LM);Continue }else {Break } } }Persistent subscription operationsPublicvoid Subscribe (string channel) { //ensures that the format in the Subscriber collection is a unique identifier/subscribed channel String key = ClientId + "/" + channel; //Determine if the client exists in the collection in boolean isexist = Jedis.sismember ("persis_sub", key); if (!isexist) { //does not exist add Jedis.sadd ("persis_sub", Key);}} public void ubsubscribe (String channel) {string key = ClientId + "/" + channel; //Jedis.srem ("persis_sub", key) from the "Active Subscribers" collection; //delete "subscriber Message queue" Jedis.del (channel);} }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21st
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125

An inner class Handlerredis is defined in listener. The Listener class delivers onmessage and Onsubscribe two methods to Handlerredis. Handler handles this method in the same way that the queue is maintained. A message () method is defined in the Listener class, which is the handler callback method, where the message is actually processed.

The subscription client class for the channel:

import Redis.clients.jedis.jedis;public class subclient {private Jedis   Jedis;   private Pubsublistener listener; public subclient (String host,pubsublistener PubSubListener) { Jedis = new Jedis (host), Jedis.auth ( "XXXXX"); this.listener = Pubsublistener; } public void sub (String channel) { Jedis.subscribe (listener, channel); } public void unsubscribe (String Channel) {listener.unsubscribe (channel);}}            
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22

The channel's message is published by the client:

Import Java.util.Set;Import Redis.clients.jedis.Jedis;PublicClasspubclient {Private Jedis Jedis;PublicPubclient (String host) {Jedis =New Jedis (host); Jedis.auth ("wx950709"); }/** * Every message that is published needs to be persisted in subscriber Message Queuing * *@param message * *PublicvoidPut (String message) {Get all active message receiver clients clientid/channel set<string> subclients = jedis.smembers ("Persis_sub");for (String subs:subclients) {//saves each client's message Jedis.rpush (Subs, message); }} public void publish (String Channel, String message) {//each message has a globally unique ID // Txid to prevent the subscriber from "disorderly ordering" during data processing, this requires the subscriber to parse the MESSAGE Long Txid = jedis.incr ( "Message_txid"); String content = Txid +  "/" + message; this.put (content); Jedis.publish (channel, content); //set ID for each message, final message format 1000/messagecontent} public void close (String channel) { Jedis.publish (channel,                
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

To test the boot class:

Import Redis.clients.jedis.Jedis;PublicClassMain {PublicStaticvoidMain (string[] args)Throws exception{pubclient pubclient =New Pubclient ("127.0.0.1");Final String channel ="Pubsub-channel222"; Pubsublistener listener =New Pubsublistener ("Client_one",new Jedis ( "127.0.0.1")); Subclient subclient = new subclient ( "127.0.0.1", listener); Thread T1 = new Thread (new Runnable () { @Override public void run () {//at the API level, this is a polling operation and will not return unsubscribe until Subclient.sub is called ( Channel); } }); T1.setdaemon (true); T1.start (); int i = 0; while (i < 2) {Pubclient.publish (channel, " "Message" +i); i++; Thread.Sleep (1000);}}           
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

"Go" uses Redis's pub/sub to implement JMS-like message persistence

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.