Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
2bbd21ab
Commit
2bbd21ab
authored
Jun 07, 2013
by
astaxie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update docs for hotupdate
parent
45536776
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
0 deletions
+44
-0
HotUpdate.md
docs/zh/HotUpdate.md
+43
-0
README.md
docs/zh/README.md
+1
-0
No files found.
docs/zh/HotUpdate.md
0 → 100644
View file @
2bbd21ab
## 热升级是什么?
热升级是什么呢?了解nginx的同学都知道,nginx是支持热升级的,可以用老进程服务先前链接的链接,使用新进程服务新的链接,即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念,热编译是通过监控文件的变化重新编译,然后重启进程,例如bee start就是这样的工具
## 热升级有必要吗?
很多人认为HTTP的应用有必要支持热升级吗?那么我可以很负责的说非常有必要,不中断服务始终是我们所追求的目标,虽然很多人说可能服务器会坏掉等等,这个是属于高可用的设计范畴,不要搞混了,这个是可预知的问题,所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛?那么现在就赶紧拥抱热升级吧。
## beego如何支持热升级
热升级的原理基本上就是:主进程fork一个进程,然后子进程exec相应的程序。那么这个过程中发生了什么呢?我们知道进程fork之后会把主进程的所有句柄、数据和堆栈、但是里面所有的句柄存在一个叫做CloseOnExec,也就是执行exec的时候,copy的所有的句柄都被关闭了,除非特别申明,而我们期望的是子进程能够复用主进程的net.Listener的句柄。一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。
那么我们要做的第一步就是让子进程继承主进程的这个句柄,我们可以通过os.StartProcess的参数来附加Files,把需要继承的句柄写在里面。
第二步就是我们希望子进程能够从这个句柄启动监听,还好Go里面支持net.FileListener,直接从句柄来监听,但是我们需要子进程知道这个FD,所以在启动子进程的时候我们设置了一个环境变量设置这个FD。
第三步就是我们期望老的链接继续服务完,而新的链接采用新的进程,这里面有两个细节,第一就是老的链接继续服务,那么我们怎么有老链接存在?所以我们必须每次接收一个链接记录一下,这样我们就知道还存在没有服务完的链接,第二就是怎么让老进程停止接收数据,让新进程接收数据呢?大家都监听在同一个端口,理论上是随机来接收的,所以这里我们只要关闭老的链接的接收就行,这样就会使得在l.Accept的时候报错。
上面是我们需要解决的三个方面的问题,具体的实现大家可以看我实现的代码逻辑。
## 如何演示热升级
1.
编写代码,在beego应用的控制器中Get方法实现大概如下:
func (this *MainController) Get() {
a, _ := this.GetInt("sleep")
time.Sleep(time.Duration(a) * time.Second)
this.Ctx.WriteString("ospid:" + strconv.Itoa(os.Getpid()))
}
2.
打开两个终端
一个终端输入:
` ps -ef|grep 应用名`
一个终端输入请求:
`curl "http://127.0.0.1:8080/?sleep=20"`
3.
热升级
`kill -HUP 进程ID`
4.
打开一个终端输入请求:
`curl "http://127.0.0.1:8080/?sleep=0"`
我们可以看到这样的结果,第一个请求等待20s,但是处理他的是老的进程,热升级之后,第一个请求还在执行,最后会输出老的进程ID,而第二次请求,输出的是新的进程ID
\ No newline at end of file
docs/zh/README.md
View file @
2bbd21ab
...
...
@@ -41,6 +41,7 @@ beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实
*
[
快速入门
](
Quickstart.md
)
*
[
一步一步开发应用
](
Tutorial.md
)
*
[
beego案例
](
Application.md
)
*
[
热升级
](
HotUpdate.md
)
# API接口
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment