【问题标题】:Golang webapp with Apache multiple VirtualHostsGolang webapp 与 Apache 多个 VirtualHosts
【发布时间】:2018-07-28 22:19:56
【问题描述】:

很遗憾,我无法在生产服务器上部署基本的 Golang WebApp。在阅读了许多文档和教程后,我了解到我需要将 Golang WebApp 作为守护程序运行。

首先要做的事:生产服务器是运行 Ubuntu 16.04 的单个 IP,带有基于 Apache 的多个 VirtualHosts /etc/apache2/sites-enabled/

Golang 环境变量

# set golang environment vars
export GOROOT=/usr/local/go

# set multiple gopaths seperated by ":"
export GOPATH=/var/www/go_projects/gotest.domain2.com

export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"

Systemd 守护进程文件

[Unit]
Description=GoTest Webserver

[Service]
Type=simple
WorkingDirectory=/var/www/go_projects/gotest.domain2.com
ExecStart=/var/www/go_projects/gotest.domain2.com/main #binary file

[Install]
WantedBy=multi-user.target

虚拟主机会议

<VirtualHost *:80>
    ServerName gotest.domain.com
    DocumentRoot /var/www/go_projects/gotest.domain2.com

    <Directory /var/www/go_projects/gotest.domain2.com>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
    </Directory>

去文件

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

不幸的是,http://gotest.domain2.com 上的程序没有被执行。而是列出DocumentRoot的内容

手动运行返回

admin@xyz:/var/www/go_projects/gotest.domain2.com$ ./main 
2018/02/18 15:52:58 listen tcp :8080: bind: address already in use

我缺少什么或者我的部署方法主要是错误的? 干杯!

编辑: 根据 Michael Ernst 的建议,我尝试更改端口/代理设置,结果如下:

http://gotest.domain2.com leads to 503 Service Unavailable

以下是sudo netstat -talpen的结果

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          16367       1250/sshd       
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      0          473536      26340/master    
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      0          16604       1417/dovecot    
tcp        0      0 0.0.0.0:2000            0.0.0.0:*               LISTEN      5001       17289       1652/asterisk   
tcp        0     xx.xx.xx.xx:22       xx.xx.xx.xx:6126      ESTABLISHED 0          615988      13025/sshd: admin [
tcp6       0      0 :::22                   :::*                    LISTEN      0          16369       1250/sshd       
tcp6       0      0 :::25                   :::*                    LISTEN      0          473537      26340/master    
tcp6       0      0 :::3306                 :::*                    LISTEN      111        17564       1391/mysqld     
tcp6       0      0 :::143                  :::*                    LISTEN      0          16605       1417/dovecot    
tcp6       0      0 :::80                   :::*                    LISTEN      0          612412      12554/apache2   
tcp6       0      0 xx.xx.xx.xx:80       xx.xx.xx.xx:6128      FIN_WAIT2   0          0           -               
tcp6       0      0 xx.xx.xx.xx:80       xx.xx.xx.xx:6129      ESTABLISHED 33         615029      12561/apache2   

知道问题出在哪里吗?

【问题讨论】:

  • 你为什么使用 apache 来托管 Golang 应用程序?
  • 干杯 Anuruddha,有两个原因,1) 服务器已经托管了几个 PHP 框架 2) 我只熟悉 Apache (PHP)。欢迎提出新建议。

标签: apache go webdeploy virtual-hosts


【解决方案1】:

至于配置apache:

您需要启动 go 应用程序并在 apache 配置中反向代理对端口 8080 的请求(您编写的 go 守护程序侦听该端口)。 go 应用程序需要始终运行,因此您可能希望在系统启动时启动它。与从 apache 调用的 php 不同,go 应该作为始终存在的二进制文件运行。

至于您的端口问题:

确保您的应用程序尚未启动,并且没有其他应用程序正在侦听端口 8080。(您可以使用netstat -talpen 来查看)

编辑: 端口 8080 通常是一个 http 代理。是否有代理或其他应用程序在此点上运行?

编辑: 你可以像这样配置你的 apache:

<VirtualHost *:80> 
  ProxyPreserveHost On
  ProxyRequests Off
  ServerName www.example.com
  ServerAlias example.com
  ProxyPass / http://localhost:8080/
  ProxyPassReverse / http://localhost:8080/
</VirtualHost>

您可能还希望使 go-application 的端口可配置,这样您就无需重新编译代码以防万一您需要更改端口。您也可以绑定到 localhost 接口,因此,如果您没有配置防火墙,人们只能通过 apache 访问 go 应用程序,而不能直接与 go 应用程序对话

// define the flag
port := flags.Int("port", 8080, "port to listen on")
// parse the flags
flags.Parse();
// here you might want to add code to make sure the port is valid.
// start webserver
log.Fatal(http.ListenAndServe("localhost:"+strconv.Atoi(*port), nil))

【讨论】:

  • 你可以给他 2 个 ProxyPass/ProxyPassReverse 行,以及一个更好的命令来识别端口 8080 上是否有任何东西正在监听(例如 netstat -talpen?)
  • @EugèneAdell 感谢您的建议。我编辑了答案以合并建议的更改
  • 关于documentroot列表而不是执行,我想代理到应用服务器会同时解决它
  • 干杯 Michael Ernst,Eugene Adell,不幸的是我还没有成功。我已经编辑了我的帖子并根据您的建议进行了更新。
  • 迈克尔(es funktioniert)谢谢!提出您的建议后,我所要做的就是重新启动守护程序。但是,像 gotest.domain2.com/testvar 这样传递 GET Vars 会导致 502 代理错误 Reason: DNS lookup failure for: localhost:8080test 知道原因是什么吗?
猜你喜欢
  • 1970-01-01
  • 2018-05-25
  • 2010-11-30
  • 2012-07-19
  • 2014-01-28
  • 2011-04-04
  • 2011-06-07
  • 2014-01-26
  • 2014-02-07
相关资源
最近更新 更多