Golang using NSQ

Source: Internet
Author: User
Tags system log
This is a creation in Article, where the information may have evolved or changed.

Why to use NSQ

has recently been looking for a high-performance, highly available message queue to do communication between internal services. At first think of using ZEROMQ, but in the process of finding information, accidentally found NSQ this Golang developed message queue, after all, is Golang original things, full-featured, the key is the performance is good. Which support dynamic expansion, eliminate the single point of failure and other characteristics, can be very good to meet my needs

The previous comparison between NSQ and other MQ looks really powerful. Here is a simple record of how NSQ is used


GOLANG2017 Developer Conference

NSQ Service Side

NSQ Service-Side introduction

Before using the NSQ service, it is still necessary to understand several core components of NSQ
The entire NSQ service consists of three main parts

Nsqlookupd

Let's take a look at what the official words say:
NSQLOOKUPD is the daemon responsible for managing topology information. The client discovers the producer of the specified topic (topic) by querying NSQLOOKUPD, and the NSQD node broadcasts the topic (topic) and channel information

Simply put, NSQLOOKUPD is the central management Service, which uses TCP (default port 4160) to manage the NSQD service, using HTTP (the default port 4161) to manage the Nsqadmin service. Also provides query functionality for clients
In general, NSQLOOKUPD has the following features or features

    • Uniqueness, there is only one NSQLOOKUPD service in a NSQ service. It is also possible to deploy multiple nsqlookupd in the cluster, but there is no association between them
    • De-NSQLOOKUPD, even if it crashes, will not affect the running NSQD service
    • Serves as a middleware for NSQD and naqadmin information interactions
    • Provides an HTTP query service to periodically update the NSQD address directory for clients

Nsqadmin

Official quote: A WEB UI that aggregates real-time statistics for a cluster and performs different management tasks

In general, Nsqadmin has the following features or features

    • Provide a unified management of topic and channel operation interface and a variety of real-time monitoring data display, interface design is very simple, easy to operate
    • Show the number of all the message, uh .... Pack x Sharp
    • Be able to create topic and channel in the background, this should not be used to
    • All features of Nsqadmin must rely on nsqlookupd,nsqadmin to simply pass user actions to NSQLOOKUPD and show data from NSQLOOKUPD
      Nsqadmin The default access address is http://127.0.0.1:4171/

Nsqd

Official quote: NSQD is a daemon that is responsible for receiving, queuing, and delivering messages to clients
Simply put, the real work is the service, it is mainly responsible for the message of the transceiver, queue maintenance. NSQD will listen to a TCP port (4150) and an HTTP port (4151) and an optional HTTPS port by default
In general, NSQD has the following features or features

    • For subscribers to the same topic, the same channel consumer uses a load balancing policy (not polling)
    • As long as the channel exists, even consumers without the channel will cache the producer's message in the queue (note the expiration of the message)
    • The message in the queue is guaranteed to be consumed at least once, even if NSQD exits, the messages in the queue are staged on the disk (except for unexpected cases such as ending the process)
    • Limited memory consumption, ability to configure the number of message caches in memory for each channel queue in NSQD, and once exceeded, message will be cached to disk
    • Topic,channel once established, will always exist, in a timely manner in the management station or in code to remove invalid topic and channel, to avoid waste of resources

This is the official figure, the first channel (meteics) because there are multiple consumers, so triggered a load balancing mechanism
After two channel because there is no consumer, all the message will be cached in the corresponding queue until the consumer appears
One problem here is that if a channel is only being delivered by a producer, will it cause server resources to be exhausted? Perhaps the NSQD internally did the corresponding treatment, but to avoid the occurrence of this situation


NSQ Client

Understand the relationship between NSQLOOKUPD,NSQD and consumers and producers in the client

Consumers

Consumers have two ways of connecting with NSQD

    • Consumers directly connected to the NSQD, this is the simplest way, the disadvantage is that the NSQD service can not achieve dynamic scaling (of course, to achieve one is also possible)
    • The consumer obtains the connection address of all NSQD on the NSQLOOKUPD via HTTP query nsqlookupd and then establishes a connection with the NSQD (the official recommended practice), but the client constantly queries the NSQLOOKUPD for the latest NSQD address directory ( Don't like polling this way with http ...)
      Or take a closer look at the chart, the official consumer model:

Producers

Producers must directly connect NSQD to deliver a message (online said, can connect to NSQLOOKUPD, let nsqlookupd automatically choose a nsqd to complete delivery, but I use producer TCP is not even nsqlookupd, I don't know if HTTP can ...),

One problem here is that if the producer is connected to the NSQD, then the message will fail, so the client must implement the corresponding fallback plan.

Installing NSQ

Method One

    • First build the Golang development environment, here is not detailed
      • Note that it is best to add the bin directory to the System environment (PATH) when building the Golang environment, eliminating the hassle of going to the bin directory every time
    • Install Package Manager GODEP
      go get github.com/tools/godep
      After the execution, check whether the GODEP is installed in the bin directory, the general will automatically install, if not, with Go install manual installation under
    • Install Dependency Pack assert
      go get github.com/bmizerany/assert
    • Installing NSQ
      godep get github.com/bitly/nsq/...
      If the installation succeeds, a lot of nsq_ will appear in the Bin directory ... The beginning of the executable file
    • PS: If the installation fails
      • Like me there's a whole bunch of "use of the internal package not allowed" error, looking for half a day to find this sentence in a corner
        Note: NSQ maintains go get compatibility, but is not recommended because it is not guaranteed to still compile.
        At this time the method of two installation

Method Two

    • Go directly to https://github.com/nsqio/nsq/releases download the compiled execution file, copy the executable file inside the bin directory to use the

Run NSQ

Running a standalone NSQD service

NSQD is a standalone service that starts a NSQD to send and receive a message
Start a single-machine nsqd, very simple

nsqd

The client can use HTTP, or TCP, where I use the official GO-NSQ package as the client, using TCP to send and receive message

    • Send


    • Receive


Running the NSQ service cluster

    • Start Nsqlookud First
      nsqlookupd
    • Start Nsqd and access the Nsqlookud that just started. Here, to facilitate the next test, two Nsqd are launched.
      nsqd --lookupd-tcp-address=127.0.0.1:4160
      nsqd --lookupd-tcp-address=127.0.0.1:4160 -tcp-address=0.0.0.0:4152 -http-address=0.0.0.0:4153
    • Start Nqsadmin
      nsqd --lookupd-http-address=127.0.0.1:4161

GO-NSQ-based client implementation

A few notable places

    • Producer will not be re-connected after disconnection, you need to manually re-connect, consumer disconnection will automatically re-connect
    • Consumer's re-connect time configuration item has two functions (this design must be spit out, a bit better separately)
      • Consumer detects that a connection to the NSQD has been broken, and every x seconds to the NSQD request to reconnect
      • Consumer every x seconds, HTTP polling to Nsqlookud to update their NSQD address directory
      • The consumer time of the default is 60s (...). The dishes are cold), I changed to 1s
    • Consumer can receive the same name topic data from different NSQD node at the same time, in order to avoid confusion, it must be processed on the client
    • The interface callbacks set in Addconurrenthandlers and AddHandler are performed in a different goroutine
    • Producer cannot publish (Publish) empty message, otherwise it will cause panic

Go_nsq-send.go

 //nsq send the Test package mainimport ("Bufio" "FMT" "GITHUB.COM/NSQIO/GO-NSQ" "Os") var producer *nsq. producer//Main function func main () {strIP1: = "127.0.0.1:4150" strIP2: = "127.0.0.1:4152" Initproducer (strIP1) Running: = TRUE//Read Take console input Reader: = Bufio. Newreader (OS. Stdin) for running {data, _, _: = Reader. ReadLine () Command: = string (data) if command = = "Stop" {running = false} for err: = Publish ("Test", command); Err! = Nil; Err = Publish ("Test", command) {//Toggle IP re-connect strIP1, strIP2 = strIP2, strIP1 initproducer (strIP1)}}}//Initialize producer Func Initprodu CER (str string) {var err error FMT. PRINTLN ("Address:", str) producer, err = nsq. Newproducer (str, NSQ. Newconfig ()) if err! = Nil {panic (err)}}//Post message func Publish (topic string, message String) error {var err error if Produc Er! = Nil {if message = = "" {//cannot publish empty string, otherwise it will cause error return nil} err = producer. Publish (topic, []byte (message))//Publish message Return ERR} return FMT. Errorf ("Producer is nil", err)}  

Go_nsq-receive.go

//nsq Receive test Package Mainimport ("FMT" "Time" "github.com/nsqio/go-nsq")//consumer type Consumert struct{}// The main function, Func, main () {Initconsumer ("test", "Test-channel", "127.0.0.1:4161") for {time. Sleep (time. Second * 10)}}//handles message func (*consumert) handlemessage (msg *nsq. Message) Error {FMT. PRINTLN ("Receive", MSG. Nsqdaddress, "Message:", String (Msg. Body)) return nil}//Initialize consumer func initconsumer (topic string, channel string, address string) {cfg: = nsq. Newconfig () cfg. Lookupdpollinterval = time. Second//Set re-connect time c, err: = nsq. Newconsumer (topic, Channel, CFG)//New consumer if err! = Nil {panic (err)} c.setlogger (nil, 0)//Masking system log c.addhandler ( &consumert{})//Add consumer interface//Establish NSQLOOKUPD connection If err: = C.CONNECTTONSQLOOKUPD (address); Err! = Nil {panic (ERR)}//Establish multiple NSQD connections//If ERR: = C.connecttonsqds ([]string{"127.0.0.1:4150", "127.0.0.1:4152"}); Err! = Nil {//Panic (ERR)//}//Establish a NSQD connection//If Err: = C.connecttonsqd ("127.0.0.1:4150"); Err! = Nil {//Panic (ERR)//}}  
Related Article

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.