This is a creation in Article, where the information may have evolved or changed.
From NSQ
NSQ's Official document of Dsign mentions a ppthttps://speakerdeck.com/snakes/nsq-nyc-golang-meetup, in which there is such a passage
Sum up.
- Don ' t be afraid of the sync Package
It's in the sync bag.
- Sync. Mutex (mutex, one-read-write)
- Sync. Rwmutex (read-write lock, can read one more write)
- Sync. Pool (object pooling, reasonable use can reduce memory allocation, reduce GC pressure, later write a blog to say)
- Sync. Once (concurrency control.) for opening several goroutines to perform a task that executes only once, such as singleton mode)
- Sync. Cond (concurrency control, Cond. Wait () blocks to other Goroutie to run to cond. Signal ())
- Sync. Waitgroup (concurrency control.) usually uses WG. Add increases the number of tasks Goroutie perform the WG after completing the task. Done, the number of tasks minus 1 WG. Wait for WG task number is 0)
- Goroutines is cheap not free
This sentence has been seen in other places, go func()
simple and easy to use, the creation cost is also very small, but also has the cost. In many cases, it is better to have a fixed number of workers and pass data with the channel.
The example in Go-apns2 is a very good example. https://github.com/sideshow/apns2/blob/master/_example/channel/main.go
Note A problem, go inside a goroutine panic, will cause the process to exit, so go func()
when the first line with
go func(){defer func(){if err:=recover(); err!=nil{}}()}()
It is safe to practice that the worker channel method is similar to
package mainimport ("fmt""log""time")func main() {ch := make(chan int, 10)for i := 0; i < 2; i++ {go worker(ch, i)}for i := 0; i < 3; i++ {ch <- ich <- -1}time.Sleep(time.Second * 5)}func worker(ch <-chan int, goId int) {defer func(ch <-chan int) {if err := recover(); err != nil {log.Printf("worker%d recover error:%s", goId, err)go worker(ch, goId)}}(ch)log.Printf("worker%d running", goId)for data := range ch {log.Printf("worker%d received data:%d", goId, data)if data == -1 {panic(fmt.Errorf("worker%d panic", goId))}}}
One of the reasons why Fasthttp is fast is that net/http is a connection to create a goroutie, and Fasthttp uses the pool to reuse goroutines.
Watch your Allocations (string () is costly, re-user buffers)
Go inside []byte and string are duplicated, the overhead is obvious, if the code is frequently cross-transferred, consider using Bytes.buffer and sync. Pool
Use anonymous structs for arbitrary JSON
In writing the HTTP API, the parse body thing, if it is purely to take the body of the JSON data, there is no need to define a separate structure, in the function to define an anonymous structure is good.var s struct { A int}
No built-in per-request HTTP timeouts
This is to note that the default httpclient does not time out
Synchronizing Goroutine exit is hard-log each cleanup step in long-running goroutines
Synchronized Goroutine accidentally did not quit, if you write a long-running service, with logger record every goroutine cleanup exit, to prevent goroutine leaks
Select skips nil channels
The SELECT statement skips the channels of nil. Because it is panic to send data in go to the already close channel, you can use the SELECT statement.
Attached: Channel operation led to panic: Close a nil channel, close a closed channel (j,ok:= <-ch, OK is false when the CH has been closed), to a closed channel to send data (Reading the data from the closed channel is OK, if the channel is buffered, you can read all the data)
From Go Proverbs
Python has import this
the Zen of Python, unexpectedly go also has proverbs
Https://speakerdeck.com/ajstarks/go-proverbs
- In go, communication between goroutines is not implemented by shared memory, it should be implemented by channel
- Concurrency is not parallel
- Channel is orchestration, Mutexs is serial
- Interface The more methods you define, the lower the abstraction level. Go advocates for a larger interface in a combination of interfaces
- 0 value, Guess here is struct{}, struct{} is a non-memory of the empty structure, in the map implementation set, the channel sends no additional meaning signal can reduce memory allocation
- Advocating gofmt
- A little copy is better than a little reliance. Some of the duplicated code is sometimes seen in the official bag to not depend on each other.
- Syscall each platform implementation is not the same, to add build tags
- CGO Each platform is not the same lib, to add a build tags
- CGO not go
- Unsafe package does not provide protection
- Simplicity trumps efficiency
- The error is that the value can be handled in a value way: Pass, compare
- Do not just check for errors, but gracefully handle them
- Multi-effort design architecture, module naming, writing detailed documentation
- Write good documents to the user
- For common errors, you should return the error with multiple values instead of manually panic
Unknown source
- Write reusable functions, receive interface types, return specific types
Golang Github
Https://github.com/golang/go/wiki/CodeReviewComments