This is a creation in Article, where the information may have evolved or changed.
Starting with this section, you will step through the code for each of the NSQ modules.
Read a code, my idea is generally:
1, understand the usage, know how to use, to understand the code has a great help on the macro. As the first article: Go language nsq Source Interpretation-Basic introduction.
2, understand the major modules of the functional characteristics, and think again, if you let yourself to achieve these modules, will be how the idea. As the second article: Go language nsq Source interpretation two nsqlookupd, NSQD and Nsqadmin
3, start to get started probation, in order not to combat the enthusiasm of reading, you can choose a simple module, or a function point to start reading. For NSQ, open source directory to look at, found that nsqlookupd and Nsqadmin code is relatively small, and nsqd more code. Compare nsqlookupd and Nsqadmin, found nsqadmin under a templates directory, which is probably in the first article to display the page in the template file. Taking into account the central role of NSQLOOKUPD, I decided to start reading from the NSQLOOKUPD code.
4, read the first pass of the code, biased to read, understand the implementation of the function can be. After all the code has been read over and over, take a look at the filename to see what the code in the file implements. If you do not understand, you can add annotations to output variables, interrupt point tracking and other ways to assist learning.
5, after reading the second time, understand the macro structure of the system, the heart always want to think of the question is: Why do you want to do so? If it was me, what would I do? What are the pros and cons of these two practices? Think more, read carefully, and bring to mind the essence of what you have learned.
6, then, you can read the third time, this is basically the realm of dispel, the code, such as the palm, consider whether there is a better implementation, and then the code can be modified. If the code is not read before the code, it belongs to Snow White to feed excrement, disgusting dying.
All right, here's the crap. A book on the Go language for the University: Go WEB programming, Chinese writing, a clear hierarchy of content, comprehensive knowledge, suitable for introductory reading.
Below we begin to nsqlookupd the source code interpretation.
The code for NSQLOOKUPD is located under Nsqlookupd of the source root directory. A total of 11 files, removing the readme.md file and two files ending with _test.go (this is the unit test file), a total of eight files. In addition, NSQLOOKUPD will also use some of the function code in the Util directory, which will also be read. The explanation of the code I will put in the comments, and so the first time the code is read, I will pack all the code to pass.
OK, start with the Nsqlookupd\nsqlookupd.go file first:
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
|
Package NSQLOOKUPD
Import( "Log" "NET"
"Github.com/bitly/nsq/util" )
Type NSQLOOKUPD struct{ //defined in file Nsqlookupd\options.go, records NSQLOOKUPD configuration information Options*Nsqlookupdoptions
//NSQLOOKUPD listening for the address of the TCP data Tcpaddr*Net.Tcpaddr
//nsqlookupd listening for HTTP data addresses Httpaddr*Net.Tcpaddr
//Use the above tcpaddr to establish the listener TcpListener Net.Listener
//Use the above httpaddr to establish the listener HttpListener Net.Listener
//defined in the Util\wait_group_wrapper.go file, with sync. Waitgroup related, for thread synchronization. Waitgroup util.Waitgroupwrapper
//defined in the Nsqlookupd\registration_db.go file, read the literal meaning of db to know that this involves data access Db*RegistrationDB } // //Create an instance of NSQLOOKUPD based on the configured nsqlookupdoptions // Func newnsqlookupd(Options*Nsqlookupdoptions) *Nsqlookupd{
//Use tcpaddress of configuration parameters to create a TCP address for communication with NSQD. Tcpaddr,Err:=Net.Resolvetcpaddr("TCP",Options.Tcpaddress) ifErr!=Nil{ Log.Fatal(Err) }
//Use the httpaddress parameter of the configuration parameter to create an HTTP link that can be accessed by nsqadmin to read the statistics Httpaddr,Err:=Net.Resolvetcpaddr("TCP",Options.Httpaddress) ifErr!=Nil{ Log.Fatal(Err) }
return &Amp;Nsqlookupd{ Options:Options, Tcpaddr:Tcpaddr, Httpaddr:Httpaddr, Db:Newregistrationdb(), } }
// //main function, which executes this function first at startup //Note: When reading options.go, it is not the main method that first runs when NSQLOOKUPD is started. But the main method in Apps\nsqlookupd\nsqlookupd.go, which is mentioned in the next article. // Func(L*Nsqlookupd)Main() { //Defines the instance of the context, which is defined in the Nsqlookupd\context.go file, which contains only a nsqlookupd pointer, note that the curly brackets are the lowercase of the character L, not the number one. Context:= &Amp;Context{L}
//Listening to TCP TcpListener,Err:=Net.Listen("TCP",L.Tcpaddr.String()) ifErr!=Nil{ Log.Fatalf("Fatal:listen (%s) failed- %s",L.Tcpaddr,Err.Error()) }
//Put listener in NSQLOOKUPD's struct L.TcpListener=TcpListener
//Create an instance of TCPServer, defined in the Nsqlookupd\tcp.go file, to handle the data received in the TCP connection. By reading earlier, you know that the context is just a pointer to a NSQLOOKUPD type. TCPServer:= &Amp;TCPServer{Context:Context}
//Call util. The TCPServer method (defined in Util\tcp_server.go) begins receiving listening and registering handler. Two parameters passed in the first one is TcpListener //The second TCPServer implements the Tcphandler interface defined in the Util\tcp_server.go. when//tcpserver receives TCP data, it calls its handle method (see NSQLOOKUPD\TCP.GO) to process it. //Why use the waitgroup here, is still relatively confused L.Waitgroup.Wrap(Func() {Util.TCPServer(TcpListener,TCPServer) })
//Listening to HTTP HttpListener,Err:=Net.Listen("TCP",L.Httpaddr.String()) ifErr!=Nil{ Log.Fatalf("Fatal:listen (%s) failed- %s",L.Httpaddr,Err.Error()) }
//Put listener in NSQLOOKUPD's struct L.HttpListener=HttpListener
//Create an instance of Httpserver, Httpserver defined in the Nsqlookupd\http.go file Httpserver:= &Amp;Httpserver{Context:Context}
//Call util. The Httpserver method (defined in Util\http_server.go) begins receiving an HTTP connection on the specified httplistener. //Two parameters passed in the first one is HttpListener The second Httpserver defines the HTTP handler, which is used to process HTTP requests. //Similarly, the use of waitgroup is not very understanding. L.Waitgroup.Wrap(Func() {Util.Httpserver(HttpListener,Httpserver) })
//After reading above, there are basically two discoveries: //1, TCPServer and Httpserver code are very similar. ///2, util\tcp_server.go before registering the handler, first defined an interface, but Tuil\http_server.go did not. //If you look at these two files again, you will find that tcp_server, through go handler. Handle (Clientconn) This code, the connection clientconn as a variable, passed to the handler //And in Http_server, the handler was passed on to Httpserver. //This is mainly because the Net/http package and net package usage is not the same, Net/http does a further encapsulation. }
// //exit close two X listener // Func(L*Nsqlookupd) Exit() { ifL.TcpListener!=Nil{ L.TcpListener.Close() }
ifL.HttpListener!=Nil{ L.HttpListener.Close() } L.Waitgroup.Wait() } |
There are several external files involved in the above code:
Nsqlookupd\options.go
Nsqlookupd\context.go
Nsqlookupd\tcp.go
Util\tcp_server.go
Nsqlookupd\http.go
Util\http_server.go
Util\wait_group_wrapper.go
Nsqlookupd\registration_db.go
These files will continue to be read in subsequent articles, with the next article:
Go Language nsq Source interpretation four NSQLOOKUPD source code options.go, Context.go and Wait_group_wrapper.go