delete docs move to github.com/beego/beedoc
102
docs/en/API.md
@ -1,102 +0,0 @@
|
|||||||
# Getting start with API application development
|
|
||||||
Go is very good for developing API applications which I think is the biggest strength compare to other dynamic languages. Beego provides powerful and quick setup tool for developing API applications, which gives you more focus on business logic.
|
|
||||||
|
|
||||||
|
|
||||||
## Quick setup
|
|
||||||
bee can setup a API application very quick by executing commands under any `$GOPATH/src`.
|
|
||||||
|
|
||||||
`bee api beeapi`
|
|
||||||
|
|
||||||
## Application directory structure
|
|
||||||
|
|
||||||
```
|
|
||||||
├── conf
|
|
||||||
│ └── app.conf
|
|
||||||
├── controllers
|
|
||||||
│ └── default.go
|
|
||||||
├── models
|
|
||||||
│ └── object.go
|
|
||||||
└── main.go
|
|
||||||
```
|
|
||||||
|
|
||||||
## Source code explanation
|
|
||||||
|
|
||||||
- app.conf has following configuration options for your API applications:
|
|
||||||
|
|
||||||
- autorender = false // Disable auto-render since API applications don't need.
|
|
||||||
- copyrequestbody = true // RESTFul applications sends raw body instead of form, so we need to read body specifically.
|
|
||||||
|
|
||||||
- main.go is for registering routers of RESTFul.
|
|
||||||
|
|
||||||
beego.RESTRouter("/object", &controllers.ObejctController{})
|
|
||||||
|
|
||||||
Match rules as follows:
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>URL</th> <th>HTTP Verb</th> <th>Functionality</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object</td> <td>POST</td> <td>Creating Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>GET</td> <td>Retrieving Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>PUT</td> <td>Updating Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object</td> <td>GET</td> <td>Queries</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>DELETE</td> <td>Deleting Objects</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
- ObejctController implemented corresponding methods:
|
|
||||||
|
|
||||||
type ObejctController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Post(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Get(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Put(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Delete(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- models implemented corresponding object operation for adding, deleting, updating and getting.
|
|
||||||
|
|
||||||
## Test
|
|
||||||
|
|
||||||
- Add a new object:
|
|
||||||
|
|
||||||
curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object
|
|
||||||
|
|
||||||
Returns a corresponding objectID:astaxie1373349756660423900
|
|
||||||
|
|
||||||
- Query a object:
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
- Query all objects:
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object`
|
|
||||||
|
|
||||||
- Update a object:
|
|
||||||
|
|
||||||
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
- Delete a object:
|
|
||||||
|
|
||||||
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
@ -1,46 +0,0 @@
|
|||||||
## What is hot update?
|
|
||||||
|
|
||||||
If you have used nginx, you may know that nginx supports hot update, which means you can update your nginx without stopping and restarting it. It serves old connections with old version, and accepts new connections with new version. Notice that hot compiling is different from hot update, where hot compiling is monitoring your source files and recompile them when the content changes, it requires stop and restart your applications, `bee start` is a tool for hot compiling.
|
|
||||||
|
|
||||||
|
|
||||||
## Is hot update necessary?
|
|
||||||
|
|
||||||
Some people says that hot update is not as useful as its cool name. In my opinion, this is absolutely necessary because zero-down server is our goal for our services. Even though sometimes some errors or hardware problems may occur, but it belongs to design of high availability, don't mix them up. Service update is a known issue, so we need to fix this problem.
|
|
||||||
|
|
||||||
|
|
||||||
## How Beego support hot update?
|
|
||||||
|
|
||||||
The basic principle of hot update: main process fork a process, and child process execute corresponding programs. So what happens? We know that after forked a process, main process will have all handles, data and stack, etc, but all handles are saved in `CloseOnExec`, so all copied handles will be closed when you execute it unless you clarify this, and we need child process to reuse the handle of `net.Listener`. Once a process calls exec functions, it is "dead", system replaces it with new code. The only thing it left is the process ID, which is the same number but it is a new program after executed.
|
|
||||||
|
|
||||||
Therefore, the first thing we need to do is that let child process fork main process and through `os.StartProcess` to append files that contains handle that is going to be inherited.
|
|
||||||
|
|
||||||
The second step is that we hope child process can start listening from same handle, so we can use `net.FileListener` to achieve this goal. Here we also need FD of this file, so we need to add a environment variable to set this FD before we start child process.
|
|
||||||
|
|
||||||
The final step is that we want to serve old connections with old version of application, and serve new connections with new version. So how can we know if there is any old connections? To do this, we have to record all connections, then we are able to know. Another problem is that how to let new application to accept connection? Because two versions of applications are listening to same port, they get connection request randomly, so we just close old accept function, and it will get error in `l.Accept`.
|
|
||||||
|
|
||||||
Above are three problems that we need to solve, you can see my code logic for specific implementation.
|
|
||||||
|
|
||||||
|
|
||||||
## Show time
|
|
||||||
|
|
||||||
1. Write code in your Get method:
|
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
|
||||||
a, _ := this.GetInt("sleep")
|
|
||||||
time.Sleep(time.Duration(a) * time.Second)
|
|
||||||
this.Ctx.WriteString("ospid:" + strconv.Itoa(os.Getpid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
2. Open two terminals:
|
|
||||||
|
|
||||||
One execute: ` ps -ef|grep <application name>`
|
|
||||||
|
|
||||||
Another one execute: `curl "http://127.0.0.1:8080/?sleep=20"`
|
|
||||||
|
|
||||||
3. Hot update
|
|
||||||
|
|
||||||
`kill -HUP <PID>`
|
|
||||||
|
|
||||||
4. Open a terminal to request connection: `curl "http://127.0.0.1:8080/?sleep=0"`
|
|
||||||
|
|
||||||
As you will see, the first request will wait for 20 seconds, but it's served by old process; after hot update, the first request will print old process ID, but the second request will print new process ID.
|
|
@ -1,26 +0,0 @@
|
|||||||
# Installation
|
|
||||||
|
|
||||||
Beego is a simple web framework, but it uses many third-party packages, so you have to install all dependency packages also.
|
|
||||||
|
|
||||||
- Before anything you do, you have to check that you installed Go in your computer, see more detail about Go installation in my book: [Chapter 1](https://github.com/Unknwon/build-web-application-with-golang_EN/blob/master/eBook/01.1.md)
|
|
||||||
- Use `go get ` to install Beego:
|
|
||||||
|
|
||||||
go get github.com/astaxie/beego
|
|
||||||
|
|
||||||
- Install bee tools for fast-develop Beego applications:
|
|
||||||
|
|
||||||
go get github.com/astaxie/bee
|
|
||||||
|
|
||||||
Good job, you're ready to Beego with powerful bee tools!
|
|
||||||
|
|
||||||
![](images/bee.png)
|
|
||||||
|
|
||||||
Beego has following dependency packages:
|
|
||||||
|
|
||||||
- Session module: [github.com/astaxie/beego/session](https://github.com/astaxie/beego/session)
|
|
||||||
- To support redis engine: [github.com/garyburd/redigo/redis](https://github.com/garyburd/redigo/redis)
|
|
||||||
- To support mysql engine: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
|
||||||
- To support markdown as template function: [github.com/russross/blackfriday](https://github.com/russross/blackfriday)
|
|
||||||
|
|
||||||
- [Introduction](README.md)
|
|
||||||
- [Quick start](Quickstart.md)
|
|
@ -1,60 +0,0 @@
|
|||||||
# Beego
|
|
||||||
|
|
||||||
Beego is a lightweight, open source, non-blocking and scalable web framework for the Go programming language. It's like tornado in Python. This web framework has already been using for building web server and tools in SNDA's CDN system. Documentation and downloads available at [http://astaxie.github.com/beego](http://astaxie.github.com/beego)
|
|
||||||
|
|
||||||
It has following main features:
|
|
||||||
|
|
||||||
- Supports MVC model, you only need to focus on logic and implementation methods.
|
|
||||||
- Supports websocket, use customized handlers to integrate sockjs.
|
|
||||||
- Supports customized router rules, including regex and semanteme.
|
|
||||||
- Session integration, supports memory, file, redis, mysql, etc.
|
|
||||||
- Automated parsing user form, you can get data very easy.
|
|
||||||
- Log level system, easy to record debugging and deployment logs.
|
|
||||||
- Use configuration file (.ini) to customized your system.
|
|
||||||
- Use built-in templates in Go, and it provides much more useful functions which are commonly used in web development.
|
|
||||||
|
|
||||||
The working principles of Beego as follows:
|
|
||||||
|
|
||||||
![](images/beego.png)
|
|
||||||
|
|
||||||
Beego is licensed under the Apache Licence, Version 2.0
|
|
||||||
(http://www.apache.org/licenses/LICENSE-2.0.html).
|
|
||||||
|
|
||||||
|
|
||||||
# Simple example
|
|
||||||
|
|
||||||
The following example prints string "Hello world" to your browser, it shows how easy to build a web application with Beego.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MainController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
|
||||||
this.Ctx.WriteString("hello world")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
beego.Router("/", &MainController{})
|
|
||||||
beego.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Handbook
|
|
||||||
|
|
||||||
- [Purposes](Why.md)
|
|
||||||
- [Installation](Install.md)
|
|
||||||
- [Quick start](Quickstart.md)
|
|
||||||
- [Step by step](Tutorial.md)
|
|
||||||
- [Real world usage](Application.md)
|
|
||||||
- [Hot update](HotUpdate.md)
|
|
||||||
|
|
||||||
|
|
||||||
# Documentation
|
|
||||||
|
|
||||||
[Go Walker](http://gowalker.org/github.com/astaxie/beego)
|
|
@ -1,36 +0,0 @@
|
|||||||
## Supervisord
|
|
||||||
|
|
||||||
[Supervisord](http://supervisord.org/) will make sure your web app is always up.
|
|
||||||
|
|
||||||
1. Installation
|
|
||||||
|
|
||||||
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
|
|
||||||
|
|
||||||
sh setuptools-0.6c11-py2.7.egg
|
|
||||||
|
|
||||||
easy_install supervisor
|
|
||||||
|
|
||||||
echo_supervisord_conf >/etc/supervisord.conf
|
|
||||||
|
|
||||||
mkdir /etc/supervisord.conf.d
|
|
||||||
|
|
||||||
2. Configure `/etc/supervisord.conf`
|
|
||||||
|
|
||||||
[include]
|
|
||||||
files = /etc/supervisord.conf.d/*.conf
|
|
||||||
|
|
||||||
3. Add new application
|
|
||||||
|
|
||||||
cd /etc/supervisord.conf.d
|
|
||||||
vim beepkg.conf
|
|
||||||
|
|
||||||
Configuration file:
|
|
||||||
|
|
||||||
[program:beepkg]
|
|
||||||
directory = /opt/app/beepkg
|
|
||||||
command = /opt/app/beepkg/beepkg
|
|
||||||
autostart = true
|
|
||||||
startsecs = 5
|
|
||||||
user = root
|
|
||||||
redirect_stderr = true
|
|
||||||
stdout_logfile = /var/log/supervisord/beepkg.log
|
|
@ -1,19 +0,0 @@
|
|||||||
# 一步一步跟我写博客
|
|
||||||
|
|
||||||
|
|
||||||
## 创建项目
|
|
||||||
|
|
||||||
|
|
||||||
## 数据库结构设计
|
|
||||||
|
|
||||||
|
|
||||||
## 控制器设计
|
|
||||||
|
|
||||||
|
|
||||||
## 模板设计
|
|
||||||
|
|
||||||
|
|
||||||
## 用户登陆退出
|
|
||||||
|
|
||||||
|
|
||||||
## 数据库操作
|
|
@ -1,20 +0,0 @@
|
|||||||
# Design purposes and ideas
|
|
||||||
|
|
||||||
People may ask me why I want to build a new web framework rather than use other good ones. I know there are many excellent web frameworks on the internet and almost all of them are open source, and I have my reasons to do this.
|
|
||||||
|
|
||||||
Remember when I was writing the book about how to build web applications with Go, I just wanted to tell people what were my valuable experiences with Go in web development, especially I have been working with PHP and Python for almost ten years. At first, I didn't realize that a small web framework can give great help to web developers when they are learning to build web applications in a new programming language, and it also helps people more by studying its source code. Finally, I decided to write a open source web framework called Beego as supporting materiel for my book.
|
|
||||||
|
|
||||||
I used to use CI in PHP and tornado in Python, there are both lightweight, so they has following advantages:
|
|
||||||
|
|
||||||
1. Save time for handling general problems, I only need to care about logic part.
|
|
||||||
2. Learn more about languages by studying their source code, it's not hard to read and understand them because they are both lightweight frameworks.
|
|
||||||
3. It's quite easy to make secondary development of these frameworks for specific purposes.
|
|
||||||
|
|
||||||
Those reasons are my original intention of implementing Beego, and used two chapters in my book to introduce and design this lightweight web framework in Go.
|
|
||||||
|
|
||||||
Then I started to design logic execution of Beego. Because Go and Python have somewhat similar, I referenced some ideas from tornado to design Beego. As you can see, there is no different between Beego and tornado in RESTful processing; they both use GET, POST or some other methods to implement RESTful. I took some ideas from [https://github.com/drone/routes](https://github.com/drone/routes) at the beginning of designing routes. It uses regular expression in route rules processing, which is an excellent idea that to make up for the default Mux router function in Go. However, I have to design my own interface in order to implement RESTful and use inherited ideas in Python.
|
|
||||||
|
|
||||||
The controller is the most important part of whole MVC model, and Beego uses the interface and ideas I said above for the controller. Although I haven't decided to have to design the model part, everyone is welcome to implement data management by referencing Beedb, my another open source project. I simply adopt Go built-in template engine for the view part, but add more commonly used functions as template functions. This is how a simple web framework looks like, but I'll keep working on form processing, session handling, log recording, configuration, automated operation, etc, to build a simple but complete web framework.
|
|
||||||
|
|
||||||
- [Introduction](README.md)
|
|
||||||
- [Installation](Install.md)
|
|
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 68 KiB |
106
docs/zh/API.md
@ -1,106 +0,0 @@
|
|||||||
# API应用开发入门
|
|
||||||
Go是非常适合用来开发API应用的,而且我认为也是Go相对于其他动态语言的最大优势应用。beego在开发API应用方面提供了非常强大和快速的工具,方便用户快速的建立API应用原型,专心业务逻辑就行了。
|
|
||||||
|
|
||||||
|
|
||||||
## 快速建立原型
|
|
||||||
bee快速开发工具提供了一个API应用建立的工具,在gopath/src下的任意目录执行如下命令就可以快速的建立一个API应用:
|
|
||||||
|
|
||||||
`bee api beeapi`
|
|
||||||
|
|
||||||
## 应用的目录结构
|
|
||||||
应用的目录结构如下所示:
|
|
||||||
|
|
||||||
```
|
|
||||||
├── conf
|
|
||||||
│ └── app.conf
|
|
||||||
├── controllers
|
|
||||||
│ └── default.go
|
|
||||||
├── models
|
|
||||||
│ └── object.go
|
|
||||||
└── main.go
|
|
||||||
```
|
|
||||||
|
|
||||||
## 源码解析
|
|
||||||
|
|
||||||
- app.conf里面主要针对API的配置如下:
|
|
||||||
|
|
||||||
autorender = false //API应用不需要模板渲染,所以关闭自动渲染
|
|
||||||
|
|
||||||
copyrequestbody = true //RESTFul应用发送信息的时候是raw body,而不是普通的form表单,所以需要额外的读取body信息
|
|
||||||
|
|
||||||
- main.go文件主要针对RESTFul的路由注册
|
|
||||||
|
|
||||||
`beego.RESTRouter("/object", &controllers.ObejctController{})`
|
|
||||||
|
|
||||||
这个路由可以匹配如下的规则
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>URL</th> <th>HTTP Verb</th> <th>Functionality</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object</td> <td>POST</td> <td>Creating Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>GET</td> <td>Retrieving Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>PUT</td> <td>Updating Objects</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object</td> <td>GET</td> <td>Queries</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>/object/objectId</td> <td>DELETE</td> <td>Deleting Objects</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
- ObejctController实现了对应的方法:
|
|
||||||
|
|
||||||
```
|
|
||||||
type ObejctController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Post(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Get(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Put(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ObejctController) Delete(){
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- models里面实现了对应操作对象的增删改取等操作
|
|
||||||
|
|
||||||
## 测试
|
|
||||||
|
|
||||||
- 添加一个对象:
|
|
||||||
|
|
||||||
`curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object`
|
|
||||||
|
|
||||||
返回一个相应的objectID:astaxie1373349756660423900
|
|
||||||
|
|
||||||
- 查询一个对象
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
- 查询全部的对象
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object`
|
|
||||||
|
|
||||||
- 更新一个对象
|
|
||||||
|
|
||||||
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
- 删除一个对象
|
|
||||||
|
|
||||||
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
@ -1,23 +0,0 @@
|
|||||||
# beego案例
|
|
||||||
|
|
||||||
- 短域名服务
|
|
||||||
|
|
||||||
使用beego开发了一个类似bitly的短域名服务,提供盛大内部项目使用,目前一台机器:32G内存、8核、centos64
|
|
||||||
redis数据库,数据量在1500w多点,从2012年8月份运行至今没有出现过问题
|
|
||||||
- 政府合作项目
|
|
||||||
|
|
||||||
使用beego提供系统级别服务,监控继承电路板信号,智能分析nginx配置,提供大数据量的下载调度
|
|
||||||
|
|
||||||
- 内部监控系统
|
|
||||||
目前这个项目还在开发中,主要是利用beego做两个服务,一个是服务器端,收集信息,一个是客户端,收集信息并上报给服务器端,如果和服务端断开,那么本地可以暂存数据,防止数据丢失,同时还支持类似pupput的功能,支持程序自动更新(重启功能,不支持热更新)
|
|
||||||
|
|
||||||
- 日志分析系统
|
|
||||||
以前采用hadoop来分析日志的来源和省份信息,发现hadoop分析这么大的数据,性能不是很好,延迟比较大,目前采用自己的一套架构,squid日志每小时分割上报,每小时对日志进行分割,然后进行UV、PV、省份、运营商、浏览器、数据量等的分析,同时把日志进行按域名分割,提供用户原始日志下载
|
|
||||||
|
|
||||||
- 下载分发系统
|
|
||||||
架构暂时不好公布,我们提供文件下载的智能分发,但是从文件上传到下发到每一台服务器,以前采用BT的方式,性能不是很好,目前采用新的架构,性能提升十几倍
|
|
||||||
|
|
||||||
- 基于微信的提醒助手
|
|
||||||
开源在github上
|
|
||||||
|
|
||||||
- 视频直播调度器
|
|
@ -1,45 +0,0 @@
|
|||||||
## 热升级是什么?
|
|
||||||
|
|
||||||
热升级是什么呢?了解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
|
|
@ -1,78 +0,0 @@
|
|||||||
## 方便的http客户端
|
|
||||||
我们经常会使用Go来请求其他API应用,例如你使用beego开发了一个RESTFul的API应用,那么如果来请求呢?当然可以使用`http.Client`来实现,但是需要自己来操作很多步骤,自己需要考虑很多东西,所以我就基于net下的一些包实现了这个简便的http客户端工具。
|
|
||||||
|
|
||||||
该工具的主要特点:
|
|
||||||
|
|
||||||
- 链式操作
|
|
||||||
- 超时控制
|
|
||||||
- 方便的解析
|
|
||||||
- 可控的debug
|
|
||||||
|
|
||||||
## 例子
|
|
||||||
我们上次开发的RESTful应用,最后我写过如何通过curl来进行测试,那么下面一一对每个操作如何用httplib来操作进行展示
|
|
||||||
|
|
||||||
- 添加一个对象:
|
|
||||||
|
|
||||||
`curl -X POST -d '{"Score":1337,"PlayerName":"Sean Plott"}' http://127.0.0.1:8080/object`
|
|
||||||
|
|
||||||
返回一个相应的objectID:astaxie1373349756660423900
|
|
||||||
|
|
||||||
str,err:=beego.Post("http://127.0.0.1:8080/object").Body(`{"Score":1337,"PlayerName":"Sean Plott"}`).String()
|
|
||||||
if err != nil{
|
|
||||||
println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
- 查询一个对象
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
var object Obeject
|
|
||||||
err:=beego.Get("http://127.0.0.1:8080/object/astaxie1373349756660423900").ToJson(&object)
|
|
||||||
if err != nil{
|
|
||||||
println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
- 查询全部的对象
|
|
||||||
|
|
||||||
`curl -X GET http://127.0.0.1:8080/object`
|
|
||||||
|
|
||||||
var objects []Object
|
|
||||||
err:=beego.Get("http://127.0.0.1:8080/object").ToJson(&objects)
|
|
||||||
if err != nil{
|
|
||||||
println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
- 更新一个对象
|
|
||||||
|
|
||||||
`curl -X PUT -d '{"Score":10000}'http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
str,err:=beego.Put("http://127.0.0.1:8080/object/astaxie1373349756660423900").Body(`{"Score":10000}`).String()
|
|
||||||
if err != nil{
|
|
||||||
println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
- 删除一个对象
|
|
||||||
|
|
||||||
`curl -X DELETE http://127.0.0.1:8080/object/astaxie1373349756660423900`
|
|
||||||
|
|
||||||
str,er:=beego.Delete("http://127.0.0.1:8080/object/astaxie1373349756660423900").String()
|
|
||||||
if err != nil{
|
|
||||||
println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
## 开启调试模式
|
|
||||||
用户可以开启调试打印request信息,默认是关闭模式
|
|
||||||
|
|
||||||
beego.Post(url).Debug(true)
|
|
||||||
|
|
||||||
## ToFile、ToXML、ToJson
|
|
||||||
上面我演示了Json的解析,其实还有直接保存为文件的ToFile操作,解析XML的ToXML操作
|
|
||||||
|
|
||||||
|
|
||||||
## 设置链接超时和读写超时
|
|
||||||
默认都设置为60秒,用户可以通过函数来设置相应的超时时间
|
|
||||||
|
|
||||||
beego.Get(url).SetTimeout(100*time.Second,100*time.Second)
|
|
||||||
|
|
||||||
|
|
||||||
更加详细的请参考[API接口](http://gowalker.org/github.com/astaxie/beego)
|
|
@ -1,31 +0,0 @@
|
|||||||
# 安装入门
|
|
||||||
|
|
||||||
beego虽然是一个简单的框架,但是其中用到了很多第三方的包,所以在你安装beego的过程中Go会自动安装其他关联的包。
|
|
||||||
|
|
||||||
- 当然第一步你需要安装Go,如何安装Go请参考我的书[第一章](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/01.1.md)
|
|
||||||
|
|
||||||
- 安装beego
|
|
||||||
|
|
||||||
go get github.com/astaxie/beego
|
|
||||||
|
|
||||||
- 安装bee工具,这个工具可以用来快速的建立beego的应用
|
|
||||||
|
|
||||||
go get github.com/astaxie/bee
|
|
||||||
|
|
||||||
这样就完成了beego的安装,你就可以开始开发了,可以通过bee工具来创建beego项目
|
|
||||||
|
|
||||||
![](images/bee.png)
|
|
||||||
|
|
||||||
>beego依赖的第三方包有如下:
|
|
||||||
|
|
||||||
> - session模块:github.com/astaxie/beego/session
|
|
||||||
|
|
||||||
|
|
||||||
> - session模块中支持redis引擎:github.com/garyburd/redigo/redis
|
|
||||||
|
|
||||||
> - session模块中支持mysql引擎:github.com/go-sql-driver/mysql
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- [beego介绍](README.md)
|
|
||||||
- [快速入门](Quickstart.md)
|
|
@ -1,54 +0,0 @@
|
|||||||
# beego介绍
|
|
||||||
beego是一个类似tornado的Go应用框架,采用了RESTFul的方式来实现应用框架,是一个超轻量级的框架,主要有如下的特点:
|
|
||||||
|
|
||||||
- 支持MVC的方式,用户只需要关注逻辑,实现对应method的方法即可
|
|
||||||
- 支持websocket,通过自定义Handler实现集成sockjs等方式实现
|
|
||||||
- 支持自定义路由,支持各种方式的路由,正则、语意均支持,类似sinatra
|
|
||||||
- session集成,支持memory、file、redis、mysql等存储
|
|
||||||
- 表单处理自动化解析,用户可以很方便的获取数据
|
|
||||||
- 日志分级系统,用户可以很方便的调试和应用日志记录
|
|
||||||
- 自定义配置文件,支持ini格式的文本配置,可以方便的在系统中调参数
|
|
||||||
- 采用了Go内置的模板,集成实现了很多Web开发中常用的函数
|
|
||||||
|
|
||||||
执行过程如下所示:
|
|
||||||
![](images/beego.png)
|
|
||||||
|
|
||||||
# beego简单例子
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/astaxie/beego"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MainController struct {
|
|
||||||
beego.Controller
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *MainController) Get() {
|
|
||||||
this.Ctx.WriteString("hello world")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
beego.Router("/", &MainController{})
|
|
||||||
beego.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# beego 指南
|
|
||||||
|
|
||||||
* [为什么设计beego](Why.md)
|
|
||||||
* [安装入门](Install.md)
|
|
||||||
* [快速入门](Quickstart.md)
|
|
||||||
* [一步一步开发应用](Tutorial.md)
|
|
||||||
* [beego案例](Application.md)
|
|
||||||
* [热升级](HotUpdate.md)
|
|
||||||
* [API应用开发入门](API.md)
|
|
||||||
* [HTTPLIB客户端](HttpLib.md)
|
|
||||||
|
|
||||||
|
|
||||||
# API接口
|
|
||||||
|
|
||||||
API对于我们平时开发应用非常有用,用于查询一些开发的函数,godoc做的非常好了
|
|
||||||
|
|
||||||
[Go Walker](http://gowalker.org/github.com/astaxie/beego)
|
|
@ -1,34 +0,0 @@
|
|||||||
## supervisord安装
|
|
||||||
|
|
||||||
1. setuptools安装
|
|
||||||
|
|
||||||
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
|
|
||||||
|
|
||||||
sh setuptools-0.6c11-py2.7.egg
|
|
||||||
|
|
||||||
easy_install supervisor
|
|
||||||
|
|
||||||
echo_supervisord_conf >/etc/supervisord.conf
|
|
||||||
|
|
||||||
mkdir /etc/supervisord.conf.d
|
|
||||||
|
|
||||||
2. 修改配置/etc/supervisord.conf
|
|
||||||
|
|
||||||
[include]
|
|
||||||
files = /etc/supervisord.conf.d/*.conf
|
|
||||||
|
|
||||||
3. 新建管理的应用
|
|
||||||
|
|
||||||
cd /etc/supervisord.conf.d
|
|
||||||
vim beepkg.conf
|
|
||||||
|
|
||||||
配置文件:
|
|
||||||
|
|
||||||
[program:beepkg]
|
|
||||||
directory = /opt/app/beepkg
|
|
||||||
command = /opt/app/beepkg/beepkg
|
|
||||||
autostart = true
|
|
||||||
startsecs = 5
|
|
||||||
user = root
|
|
||||||
redirect_stderr = true
|
|
||||||
stdout_logfile = /var/log/supervisord/beepkg.log
|
|
@ -1,19 +0,0 @@
|
|||||||
# 一步一步跟我写博客
|
|
||||||
|
|
||||||
|
|
||||||
## 创建项目
|
|
||||||
|
|
||||||
|
|
||||||
## 数据库结构设计
|
|
||||||
|
|
||||||
|
|
||||||
## 控制器设计
|
|
||||||
|
|
||||||
|
|
||||||
## 模板设计
|
|
||||||
|
|
||||||
|
|
||||||
## 用户登陆退出
|
|
||||||
|
|
||||||
|
|
||||||
## 数据库操作
|
|
@ -1,20 +0,0 @@
|
|||||||
# 为什么设计beego和设计的思路
|
|
||||||
|
|
||||||
很多人会问为什么有那么多框架了,还要去实现一个框架呢?是不是大家都有自己实现框架的情节,我可以肯定的说不是,我说一下为什么设计beego的初衷
|
|
||||||
|
|
||||||
还记得当初写书的时候,我纯粹只是想把自己在学习Go语言中的一些体会写出来,由于我以前主要从事PHP和python的Web开发,所以想写一本Go如何来做Web实战的经验,刚开始的时候书的目录里面根本就没有框架实现这些章节,是写到后来发现其实对于Web开发者来说,一个微型的框架是非常有利于大家学习一个语言和快速进行应用开发的。
|
|
||||||
|
|
||||||
我以前经常用PHP的CI框架和python的tornado框架,这些框架都是非常轻量级的,轻量级就有利于我们:
|
|
||||||
|
|
||||||
- 第一节约我开发中一些常见问题的处理,用户只需要关注逻辑层面的东西
|
|
||||||
- 第二轻量级以至于他们的代码也是非常清晰的,我们可以通过阅读他们的源码来学习和体会这门语言的一些细节
|
|
||||||
- 第三对于项目开发者来说可以基于这些框架进行改造以适应自己的项目,从而实现二次框架的创造
|
|
||||||
|
|
||||||
所以基于上面这些的考虑,我就想实现一个类似这些语言的轻量级框架,所以我就在书的最后设计了两个章节来介绍和实现beego框架,这就是当初写beego框架的初衷。
|
|
||||||
|
|
||||||
有了这个初衷之后我就开始设计beego的执行逻辑,由于Go语言和python的思路比较接近,所以我就参考了tornado的思路来设计beego,你可以看到beego的RESTful处理完全和tornado的处理是一模一样的,通过controller层的Get、Post等方法来实现RESTFul。刚开始的时候路由参考的是[https://github.com/drone/routes](https://github.com/drone/routes),这个的正则处理我觉得非常好,弥补了Go语言默认Mux中的路由功能,但是由于要采用RESTFul方式,所以我自己设计了一个接口,实现python中的继承思想。
|
|
||||||
|
|
||||||
整个的MVC逻辑中C是最重要的部分,这一块采用了我上面说的接口方式,M模块目前我还没想好怎么做,但是大家可以参考我的另一个开源项目beedb来实现数据的管理,V这一块目前采用了Go语言自带的模板引擎,但是实现了很多方便的模板函数。这样一个简易的框架就完成了,然后我就不断的完善周边的功能,包括表单处理、session处理、日志处理、配置处理、自动化运行等功能。
|
|
||||||
|
|
||||||
- [beego介绍](README.md)
|
|
||||||
- [安装入门](Install.md)
|
|
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 68 KiB |