Golang Hot Update Tips

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

# # Preface

The HTTP section of the Golang standard library provides powerful Web application support, coupled with the support of middleware frameworks such as Negroni, to develop high-performance Web applications, such as providing RESTful API services.
Typically these Web applications are deployed on multiple Linux operating system application servers, using Nginx as the reverse proxy for highly available cluster services. When applying version upgrades, how do you implement a more elegant version update of polymorphic servers?

# # Problem Analysis
Web App updates, I think there are a couple of things that might need to be considered:
1. Compile the application binary files, configuration files uploaded to the server;
2. The application server can sense that there is a new version upload;
3. If the service is not stopped, the hot update version;
4. It is best to have all the update process, can be scripted, reduce the manual operation error.

# # Scenario
In fact, the go Community has a number of open source projects that can automatically detect changes in Web applications and Automatic Updates, but these applications are detection of source code, resource file updates, start the build process, to achieve automatic compilation and restart, such as [Gin] (https://github.com/ Codegangsta/gin) and [fresh] (Https://github.com/pilu/fresh), these applications are suitable for the development and testing phases, and may not be suitable for deployment and updates of applications, but provide a good idea.

Upload the directory and version of the deployment environment
I will publish the application binaries and configuration files, stored in a directory, such as ~/app/release, each version is kept in this directory, such as app.1.0, app.1.1, app.2.0, once found a problem, can be timely rollback.
Also, under the ~/app directory, use the soft link file to point to the latest version, such as
```
Ln-s ~/app/release/app.2.0 ~/app/app.bin
```
Also, use a text file that is saved under ~/app/release to indicate the current version of the app, such as current.conf:
```
{
"Bin.file": "~/app/release/app.2.0",
"Cfg.file": "~/app/release/cfg.2.0"
}
```
When you need to update the version of the server, you can invoke the SCP through a script, upload the new version to the release directory, and then update the current.conf file.
Monitor current.conf files for version updates
current.conf file is the current version, once this file changes, that is, the version needs to be updated (or rollback), we only need to monitor the change of this file, once the change, then do the corresponding processing. The monitoring of files can be achieved by [fsnotify] (https://github.com/howeyc/fsnotify).
```
Func Watch () {
Watcher, err: = Fsnotify. Newwatcher ()
If err! = Nil {
Logger. Fatal (ERR)
}
Defer watcher. Close ()

Go func () {
for {
Select {
Case event: = <-watcher. Events:
Logger. Println ("Event:", event)
If event. Op&fsnotify. Write = = Fsnotify. Write {
Logger. Println ("Notify runner to do the Ln-s and restart server.")
Restartchan <-True
}
Case ERR: = <-watcher. Errors:
Logger. Println ("Error:", err)
}
}
}()

Err = Watcher. ADD ("/path/to/current.conf")
If err! = Nil {
Logger. Fatal (ERR)
}

<-make (chan bool)
}
```
Restart Service
After monitoring the changes to the current.conf file, the next step is to restart the service.
To make the service uninterrupted and graceful to restart, you can use [endless] (https://github.com/fvbock/endless) to replace the listenandserve of the standard library net/http:
```
N: = Negroni. New ()
N.use (middleware. Newrecovery ())
N.use (middleware. Newmaintainmiddleware ())
N.use (middleware. Newlogmiddleware ())
N.use (middleware. Newstatic (http. Dir ("Static")))
N.usehandler (router. Newrouter ())

Log. Fatal (Endless. Listenandserve (":", N))
```
After the current.conf change, first point the soft link file under ~/app to the latest version, and then use
```
Kill-hup
```
Notifies the app to restart.
```
Func run () {
for {
<-Restartchan

C, err: = Ioutil. ReadFile ("/path/to/current.conf")
If err! = Nil {
Logger. PRINTLN ("current.conf read error:", err)
Return
}

var J interface{}
Err = json. Unmarshal (c, &j)
If err! = Nil {
Logger. Println ("Current.conf Parse Error:", err)
Return
}

parsed, OK: = J. (map[string]interface{})
If!ok {
Logger. Println ("Current.conf Parse error:mapping errors")
Return
}

Exec.command ("rm", "App.bin"). Run ()
Exec.command ("ln", "-S", parsed["Bin.file"]. ( String), "App.bin"). Run ()

Exec.command ("rm", "app.conf"). Run ()
Exec.command ("ln", "-S", parsed["Cfg.file"]. ( String), "App.cfg"). Run ()

        If!started {
            cmd: = exec. Command ("./app.bin", "-C", "App.cfg")
            started = True
    &NBSP ;  } else {
            Processes, _: = PS. Processes ()
            for _, V: = range Processes {
        &N Bsp       if strings. Contains (V.executable (), parsed["Bin.file"]) {
                    p Rocess, _: = OS. Findprocess (V.pid ())
             ,       process. Signal (Syscall. SIGHUP)
               }
           }
       }
   }
}
"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.