Application exit gracefully and hot upgrade

After the on-line application deployment formal operation, upgrade and maintenance program will encounter problems, under normal circumstances directly kill off a running application, and then update program, start the program. Such operation will encounter a problem that, at the time kill off the program, the current program is no guarantee that no business process, if there is a request, current business will fail if it is to obtain data, will not have much of a problem If other cases, it may produce erroneous data or dirty data, how elegant solution to upgrade the program but do not affect the operation of running the business (how hot upgrade)?

A necessary condition for the thermal upgrading of conduct of the proceedings:

  1. Update applications
  2. Stop running programs access data (stop listening port), automatically exits after handling requesting access
  3. Start the updated application, and for data access.

How to listen to exit the operating procedures

Starting and exiting the program, the operating system will emit a signal corresponding to the program can monitor the corresponding signal processing. golang, the monitoring signal may be performed by the signal packet Notify.

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    signals := make(chan os.Signal, 10)
    signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)

    select {
    case sg := <-signals:
        fmt.Println(sg)
    }
}

It should be noted that different operating systems handling of signals is not the same. golang signal unix-mainly on the operating system. For window systems, control + c will trigger os.Interrupt, support for the signal can refer godoc.

How to determine the current statistics of the number of ongoing business

golang the http server has a function variables connstate can listen request for link status changes.

package main

import (
    "fmt"
    "net"
    "net/http"
)

func main() {
    http.HandleFunc("/hello", func(resp http.ResponseWriter, req *http.Request) {
        resp.Write([]byte("hello"))
    })
    s := http.Server{
        Addr: "0.0.0.0:9090",
        ConnState: func(c net.Conn, s http.ConnState) {
            fmt.Println(c.RemoteAddr(), s.String())
        },
    }
    s.ListenAndServe()
}

Determining the number of counts may be the number of access service is currently being processed by a change in the listening state in ConnState. Note that, http multiplexing, there may be multiple requests, only one of the new state

How graceful exit program

  1. Receiving the operating system sends the SIGINT signal, blocking exit
  2. Monitor change requests link, the link count is 0 and the starting signal is received sigint real exit signals
package main

import (
    "fmt"
    "net"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    http.HandleFunc("/hello", func(resp http.ResponseWriter, req *http.Request) {
        time.Sleep(time.Second * 20)
        resp.Write([]byte("hello"))
    })

    exit := make(chan int, 1) //用于mark是否真的退出
    iscalllexit := false      //用于mark是否接收到exit signal
    count := 0                //用于mark 正在处理请求数
    s := http.Server{
        Addr: "0.0.0.0:9090",
        ConnState: func(c net.Conn, s http.ConnState) {
            fmt.Println(count, s)
            switch s { //需要注意的是并发的问题,只是用来演示原理
            case http.StateActive:
                count++
            case http.StateIdle:
                count--
            }
            if count == 0 && iscalllexit { //链接数为0且受到exit信号
                exit <- 1
            }
        },
    }

    ln, err := net.Listen("tcp", s.Addr)
    if err != nil {
        fmt.Println(err)
    }

    go s.Serve(ln)

    signals := make(chan os.Signal, 10)
    signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)

    select {
    case <-signals:
        ln.Close()
        iscalllexit = true
        fmt.Println("exit")
        if i := <-exit; i != 0 {
            return
        }
    }
    fmt.Println("exit success")
}

How Hot Upgrade

Os.StartProcess start using new applications (due to a port of the original application has been released, the new program can re-listen)

For hot update, facebook has a complete implementation. https://github.com/facebookarchive/httpdown (elegant dealt exit)
https://github.com/facebookarchive/grace (elegant program upgrade)

Guess you like

Origin www.cnblogs.com/zp900704/p/11721650.html