Beego新手项目-短链接编码到部署

--练手实操--

新建git项目

新建beego项目

bee new shorturl_on_beego

预先构想

描述

实现将长链接转换为短链接的功能

  1. 使用MySQL记录数据

功能划分

  1. 接口1 长链接转短链接
  2. 接口2 短链接反查长链接
  3. 功能3 访问短链接,跳转至长链接

代码实现

引入数据库

  1. 定义数据库配置文件
; conf/database.conf
dbhost=127.0.0.1
dbuser=root
dbpassword=rootroot
dbport=3306
db=shorturl_on_beego

app.conf中进行引入

appname = shorturl_on_beego
httpport = 8081
runmode = dev
appurl = http://localhost:8081

include "database.conf"
  1. main.go 中注册数据库
package main

import (
	"fmt"
	"github.com/astaxie/beego/orm"
	beego "github.com/beego/beego/v2/server/web"
	_ "github.com/go-sql-driver/mysql"
	_ "shorturl_on_beego/models"
	_ "shorturl_on_beego/routers"
)

func init() {
	dbuser, _ := beego.AppConfig.String("dbuser")
	dbpassword, _ := beego.AppConfig.String("dbpassword")
	dbhost, _ := beego.AppConfig.String("dbhost")
	dbport, _ := beego.AppConfig.String("dbport")
	db, _ := beego.AppConfig.String("db")
	// root:root@tcp(127.0.0.1:3306)/orm_test?charset=utf8
	datasource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&loc=Local", dbuser, dbpassword, dbhost, dbport, db)

	// 先注册数据库驱动
	orm.RegisterDriver("mysql", orm.DRMySQL)
	// 注册数据库
	orm.RegisterDataBase("default", "mysql", datasource)
	fmt.Println("连接数据库成功")

	name := "default"
	force := true
	err := orm.RunSyncdb(name, force, true)
	orm.Debug = true

	if err != nil {
		panic(err)
	}
}

func main() {
	beego.Run()
}

定义models

// models/urlRecord.go

package models

import (
	"github.com/astaxie/beego/orm"
	"time"
)

type UrlRecord struct {
	Id          uint64    `json:"id"`
	Key         string    `orm:"size(20);unique;description(短链后的key)" json:"key"`
	OriginalUrl string    `orm:"size(512);unique;description(原长链接)" json:"original_url"`
	CreatedAt   time.Time `orm:"auto_now_add,type(datetime)" json:"created_at"`
	UpdatedAt   time.Time `orm:"auto_now,type(datetime)" json:"updated_at"`
}

func (m *UrlRecord) TableName() string {
	return "url_records"
}

func init() {
	// 注册model
	orm.RegisterModel(new(UrlRecord))
}

定义 controller

  1. 定义 base.go,统一处理json返回
// controllers/base.go
package controllers

import (
	beego "github.com/beego/beego/v2/server/web"
	"strconv"
)

type BaseController struct {
	beego.Controller
}

type ReturnMessage struct {
	StatusCode int                    `json:"status_code"`
	Message    string                 `json:"message"`
	Data       map[string]interface{} `json:"data"`
}

func (c *BaseController) SuccessResponse(retData map[string]interface{}, otherParams ...string) {
	state := 200
	message := "操作成功"

	paramsLen := len(otherParams)
	if paramsLen > 0 {
		var err error
		state, err = strconv.Atoi(otherParams[0])
		if err != nil {
			state = 200
		}
	}

	if paramsLen > 1 {
		message = otherParams[1]
	}

	c.Data["json"] = c.GetRetMessages(retData, state, message)
	c.ServeJSON()
	c.StopRun()
}

func (c *BaseController) FailResponse(message string, failCode ...int) {
	state := 400
	if len(failCode) > 0 {
		state = failCode[0]
	}

	c.Data["json"] = c.GetRetMessages(nil, state, message)
	c.ServeJSON()
	c.StopRun()

}

func (c *BaseController) GetRetMessages(retData map[string]interface{}, state int, message string) ReturnMessage {
	return ReturnMessage{
		state, message, retData,
	}

}
  1. 定义 url.go 业务逻辑处理
// controllers/url.go

package controllers

import (
	"bytes"
	"fmt"
	"github.com/astaxie/beego/orm"
	_ "github.com/beego/beego/v2/client/cache"
	beego "github.com/beego/beego/v2/server/web"
	"math/rand"
	"shorturl_on_beego/models"
	"strings"
	"time"
)

type UrlController struct {
	BaseController
}

const (
	SHORTEN_KEY_LENGTH = 6
)

/*
	转成短链接
*/
func (c *UrlController) GetShorten() {
	url := c.GetString("url")

	// 获取url,判断是否是合法的链接,仅判断startsWith http:// or https://
	url = strings.TrimSpace(url)

	appUrl, _ := beego.AppConfig.String("appurl")

	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
		c.FailResponse("非法url")
	}

	/*
		re := md5.Sum([]byte("123456"))
		fmt.Printf("%x\n", re) // e10adc3949ba59abbe56e057f20f883e

		h := md5.New()
		h.Write([]byte("123456"))
		re1 := h.Sum(nil)
		fmt.Printf("%x\n", re1)
	*/

	// 查询数据库,最新一条记录
	// 数据库操作
	var urlRecord models.UrlRecord

	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))
	key := CreateRandomString(SHORTEN_KEY_LENGTH)

	err := qs.Filter("original_url", url).One(&urlRecord)

	// 找到记录
	if err == nil {
		c.SuccessResponse(map[string]interface{}{
			"url_record":  urlRecord,
			"shorten_url": appUrl + c.URLFor("UrlController.GetJump", ":key", urlRecord.Key),
			"now":         time.Now().Format("2006-01-02 15:04:05"),
			"from":        "db",
		})
	}

	for {
		count, _ := qs.Filter("key", key).Count()
		if count < 1 {
			break
		} else {
			key = CreateRandomString(SHORTEN_KEY_LENGTH)
		}
	}

	urlRecord = models.UrlRecord{
		Key:         key,
		OriginalUrl: url,
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}

	id, err := o.Insert(&urlRecord)

	if err != nil {
		c.FailResponse("转链失败,请稍后重试")
	}

	fmt.Println(id, err, urlRecord)
	c.SuccessResponse(map[string]interface{}{
		"url_record":  urlRecord,
		"shorten_url": appUrl + c.URLFor("UrlController.GetJump", ":key", urlRecord.Key),
		"now":         time.Now().Format("2006-01-02 15:04:05"),
		"from":        "db_new",
	})
}

func (c *UrlController) GetExpand() {
	url := c.GetString("url")
	url = strings.TrimSpace(url)

	// 非本域短链,返回错误
	appUrl, _ := beego.AppConfig.String("appurl")
	jumpPrefix := appUrl + c.URLFor("UrlController.GetJump") + "/"
	if !strings.HasPrefix(url, jumpPrefix) {
		c.FailResponse("非法Url")
	}

	key := url[len(jumpPrefix) : len(jumpPrefix)+SHORTEN_KEY_LENGTH]

	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))

	urlRecord := models.UrlRecord{}
	err := qs.Filter("key", key).One(&urlRecord)

	if err == orm.ErrNoRows {
		// 没有找到记录
		c.FailResponse("找不到该短链记录")
	}

	// 通过 url 提取key
	c.SuccessResponse(map[string]interface{}{
		"url_record": urlRecord,
		"now":        time.Now().Format("2006-01-02 15:04:05"),
	})
}

func (c *UrlController) GetJump() {
	key := c.GetString(":key")

	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))

	urlRecord := models.UrlRecord{}
	err := qs.Filter("key", key).One(&urlRecord)

	if err != nil {
		c.FailResponse("暂无短链数据")
	}

	c.Redirect(urlRecord.OriginalUrl, 307)

	/*
		c.SuccessResponse(map[string]interface{}{
			"url_record": urlRecord,
			"now": time.Now().Format("2006-01-02 15:04:05"),
		})
	*/
}

func CreateRandomString(len int) string {
	var container string
	var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

	b := bytes.NewBufferString(str)
	length := b.Len()
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < len; i++ {
		random := rand.Intn(length)
		container += string(str[random])
	}

	return container
}

定义路由

// routers/router.go
package routers

import (
	beego "github.com/beego/beego/v2/server/web"
	"shorturl_on_beego/controllers"
)

func init() {
	beego.Router("/", &controllers.MainController{})
	beego.Router("/shorten", &controllers.UrlController{}, "get:GetShorten")
	beego.Router("/expand", &controllers.UrlController{}, "get:GetExpand")
	beego.Router("/j/?:key", &controllers.UrlController{}, "get:GetJump")
}

至此,已可成功完成所需功能

http://localhost:8081/shorten?url= // 将url转成短链
http://localhost:8081/expand?url= // 根据短链反查原url链接
http://localhost:8081/j/9Bwq5k // 访问短链跳转至原始链接

TODO,优化一版加入Redis缓存

定义redis配置

  1. 定义redis配置内容
; conf/redis.conf
redis.key=collectionName
redis.conn=127.0.0.1:6379
redis.dbnum=1
redis.password=
  1. app.conf 中引入 redis.conf
    include "redis.conf"

新增redis操作struct

// services/redis.go
package services

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/astaxie/beego/orm"
	"github.com/beego/beego/v2/client/cache"
	"github.com/beego/beego/v2/core/logs"
	beego "github.com/beego/beego/v2/server/web"
	"time"
)

var (
	bm cache.Cache
)

type Redis struct {
}

func init() {
	//{"key":"collectionName","conn":":6039","dbNum":"0","password":"thePassWord"}
	key, _ := beego.AppConfig.String("redis.key")
	conn, _ := beego.AppConfig.String("redis.conn")
	dbNum, _ := beego.AppConfig.String("redis.dbnum")
	password, _ := beego.AppConfig.String("redis.password")

	config := orm.Params{
		"key":      key,
		"conn":     conn,
		"dbNum":    dbNum,
		"password": password,
	}

	configStr, _ := json.Marshal(config)

	var err error = nil
	bm, err = cache.NewCache("redis", string(configStr))

	if err != nil {
		logs.Error(err)
	}
	fmt.Println("连接Redis成功")
}

// 复写一遍,省略 context.Context
func (r *Redis) Get(key string, obj interface{}) error {
	v, err := bm.Get(context.Background(), key)

	if err != nil {
		logs.Error(err)
		return err
	}

	if v == nil {
		return errors.New("key not found")
	}

	err = json.Unmarshal(v.([]byte), obj)

	if err != nil {
		return err
	}

	return nil
}

func (r *Redis) Put(key string, val interface{}, timeout time.Duration) error {
	v, err := json.Marshal(val)

	if err != nil {
		return err
	}

	err = bm.Put(context.Background(), key, v, timeout)

	if err != nil {
		return err
	}

	return nil
}

func (r *Redis) Delete(key string) error {
	err := bm.Delete(context.Background(), key)
	return err
}

// Increment a cached int value by key, as a counter.
func (r *Redis) Incr(key string) error {
	return bm.Incr(context.Background(), key)
}

// Decrement a cached int value by key, as a counter.
func (r *Redis) Decr(key string) error {
	return bm.Decr(context.Background(), key)
}

func (r *Redis) IsExist(key string) (bool, error) {
	return bm.IsExist(context.Background(), key)
}

func (r *Redis) ClearAll(key string) error {
	return bm.ClearAll(context.Background())
}

func (r *Redis) StartAndGC(config string) error {
	return bm.StartAndGC(config)
}

定义 controller 进行业务处理

// controllers/cachedUrl.go
package controllers

import (
	"crypto/md5"
	"fmt"
	"github.com/astaxie/beego/orm"
	_ "github.com/beego/beego/v2/client/cache"
	beego "github.com/beego/beego/v2/server/web"
	"shorturl_on_beego/models"
	"shorturl_on_beego/services"
	_ "shorturl_on_beego/services"
	"strings"
	"time"
)

type CachedUrlController struct {
	BaseController
}

const (
	CACHED_TTL = 1800 * time.Second
)

/*
	转成短链接
*/
func (c *CachedUrlController) GetShorten() {
	/*
		    // Redis 操作
			m1 := AA{
				Age: 1,
				B:   3.1415926,
				Str: "Hello, world!",
			}

			m1Json, _ := json.Marshal(m1)
			redisop.BM.Put(context.Background(), "astaxie", m1Json, 1000*time.Second)
			v, _ := redisop.BM.Get(context.Background(), "astaxie")
			aaa := AA{}
			fmt.Println(string(v.([]byte)))
			err111 := json.Unmarshal(v.([]byte), &aaa)

			fmt.Println("---", err111)
			fmt.Println("aaa: ", aaa)
			fmt.Println(aaa.Age, aaa.B, aaa.Str)
	*/

	/*
		// 操作redis
		redis := new(services.Redis)
		m1 := AA{
			Age: 1,
			B:   3.1415926,
			Str: "Hello, world!",
		}

		err1 := redis.Put("astaxie", m1, 1000*time.Second)

		if err1 != nil {
			fmt.Println(err1)
		}

		m2 := AA{}
		err1 = redis.Get("astaxie", &m2)
		if err1 != nil {
			fmt.Println(err1)
		}
		fmt.Println(m2.Age, m2.Str, m2.B)
	*/

	url := c.GetString("url")

	// 获取url,判断是否是合法的链接,仅判断startsWith http:// or https://
	url = strings.TrimSpace(url)

	appUrl, _ := beego.AppConfig.String("appurl")

	if (!strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://")) || url == "" {
		c.FailResponse("非法url")
	}

	/*
		re := md5.Sum([]byte("123456"))
		fmt.Printf("%x\n", re) // e10adc3949ba59abbe56e057f20f883e

		h := md5.New()
		h.Write([]byte("123456"))
		re1 := h.Sum(nil)
		fmt.Printf("%x\n", re1)
	*/

	// 查询数据库,最新一条记录
	// 数据库操作
	var urlRecord models.UrlRecord

	redis := new(services.Redis)
	urlRedisKey := fmt.Sprintf("%x", md5.Sum([]byte(url)))
	isExists, _ := redis.IsExist(urlRedisKey)
	if isExists {
		// 直接获取,然后返回
		cacheErr := redis.Get(urlRedisKey, &urlRecord)

		if cacheErr == nil {
			c.SuccessResponse(map[string]interface{}{
				"url_record":  urlRecord,
				"shorten_url": appUrl + c.URLFor("CachedUrlController.GetJump", ":key", urlRecord.Key),
				"now":         time.Now().Format("2006-01-02 15:04:05"),
				"from":        "redis",
			})
		}
	}

	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))
	key := CreateRandomString(SHORTEN_KEY_LENGTH)

	err := qs.Filter("original_url", url).One(&urlRecord)

	// 找到记录
	if err == nil {
		// do cache
		_ = redis.Put(urlRedisKey, urlRecord, CACHED_TTL)
		_ = redis.Put(key, urlRecord, CACHED_TTL)

		c.SuccessResponse(map[string]interface{}{
			"url_record":  urlRecord,
			"shorten_url": appUrl + c.URLFor("CachedUrlController.GetJump", ":key", urlRecord.Key),
			"now":         time.Now().Format("2006-01-02 15:04:05"),
			"from":        "db",
		})
	}

	for {
		count, _ := qs.Filter("key", key).Count()
		if count < 1 {
			break
		} else {
			key = CreateRandomString(SHORTEN_KEY_LENGTH)
		}
	}

	urlRecord = models.UrlRecord{
		Key:         key,
		OriginalUrl: url,
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}

	id, err := o.Insert(&urlRecord)

	if err != nil {
		c.FailResponse("转链失败,请稍后重试")
	}

	fmt.Println(id, err, urlRecord)
	// do cache

	_ = redis.Put(urlRedisKey, urlRecord, CACHED_TTL)
	_ = redis.Put(key, urlRecord, CACHED_TTL)

	c.SuccessResponse(map[string]interface{}{
		"url_record":  urlRecord,
		"shorten_url": appUrl + c.URLFor("CachedUrlController.GetJump", ":key", urlRecord.Key),
		"now":         time.Now().Format("2006-01-02 15:04:05"),
		"from":        "db_new",
	})
	//c.FailResponse("操作失败")
}

func (c *CachedUrlController) GetExpand() {
	url := c.GetString("url")
	url = strings.TrimSpace(url)

	// 非本域短链,返回错误
	appUrl, _ := beego.AppConfig.String("appurl")
	jumpPrefix := appUrl + c.URLFor("CachedUrlController.GetJump") + "/"
	if !strings.HasPrefix(url, jumpPrefix) {
		c.FailResponse("非法Url")
	}

	key := url[len(jumpPrefix) : len(jumpPrefix)+SHORTEN_KEY_LENGTH]

	urlRecord := models.UrlRecord{}

	// 通过redis反查
	redis := new(services.Redis)
	isExists, redisErr := redis.IsExist(key)

	if isExists {
		redisErr = redis.Get(key, &urlRecord)
		if redisErr == nil {
			// 直接返回
			c.SuccessResponse(map[string]interface{}{
				"url_record": urlRecord,
				"now":        time.Now().Format("2006-01-02 15:04:05"),
				"from":       "redis",
			})
		}
	}

	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))
	err := qs.Filter("key", key).One(&urlRecord)

	if err == orm.ErrNoRows {
		// 没有找到记录
		c.FailResponse("找不到该短链记录")
	}

	// 存入缓存
	redisErr = redis.Put(urlRecord.Key, urlRecord, CACHED_TTL)
	urlRedisKey := fmt.Sprintf("%x", md5.Sum([]byte(urlRecord.OriginalUrl)))
	fmt.Println(urlRedisKey)
	redisErr = redis.Put(urlRedisKey, urlRecord, CACHED_TTL)

	// 通过 url 提取key
	c.SuccessResponse(map[string]interface{}{
		"url_record": urlRecord,
		"now":        time.Now().Format("2006-01-02 15:04:05"),
		"from":       "db",
	})
}

func (c *CachedUrlController) GetJump() {
	key := c.GetString(":key")

	if key == "" {
		c.FailResponse("暂无短链信息!")
	}

	fmt.Println(key)
	o := orm.NewOrm()
	qs := o.QueryTable(new(models.UrlRecord))
	urlRecord := models.UrlRecord{}

	// 查询cache
	redis := new(services.Redis)
	isExist, redisErr := redis.IsExist(key)
	fmt.Println(isExist, redisErr)
	if isExist {
		redisErr = redis.Get(key, &urlRecord)
		if redisErr == nil {
			fmt.Println("via cache")
			c.Redirect(urlRecord.OriginalUrl, 302)
			// 不加return,会往下执行
			return
		}
	}

	err := qs.Filter("key", key).One(&urlRecord)
	if err != nil {
		c.FailResponse("暂无短链数据")
	}

	_ = redis.Put(key, urlRecord, CACHED_TTL)
	urlRedisKey := fmt.Sprintf("%x", md5.Sum([]byte(urlRecord.OriginalUrl)))
	_ = redis.Put(urlRedisKey, urlRecord, CACHED_TTL)

	fmt.Println("via db")
	c.Redirect(urlRecord.OriginalUrl, 302)
	c.StopRun()
}

定义路由

        // routers/router.go
	beego.Router("/c/shorten", &controllers.CachedUrlController{}, "get:GetShorten")
	beego.Router("/c/expand", &controllers.CachedUrlController{}, "get:GetExpand")
	beego.Router("/c/j/?:key", &controllers.CachedUrlController{}, "get:GetJump")

至此,已添加了redis缓存热数据

http://localhost:8081/c/shorten?url= // 将url转成短链
http://localhost:8081/c/expand?url= // 根据短链反查原url链接
http://localhost:8081/c/j/9Bwq5k // 访问短链跳转至原始链接




部署至线上服务器

打包

bee pack -be GOOS=linux (打包到linux上部署命令)
bee pack -be GOOS=window (打包到windows上部署命令)

上传文件至服务器

  1. 将打包好的压缩包上传至服务器
    scp /Users/au/go/src/shorturl_on_beego/shorturl_on_beego.tar.gz user@ip:/data/wwwroot/shorturl_on_beego

  2. 解压压缩包,修改配置
    解压压缩包到目录的 ./dist 文件夹下
    cd /data/wwwroot/shorturl_on_beego && mkdir dist && tar -zxvf shorturl_on_beego.tar.gz -C ./dist/
    按需修改 conf/app.confconf/database.confconf/redis.conf 的配置项;可修改一份放置在 /data/wwwroot/shorturl_on_beego 下,后续直接复制至 dist/conf
    ps: 修改 runmode = prod,修改 databse.conf 中线上服务器的配置

  3. 通过 nohup 启动
    cd /data/wwwroot/shorturl_on_beego/dist && nohup ./shorturl_on_beego >> /home/ubuntu/shorturl_on_beego.log & // nohup 启动;ps 需要先cd到目录里面,/data/wwwroot/shorturl_on_beego/dist/shorturl_on_beego 启动,由于没设置viewspath 会导致默认路径有误
    ps aux | grep shorturl_on_beego // 查看pid
    kill -9 pid // 杀死进程

ip+端口形式访问

可通过以下链接访问
http://146.56.250.101:8081/shorten?url=https://www.baidu.com/
http://146.56.250.101:8081/expand?url=
http://146.56.250.101:8081/j/cXSumC
http://146.56.250.101:8081/c/shorten?url=https://www.baidu.com/
http://146.56.250.101:8081/c/expand?url=
http://146.56.250.101:8081/c/j/cXSumC


---

## nginx部署 #### nginx配置 ```` # /usr/local/nginx/conf/vhost/dev.aqiuliuxin614.com.conf server { listen 80; server_name dev.aqiuliuxin614.com; #index index.html index.htm; #root /data/wwwroot/shorturl_on_beego/dist;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ {
  expires 30d;
  access_log off;
  root /data/wwwroot/shorturl_on_beego/dist/static;
  try_files $uri @backend;
}

location ~ .*\.(js|css)?$ {
  expires 7d;
  access_log off;
  root /data/wwwroot/shorturl_on_beego/dist/static;
  try_files $uri @backend;
}

location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) {
  deny all;
}

location / {
   try_files /_not_exists_ @backend;
}

location @backend {
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:8081;
}

}


#### 域名形式访问
`http://dev.aqiuliuxin614.com/shorten?url=https://www.baidu.com/`
`http://dev.aqiuliuxin614.com/expand?url=`
`http://dev.aqiuliuxin614.com/j/cXSumC`
`http://dev.aqiuliuxin614.com/c/shorten?url=https://www.baidu.com/`
`http://dev.aqiuliuxin614.com/c/expand?url=`
`http://dev.aqiuliuxin614.com/c/j/cXSumC`
<br>

## 热更新
#### 修改app.conf 
`graceful = true`

#### 重启服务
`ps aux | grep shorturl_on_beego`
`kill -HUP 进程ID`

#### 测试
ps: 访问 `http://146.56.250.101:8081/suspend` 时,延时返回消息,表现为在浏览器一直loading,15秒后,返回首页内容
`GetSuspend` 方法设置了延时返回;
##### 测试预期
1. 运行`kill`命令后,"/suspend" 不可中断;
1. 运行`kill`命令后,"/suspend" 的Data的为原启动时的配置内容;
1. 运行`kill`命令后,"/" 马上返回新启动的配置项

##### 测试过程
1. 访问 "/", "/suspend",  页面中 Website 值为配置内的值
2. 重新访问 "/suspend", 页面loading时,同时监控 `.log` 文件 `tail -f shorten_on_beego.log -n 30`
3. 修改 app.conf 的appname,`ps aux | grep shorten_on_beego` , `kill -HUP 进程id`, 发送信号杀进程;
4. 重新访问 "/", Website的值为新 app.conf 的值,原loading的"/suspend"的页面中Website值为修改前的值

// controllers/base.go
package controllers

import (
"fmt"
beego "github.com/beego/beego/v2/server/web"
"time"
)

type MainController struct {
beego.Controller
}

func (c *MainController) Get() {
c.Data["Website"], _ = beego.AppConfig.String("appname")
c.Data["Email"] = "astaxie@gmail.com"
c.TplName = "index.tpl"
}

func (c *MainController) GetSuspend() {
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), i)
}

c.Data["Website"], _ = beego.AppConfig.String("appname")
c.Data["Email"] = "astaxie@gmail.com"
c.TplName = "index.tpl"

}


## 部署脚本

!/bin/bash

/data/wwwroot/shorturl_on_beego/restart.sh

tar -zxf shorturl_on_beego.tar.gz -C /data/wwwroot/shorturl_on_beego/dist/
echo "tar -zxf Success.."
cp app.conf dist/conf/app.conf && cp database.conf dist/conf/database.conf
echo ".conf files Copied.."

appname="shorturl_on_beego"
pid=pidof "${appname}"

if [ ! -n "$pid" ]; then
echo "Begoo Application is not running!"
cd /data/wwwroot/shorturl_on_beego/dist && nohup ./shorturl_on_beego >> /home/ubuntu/shorturl_on_beego.log &
echo "Started!!"
else
echo "Begoo Application is running, pid=${pid}"
echo "Send Kill HUP"
kill -HUP ${pid}
sleep 1
pid=pidof "${appname}"
echo "Restarted!!"
echo "new pid=${pid}"

fi

posted @ 2021-07-28 16:44  Au_ww  阅读(94)  评论(0编辑  收藏  举报