如何使用http进行多个进程

时间:2014-09-28 17:20:55

标签: multithreading http go

如何利用所有CPU并为每个CPU生成http进程?

获取数量的CPU

numCPU := runtime.NumCPU()

启动http

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

2 个答案:

答案 0 :(得分:5)

如果你的目标只是让你的请求处理代码在所有CPU内核上运行,那么net/http已经启动了goroutine(一个类似线程的模糊事物特定于Go的实现)每个连接,并且Go安排NumCPU OS线程默认运行,以便goroutine可以分布在所有可用的CPU核心上。

Accept循环在单个goroutine中运行,但解析请求和生成响应的实际工作在每个连接中运行一次。

答案 1 :(得分:1)

你不能天真地,你必须编写自己的包装器:

// copied from http://golang.org/src/pkg/net/http/server.go#L1942
type tcpKeepAliveListener struct {
    *net.TCPListener
}

func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
    tc, err := ln.AcceptTCP()
    if err != nil {
        return
    }
    tc.SetKeepAlive(true)
    tc.SetKeepAlivePeriod(3 * time.Minute)
    return tc, nil
}

func ListenAndServe(addr string, num int) error {
    if addr == "" {
        addr = ":http"
    }
    ln, err := net.Listen("tcp", addr)
    if err != nil {
        return err
    }
    var wg sync.WaitGroup
    for i := 0; i < num; i++ {
        wg.Add(1)
        go func(i int) {
            log.Println("listener number", i)
            log.Println(http.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}, nil))

            wg.Done()
        }(i)
    }
    wg.Wait()
    return nil
}

func main() {
    num := runtime.NumCPU()
    runtime.GOMAXPROCS(num) //so the goroutine listeners would try to run on multiple threads
    log.Println(ListenAndServe(":9020", num))
}

或者,如果您使用最新的Linux内核,则可以使用http://comments.gmane.org/gmane.comp.lang.go.general/121122中的补丁并实际生成多个进程。