具有 Apache 多个虚拟主机的 Golang Web 应用程序
Golang webapp with Apache multiple VirtualHosts
不幸的是,我无法在生产服务器上部署基本的 Golang WebApp。在阅读了许多文档和教程后,我明白我需要 运行 Golang WebApp 作为守护进程。
首先要做的事情是:生产服务器是单个 IP 运行ning Ubuntu 16.04,带有基于 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
的内容
手动 运行 returns
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 的建议,我尝试更改 port/proxy 设置,结果如下:
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:
您需要启动 go 应用程序,并在 apache 配置中将请求反向代理到端口 8080(您编写的 go 守护程序侦听该端口)。
go 应用程序需要始终处于 运行ning 状态,因此您可能希望在系统启动时启动它。与从 apache 调用的 php 不同,go 应该 运行 作为始终存在的二进制文件。
关于你的端口问题:
确保您的应用程序尚未启动,并且没有其他应用程序正在侦听端口 8080。(您可以使用 netstat -talpen
查看)
编辑:
端口 8080 通常是一个 http 代理。在这一点上是否有代理或其他应用程序运行ning?
编辑:
您可以像这样配置您的 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 的端口可配置,这样您就不需要 re-compile 代码,以防您需要更改端口。你也可以绑定到本地主机接口,这样,如果你没有配置防火墙,人们只能通过 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))
不幸的是,我无法在生产服务器上部署基本的 Golang WebApp。在阅读了许多文档和教程后,我明白我需要 运行 Golang WebApp 作为守护进程。
首先要做的事情是:生产服务器是单个 IP 运行ning Ubuntu 16.04,带有基于 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
手动 运行 returns
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 的建议,我尝试更改 port/proxy 设置,结果如下:
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:
您需要启动 go 应用程序,并在 apache 配置中将请求反向代理到端口 8080(您编写的 go 守护程序侦听该端口)。 go 应用程序需要始终处于 运行ning 状态,因此您可能希望在系统启动时启动它。与从 apache 调用的 php 不同,go 应该 运行 作为始终存在的二进制文件。
关于你的端口问题:
确保您的应用程序尚未启动,并且没有其他应用程序正在侦听端口 8080。(您可以使用 netstat -talpen
查看)
编辑: 端口 8080 通常是一个 http 代理。在这一点上是否有代理或其他应用程序运行ning?
编辑: 您可以像这样配置您的 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 的端口可配置,这样您就不需要 re-compile 代码,以防您需要更改端口。你也可以绑定到本地主机接口,这样,如果你没有配置防火墙,人们只能通过 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))