2017. december 18., hétfő 13:51:26 UTC+1 időpontban eric.sh...@gmail.com a 
következőt írta:
>
> I try to implement a golang tcp server, and I found the concurrency is 
> satisfied for me, but the CPU usage is too high(concurrency is 15W+/s, but 
> the CPU usage is about 800% in a 24 cores linux machine). At the same time, 
> a C++ tcp server is only about 200% usage with a similar concurrency(with 
> libevent).
>
> The following code is the demo of golang:
>
> func main() {
>     listen, err := net.Listen("tcp", "0.0.0.0:17379")
>     if err != nil {
>         fmt.Errorf(err.Error())
>     }
>     go acceptClient(listen)
>     var channel2 = make(chan bool)
>     <-channel2}
>
> func acceptClient(listen net.Listener) {
>     for {
>         sock, err := listen.Accept()
>         if err != nil {
>             fmt.Errorf(err.Error())
>         }
>         tcp := sock.(*net.TCPConn)
>         tcp.SetNoDelay(true)
>         var channel = make(chan bool, 10)
>
>
why buffered? Who will close it?


>         go read(channel, sock.(*net.TCPConn))
>         go write(channel, sock.(*net.TCPConn))
>     }}
>
> func read(channel chan bool, sock *net.TCPConn) {
>     count := 0
>     for {
>         var buf = make([]byte, 1024)
>
>
Why allocate a new slice on every iteration?


>         n, err := sock.Read(buf)
>
>
This will be slow: TCP is a streaming protocol, so this Read can read any 
length between 0 (! yes !) and 1024 bytes.
Use buffering (bytes.NewReader) and some kind of message separation (e.g. 
bufio.Scanner for a line-oriented protocol).
 

>
>         if err != nil {
>             close(channel)
>             sock.CloseRead()
>             return
>         }
>         count += n
>         x := count / 58
>         count = count % 58
>         for i := 0; i < x; i++ {
>             channel <- true
>         }
>    }}
>
> func write(channel chan bool, sock *net.TCPConn) {
>     buf := []byte("+OK\r\n")
>     defer func() {
>         sock.CloseWrite()
>         recover()
>     }()
>     for {
>         _, ok := <-channel
>         if !ok {
>             return
>         }
>         _, writeError := sock.Write(buf)
>         if writeError != nil {
>             return
>         }
>     }}
>
> And I test this tcp server by the redis-benchmark with multi-clients:
>
> redis-benchmark -h 10.100.45.2  -p 17379 -n 1000 -q script load 
> "redis.call('set','aaa','aaa')"
>
> I also analyzed my golang code by the pprof, it is said CPU cost a lot of 
> time on syscall:
>
>
> <https://lh3.googleusercontent.com/-Xe7U4uSDwK8/Wjc25XRiF5I/AAAAAAAAAAc/ImuGGSAShmkVHEt2f-eTr2KO_OjunZuCQCLcBGAs/s1600/%25E6%2580%25A7%25E8%2583%25BD%25E5%25AE%259E%25E4%25BE%258B.png>
>
>
>
Next time please include the FULL svg, not only the node you think 
important! 

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to