beego

概述

  • beego 是免费、开源的软件,这意味着任何人都可以为其开发和进步贡献力量。beego 源代码目前托管在 Github 上,Github 提供非常容易的途径 fork 项目和合并你的贡献。

beego安装

  • beego 的安装
    • beego 的安装是典型的 Go 安装包的形式:go get github.com/astaxie/beego
  • beego 的升级
    • Go 升级,通过该方式用户可以升级 beego 框架,强烈推荐该方式: go get -u github.com/astaxie/beego
    • 源码下载升级,用户访问 https://github.com/astaxie/beego ,下载源码,然后覆盖到 $GOPATH/src/github.com/astaxie/beego 目录,然后通过本地执行安装就可以升级了:go install github.com/astaxie/beego
  • bee工具的使用
    • bee 工具是一个为了协助快速开发 beego 项目而创建的项目,通过 bee 您可以很容易的进行 beego 项目的创建、热编译、开发、测试、和部署。
    • bee 工具的安装:go get github.com/beego/bee
    • new命令
      • new 命令是新建一个 Web 项目,我们在命令行下执行 bee new <项目名> 就可以创建一个新的项目。但是注意该命令必须在 $GOPATH/src 下执行。最后会在 $GOPATH/src 相应目录下生成如下目录结构的项目:bee new 项目名
    • api命令
      • 上面的 new 命令是用来新建 Web 项目,不过很多用户使用 beego 来开发 API 应用。所以这个 api 命令就是用来创建 API 应用的,执行命令之后如下所示:bee api apiproject
      • 从上面的目录我们可以看到和 Web 项目相比,少了 static 和 views 目录,多了一个 test 模块,用来做单元测试的。
      • 同时,该命令还支持一些自定义参数自动连接数据库创建相关 model 和 controller: bee api [appname] [-tables=""] [-driver=mysql] [-conn="root:<password>@tcp(127.0.0.1:3306)/test"] 如果 conn 参数为空则创建一个示例项目,否则将基于链接信息链接数据库创建项目。
    • run 命令
      • 我们在开发 Go 项目的时候最大的问题是经常需要自己手动去编译再运行,bee run 命令是监控 beego 的项目,通过 fsnotify监控文件系统。但是注意该命令必须在 $GOPATH/src/appname 下执行。 这样我们在开发过程中就可以实时的看到项目修改之后的效果:
    • pack 命令
      • pack 目录用来发布应用的时候打包,会把项目打包成 zip 包,这样我们部署的时候直接把打包之后的项目上传,解压就可以部署了:bee pack
    • bale 命令
      • 这个命令目前仅限内部使用,具体实现方案未完善,主要用来压缩所有的静态文件变成一个变量申明文件,全部编译到二进制文件里面,用户发布的时候携带静态文件,包括 js、css、img 和 views。最后在启动运行时进行非覆盖式的自解压
    • version 命令
      • 这个命令是动态获取 bee、beego 和 Go 的版本,这样一旦用户出现错误,可以通过该命令来查看当前的版本
    • generate 命令
      • 这个命令是用来自动化的生成代码的,包含了从数据库一键生成 model,还包含了 scaffold 的,通过这个命令,让大家开发代码不再慢
    • migrate 命令
      • 这个命令是应用的数据库迁移命令,主要是用来每次应用升级,降级的SQL管理。
    • dockerize 命令
      • 这个命令可以通过生成Dockerfile文件来实现docker化你的应用。
      • 生成一个以1.6.4版本Go环境为基础镜像的Dockerfile,并暴露9000端口:bee dockerize -image="library/golang:1.6.4" -expose=9000

快速入门

  • 新建项目
    • beego 的项目基本都是通过 bee 命令来创建的,所以在创建项目之前确保你已经安装了 bee 工具和 beego。
    • 进入 $GOPATH/src 所在的目录:
      • bee new quickstart
      • cd quickstart
      • bee run
      • localhost:8080
  • 路由设置
    • 前面我们已经创建了 beego 项目,而且我们也看到它已经运行起来了,那么是如何运行起来的呢?让我们从入口文件先分析起来吧:
    • package main import ( _ "quickstart/routers" "github.com/astaxie/beego" ) func main() { beego.Run() }
    • 这里我们就看到了我们引入了一个包 _ "quickstart/routers",这个包只引入执行了里面的 init 函数,那么让我们看看这个里面做了什么事情:
      • package routers import ( "quickstart/controllers" "github.com/astaxie/beego" ) func init() { beego.Router("/", &controllers.MainController{}) }
      • 路由包里面我们看到执行了路由注册 beego.Router, 这个函数的功能是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),这里我们注册的是 /,也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller,也就是我们即将把请求分发到那个控制器来执行相应的逻辑,我们可以执行类似的方式注册如下路由:
      • beego.Router("/user", &controllers.UserController{})
      • 这样用户就可以通过访问 /user 去执行 UserController 的逻辑。这就是我们所谓的路由,更多更复杂的路由规则请查询beego 的路由设置
    • 再回来看看 main 函数里面的 beego.Run, beego.Run 执行之后,我们看到的效果好像只是监听服务端口这个过程,但是它内部做了很多事情:
      • 解析配置文件:beego 会自动解析在 conf 目录下面的配置文件 app.conf,通过修改配置文件相关的属性,我们可以定义:开启的端口,是否开启 session,应用名称等信息。
      • 执行用户的 hookfunc:beego 会执行用户注册的 hookfunc,默认的已经存在了注册 mime,用户可以通过函数 AddAPPStartHook 注册自己的启动函数。
      • 是否开启 session:会根据上面配置文件的分析之后判断是否开启 session,如果开启的话就初始化全局的 session。
      • 是否编译模板:beego 会在启动的时候根据配置把 views 目录下的所有模板进行预编译,然后存在 map 里面,这样可以有效的提高模板运行的效率,无需进行多次编译。
      • 是否开启文档功能:根据 EnableDocs 配置判断是否开启内置的文档路由功能
      • 是否启动管理模块:beego 目前做了一个很酷的模块,应用内监控模块,会在 8088 端口做一个内部监听,我们可以通过这个端口查询到 QPS、CPU、内存、GC、goroutine、thread 等统计信息。
      • 监听服务端口:这是最后一步也就是我们看到的访问 8080 看到的网页端口,内部其实调用了 ListenAndServe,充分利用了 goroutine 的优势
    • 一旦 run 起来之后,我们的服务就监听在两个端口了,一个服务端口 8080 作为对外服务,另一个 8088 端口实行对内监控。
    • 通过这个代码的分析我们了解了 beego 运行起来的过程,以及内部的一些机制。接下来让我们去剥离 Controller 如何来处理逻辑的。
  • Controller运行机制
    • controller 逻辑
    • 上面的代码显示首先我们声明了一个控制器 MainController,这个控制器里面内嵌了 beego.Controller,这就是 Go 的嵌入方式,也就是 MainController 自动拥有了所有 beego.Controller 的方法。
    • 而 beego.Controller 拥有很多方法,其中包括 InitPreparePostGetDeleteHead 等方法。我们可以通过重写的方式来实现这些方法,而我们上面的代码就是重写了 Get 方法。
    • 我们先前介绍过 beego 是一个 RESTful 的框架,所以我们的请求默认是执行对应 req.Method 的方法。例如浏览器的是 GET 请求,那么默认就会执行 MainController 下的 Get 方法。这样我们上面的 Get 方法就会被执行到,这样就进入了我们的逻辑处理。(用户可以改变这个行为,通过注册自定义的函数名
    • 里面的代码是需要执行的逻辑,这里只是简单的输出数据,我们可以通过各种方式获取数据,然后赋值到 this.Data 中,这是一个用来存储输出数据的 map,可以赋值任意类型的值,这里我们只是简单举例输出两个字符串。
    • 最后一个就是需要去渲染的模板,this.TplName 就是需要渲染的模板,这里指定了 index.tpl,如果用户不设置该参数,那么默认会去到模板目录的 Controller/<方法名>.tpl 查找,例如上面的方法会去 maincontroller/get.tpl (文件、文件夹必须小写)
    • 用户设置了模板之后系统会自动的调用 Render 函数(这个函数是在 beego.Controller 中实现的),所以无需用户自己来调用渲染。
    • 当然也可以不使用模版,直接用 this.Ctx.WriteString 输出字符串,如:
      • func (this *MainController) Get() { this.Ctx.WriteString("hello") }
  • Model逻辑
    • 我们知道 Web 应用中我们用的最多的就是数据库操作,而 model 层一般用来做这些操作,我们的 bee new 例子不存在 Model 的演示,但是 bee api 应用中存在 model 的应用。说的简单一点,如果您的应用足够简单,那么 Controller 可以处理一切的逻辑,如果您的逻辑里面存在着可以复用的东西,那么就抽取出来变成一个模块。因此 Model 就是逐步抽象的过程,一般我们会在 Model 里面处理一些数据读取,如下是一个日志分析应用中的代码片段:
package models

import (
    "loggo/utils"
    "path/filepath"
    "strconv"
    "strings"
)

var (
    NotPV []string = []string{"css", "js", "class", "gif", "jpg", "jpeg", "png", "bmp", "ico", "rss", "xml", "swf"}
)

const big = 0xFFFFFF

func LogPV(urls string) bool {
    ext := filepath.Ext(urls)
    if ext == "" {
        return true
    }
    for _, v := range NotPV {
        if v == strings.ToLower(ext) {
            return false
        }
    }
    return true
}
所以如果您的应用足够简单,那么就不需要 Model 了;如果你的模块开始多了,需要复用,需要逻辑分离了,那么 Model 是必不可少的。接下来我们将分析如何编写 View 层的东西。
  • View编写
    • 在前面编写 Controller 的时候,我们在 Get 里面写过这样的语句 this.TplName = "index.tpl",设置显示的模板文件,默认支持 tpl 和 html 的后缀名,如果想设置其他后缀你可以调用 beego.AddTemplateExt 接口设置,那么模板如何来显示相应的数据呢?beego 采用了 Go 语言默认的模板引擎,所以和 Go 的模板语法一样,Go 模板的详细使用方法请参考《Go Web 编程》模板使用指南
    • 我们看看快速入门里面的代码(去掉了 css 样式):
<!DOCTYPE html>

<html>
    <head>
        <title>Beego</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
        <header class="hero-unit" style="background-color:#A9F16C">
            <div class="container">
                <div class="row">
                    <div class="hero-text">
                        <h1>Welcome to Beego!</h1>
                        <p class="description">
                            Beego is a simple & powerful Go web framework which is inspired by tornado and sinatra.
                            <br />
                            Official website: <a href="http://{{.Website}}">{{.Website}}</a>
                            <br />
                            Contact me: {{.Email}}
                        </p>
                    </div>
                </div>
            </div>
        </header>
    </body>
</html>
我们在 Controller 里面把数据赋值给了 data(map 类型),然后我们在模板中就直接通过 key 访问 .Website 和 .Email 。这样就做到了数据的输出。接下来我们讲解如何让静态文件输出。
  • 静态文件处理
    • 前面我们介绍了如何输出静态页面,但是我们的网页往往包含了很多的静态文件,包括图片、JS、CSS 等,刚才创建的应用里面就创建了如下目录:static
    • beego 默认注册了 static 目录为静态处理的目录,注册样式:URL 前缀和映射的目录(在/main.go文件中beego.Run()之前加入):StaticDir["/static"] = "static"
    • 用户可以设置多个静态文件处理目录,例如你有多个文件下载目录 download1、download2,你可以这样映射(在 /main.go 文件中 beego.Run() 之前加入):
      • beego.SetStaticPath("/down1", "download1")
      • beego.SetStaticPath("/down2", "download2")
    • 这样用户访问 URL http://localhost:8080/down1/123.txt 则会请求 download1 目录下的 123.txt 文件。

beego的MVC架构介绍

  • controller设计
  • model设计
  • view设计

beego的模块设计

  • Session模块
    • session 模块是用来存储客户端用户,session 模块目前只支持 cookie 方式的请求,如果客户端不支持 cookie,那么就无法使用该模块。
    • 安装session:go get github.com/astaxie/beego/session
    • session 使用
      • 导包:import ( "github.com/astaxie/beego/session" )
      • 初始化一个全局的变量用来存储 session 控制器:var globalSessions *session.Manager
      • 接着在你的入口函数中初始化数据:
      • func init() { sessionConfig := &session.ManagerConfig{ CookieName:"gosessionid", EnableSetCookie: true, Gclifetime:3600, Maxlifetime: 3600, Secure: false, CookieLifeTime: 3600, ProviderConfig: "./tmp", } globalSessions, _ = session.NewManager("memory",sessionConfig) go globalSessions.GC() }
      • NewManager 函数的参数的函数如下所示
      • 引擎名字,可以是 memory、file、mysql 或 redis。
      • 一个 JSON 字符串,传入 Manager 的配置信息
        1. cookieName: 客户端存储 cookie 的名字。
        2. enableSetCookie,omitempty: 是否开启 SetCookie,omitempty 这个设置
        3. gclifetime: 触发 GC 的时间。
        4. maxLifetime: 服务器端存储的数据的过期时间
        5. secure: 是否开启 HTTPS,在 cookie 设置的时候有 cookie.Secure 设置。
        6. sessionIDHashFunc: sessionID 生产的函数,默认是 sha1 算法。
        7. sessionIDHashKey: hash 算法中的 key。
        8. cookieLifeTime: 客户端存储的 cookie 的时间,默认值是 0,即浏览器生命周期。
        9. providerConfig: 配置信息,根据不同的引擎设置不同的配置信息,详细的配置请看下面的引擎设置
      • 最后我们的业务逻辑处理函数中可以这样调用:
      • func login(w http.ResponseWriter, r *http.Request) { sess, _ := globalSessions.SessionStart(w, r) defer sess.SessionRelease(w) username := sess.Get("username") if r.Method == "GET" { t, _ := template.ParseFiles("login.gtpl") t.Execute(w, nil) } else { sess.Set("username", r.Form["username"]) } }
      • globalSessions 有多个函数如下所示:
        • SessionStart 根据当前请求返回 session 对象
        • SessionDestroy 销毁当前 session 对象
        • SessionRegenerateId 重新生成 sessionID
        • GetActiveSession 获取当前活跃的 session 用户
        • SetHashFunc 设置 sessionID 生成的函数
        • SetSecure 设置是否开启 cookie 的 Secure 设置
      • 返回的 session 对象是一个 Interface,包含下面的方法
        • Set(key, value interface{}) error
        • Get(key interface{}) interface{}
        • Delete(key interface{}) error
        • SessionID() string
        • SessionRelease()
        • Flush() error
  • Grace模块
    • 热升级是什么?
      • 热升级是什么呢?了解 nginx 的同学都知道,nginx 是支持热升级的,可以用老进程服务先前链接的链接,使用新进程服务新的链接,即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念,热编译是通过监控文件的变化重新编译,然后重启进程,例如 bee run 就是这样的工具
    • 热升级有必要吗?
      • 很多人认为 HTTP 的应用有必要支持热升级吗?那么我可以很负责的说非常有必要,不中断服务始终是我们所追求的目标,虽然很多人说可能服务器会坏掉等等,这个是属于高可用的设计范畴,不要搞混了,这个是可预知的问题,所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛?那么现在就赶紧拥抱热升级吧。
    • grace 模块
  • Cache模块
    • 缓存模块
      • beego 的 cache 模块是用来做数据缓存的,设计思路来自于 database/sql,目前支持 file、memcache、memory 和 redis 四种引擎,安装方式如下:
        go get github.com/astaxie/beego/cache
        如果你使用memcache 或者 redis 驱动就需要手工安装引入包
        go get -u github.com/astaxie/beego/cache/memcache
        而且需要在使用的地方引入包
        import _ "github.com/astaxie/beego/cache/memcache"
    • 使用入门
      • 首先引入包:
        import ( "github.com/astaxie/beego/cache" )
        然后初始化一个全局变量对象:
        bm, err := cache.NewCache("memory", `{"interval":60}`)
        然后我们就可以使用bm增删改缓存:
        bm.Put("astaxie", 1, 10*time.Second) bm.Get("astaxie") bm.IsExist("astaxie") bm.Delete("astaxie")
    • Logs模块
      • 这是一个用来处理日志的库,它的设计思路来自于 database/sql,目前支持的引擎有 file、console、net、smtp,可以通过如下方式进行安装::go get github.com/astaxie/beego/logs
      • 通用方式:
        • 首先引入包:
          import ( "github.com/astaxie/beego/logs" )
          然后添加输出引擎(log 支持同时输出到多个引擎),这里我们以 console 为例,第一个参数是引擎名(包括:console、file、conn、smtp、es、multifile)
          logs.SetLogger("console")
          添加输出引擎也支持第二个参数,用来表示配置信息,详细的配置请看下面介绍:
          logs.SetLogger(logs.AdapterFile,`{"filename":"project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
          然后我们就可以在我们的逻辑中开始任意的使用了:
          package main import ( "github.com/astaxie/beego/logs" ) func main() { //an official log.Logger l := logs.GetLogger() l.Println("this is a message of http") //an official log.Logger with prefix ORM logs.GetLogger("ORM").Println("this is a message of orm") logs.Debug("my book is bought in the year of ", 2016) logs.Info("this %s cat is %v years old", "yellow", 3) logs.Warn("json is a type of kv like", map[string]int{"key": 2016}) logs.Error(1024, "is a very", "good game") logs.Critical("oh,crash") }
    • Httplib模块
      • httplib 库主要用来模拟客户端发送 HTTP 请求,类似于 Curl 工具,支持 JQuery 类似的链式操作。使用起来相当的方便;通过如下方式进行安装::go get github.com/astaxie/beego/httplib
      • 如何使用
        • 首先导入包
          import ( "github.com/astaxie/beego/httplib" )
          然后初始化请求方法,返回对象
          req := httplib.Get("http://beego.me/")
          然后我们就可以获取数据了
          str, err := req.String() if err != nil { t.Fatal(err) } fmt.Println(str)
      • 支持的方法对象(httplib 包里面支持如下的方法返回 request 对象:)
        • Get(url string)
        • Post(url string)
        • Put(url string)
        • Delete(url string)
        • Head(url string)
    • Context模块
      • 上下文模块:上下文模块主要是针对 HTTP 请求中,request 和 response 的进一步封装,他包括用户的输入和输出,用户的输入即为 request,context 模块中提供了 Input 对象进行解析,用户的输出即为 response,context 模块中提供了 Output 对象进行输出。
      • context 对象
        • context 对象是对 Input 和 Output 的封装,里面封装了几个方法:
        • Redirect
        • Abort
        • WriteString
        • GetCookie
        • SetCookie
        • context 对象是 Filter 函数的参数对象,这样你就可以通过 filter 来修改相应的数据,或者提前结束整个的执
    • Toolbox模块
      • 核心工具模块
        • 这个模块主要是参考了 Dropwizard 框架,是一位用户提醒我说有这么一个框架,然后里面实现一些很酷的东西。那个 issue 详细描述了该功能的雏形,然后就在参考该功能的情况下增加了一些额外的很酷的功能,接下来我将一一介绍这个模块中的几个功能:健康检查、性能调试、访问统计、计划任务。
      • 安装:go get github.com/astaxie/beego/toolbox
    • Config模块
      • 配置文件解析
        • 这是一个用来解析文件的库,它的设计思路来自于 database/sql,目前支持解析的文件格式有 ini、json、xml、yaml,可以通过如下方式进行安装:
          go get github.com/astaxie/beego/config
          如果你使用xml 或者 yaml 驱动就需要手工安装引入包
          go get -u github.com/astaxie/beego/config/xml
          而且需要在使用的地方引入包
          import _ "github.com/astaxie/beego/config/xml"
      •  如何使用
        • 首先初始化一个解析器对象
          iniconf, err := NewConfig("ini", "testini.conf") if err != nil { t.Fatal(err) }
          然后通过对象获取数据
          iniconf.String("appname")
          解析器对象支持的函数有如下:
          Set(key, val string) error
          String(key string) string
          Int(key string) (int, error)
          Int64(key string) (int64, error)
          Bool(key string) (bool, error)
          Float(key string) (float64, error)
          DIY(key string) (interface{}, error)
          ini 配置文件支持 section 操作,key通过 section::key 的方式获取
          例如下面这样的配置文件
          [demo] key1 = "asta" key2 = "xie"
          那么可以通过 iniconf.String("demo::key2") 获取值.
          2.2. 如何获取环境变量
          config 模块支持环境变量配置,对应配置项 Key 格式为 ${环境变量名} ,则 Value = os.Getenv(‘环境变量名’)。 同时可配置默认值,当环境变量无此配置或者环境变量值为空时,则优先使用默认值。包含默认值的 Key 格式为 ${GOPATH||/home/workspace/go/} ,使用||分割环境变量和默认值。
          注意 获取环境变量值仅仅是在配置文件解析时处理,而不会在调用函数获取配置项时实时处理。
    • I18n模块
      • 国际化介绍
        • i18n 模块主要用于实现站点或应用的国际化功能,实现多语言界面与反馈,增强用户体验。像 Go Walker 和 beego 官网 即是采用了该模块实现了中文与英文的双语界面。
          您可以通过以下方式安装该模块:
          go get github.com/beego/i18n

beego高级编程

  • 进程内监控
    • 前面介绍了 toolbox 模块,beego 默认是关闭的,在进程开启的时候监控端口,但是默认是监听在 127.0.0.1:8088,这样无法通过外网访问。当然你可以通过各种方法访问,例如 nginx 代理。
      为了安全,建议用户在防火墙中把 8088 端口给屏蔽了。你可以在 conf/app.conf 中打开它
      默认监控是关闭的,你可以通过设置参数配置开启监控:
      EnableAdmin = true
      而且你还可以修改监听的地址和端口:
      AdminAddr = "localhost" AdminPort = 8088
      打开浏览器,输入 URL:http://localhost:8088/,你会看到一句欢迎词:Welcome to Admin Dashboard
      目前由于刚做出来第一版本,因此还需要后续继续界面的开发。
    • 请求统计信息
      • 访问统计的 URL 地址 http://localhost:8088/qps,展现如下所示:
    • 性能调试
      • 你可以查看程序性能相关的信息, 进行性能调优.
    • 健康检查
      • 需要手工注册相应的健康检查逻辑,才能通过 URLhttp://localhost:8088/healthcheck 获取当前执行的健康检查的状态。
    • 定时任务
      • 用户需要在应用中添加了 task,才能执行相应的任务检查和手工触发任务。
      • 检查任务状态 URL:http://localhost:8088/task
      • 手工执行任务 URL:http://localhost:8088/task?taskname=任务名
    • 配置信息
      • 应用开发完毕之后,我们可能需要知道在运行的进程到底是怎么样的配置,beego 的监控模块提供了这一功能。
      • 显示所有的配置信息: http://localhost:8088/listconf?command=conf
      • 显示所有的路由配置信息: http://localhost:8088/listconf?command=router
      • 显示所有的过滤设置信息: http://localhost:8088/listconf?command=filter
  • API自动化文档
    • API 全局设置
      • 必须设置在 routers/router.go 中,文件的注释,最顶部:
        // @APIVersion 1.0.0 // @Title mobile API // @Description mobile has every tool to get any job done, so codename for the new mobile APIs. // @Contact astaxie@gmail.com package routers
        全局的注释如上所示,是显示给全局应用的设置信息,有如下这些设置
        @APIVersion
        @Title
        @Description
        @Contact
        @TermsOfServiceUrl
        @License
        @LicenseUrl

应用部署

  • linux
    • 在 linux 下面部署,我们可以利用 nohup 命令,把应用部署在后端,如下所示:
      nohup ./beepkg &
      这样你的应用就跑在了 Linux 系统的守护进程
  • Windows
    • 在 Windows 系统中,设置开机自动,后台运行,有如下几种方式:
    • 制作 bat 文件,放在“启动”里面
    • 制作成服务
  • Nginx部署
    • Go 是一个独立的 HTTP 服务器,但是我们有些时候为了 nginx 可以帮我做很多工作,例如访问日志,cc 攻击,静态服务等,nginx 已经做的很成熟了,Go 只要专注于业务逻辑和功能就好,所以通过 nginx 配置代理就可以实现多应用同时部署,如下就是典型的两个应用共享 80 端口,通过不同的域名访问,反向代理到不同的应用。
server {
    listen       80;
    server_name  .a.com;

    charset utf-8;
    access_log  /home/a.com.access.log;

    location /(css|js|fonts|img)/ {
        access_log off;
        expires 1d;

        root "/path/to/app_a/static";
        try_files $uri @backend;
    }

    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:8080;
    }
}

server {
    listen       80;
    server_name  .b.com;

    charset utf-8;
    access_log  /home/b.com.access.log  main;

    location /(css|js|fonts|img)/ {
        access_log off;
        expires 1d;

        root "/path/to/app_b/static";
        try_files $uri @backend;
    }

    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;
    }
}
  • Apache部署
    • apache 和 nginx 的实现原理一样,都是做一个反向代理,把请求向后端传递,配置如下所示:
NameVirtualHost *:80
<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    ServerName www.a.com
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    ServerName www.b.com
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass / http://127.0.0.1:8081/
    ProxyPassReverse / http://127.0.0.1:8081/
</VirtualHost>

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇