内容
状態:-
閲覧数:1,481
投稿日:2018-04-27
更新日:2018-08-16
一覧
前提 / 解決できた課題 / 進め方の手順 / 未解決の課題 / 時系列
エラー履歴
Go で書いた Web アプリケーションを UNIX ドメインソケットで公開
前提 / 解決できた課題 / 進め方の手順 / 未解決の課題 / 時系列
前提
サーバ環境
・CentOS7
解決できた課題
Go で Webサイト作成
・Webブラウザで表示確認
進め方の手順
1.コマンド起動
・Goをコマンド起動させWeb表示確認
→ コマンド終了したらWeb表示確認できなくなるため、実質的な運用は出来ない
未解決の課題
時系列
2017/12/15
・Go web framework Echoで、「Hello, World!」をブラウザ表示
→ 「http://グローバルIPアドレス:ポート番号」でブラウザアクセスしているため、実運用出来ない
2018/4/28
・Nginxで Goコマンド起動し、「Hello, World!」をブラウザ表示
→ コマンド終了するとブラウザ表示されなくなるため、実運用出来ない
2018/4/29 → 2018/5/6
・NginxとCentOS7のサービス経由で Goコマンド起動し、「Hello, World!」をブラウザ表示
→ CentOS7のサービス経由で 起動しているため、(CentOS7を起動している限り)常にブラウザ表示されるようになった。実運用出来る
エラー履歴
13: Permission denied
sock failed (13: Permission denied)
・nginx error connect to php5-fpm.sock failed (13: Permission denied)upstream timed out (110: Connection
upstream timed out (110: Connection
・nginx でupstream timed outエラーが発生した時の対処・nginxのタイムアウトエラー(upstream timed out (110: Connection timed out) while reading response header from upstream)
その他エラー履歴
502 Bad Gateway
504 Gateway Time-out
.sock failed (111: Connection refused)
vi go-demo.w4c.work.conf
server {
listen 80;
server_name go-demo.w4c.work
location / {
fastcgi_pass unix:/var/run/go-fcgi.sock;
include fastcgi_params;
}
}
root /var/www/◇◇/w4c.work/go-demo.w4c.work;
index index.php index.html index.htm index.go;
2018/04/27 09:26:36 [crit] 22015#22015: *1 connect() to unix:/var/run/go/go-fcgi.sock failed (2: No such file or directory) while connecting to upstream, client: IPアドレス, server: go-demo.w4c.work, request: "GET /index.go HTTP/1.1", upstream: "fastcgi://unix:/var/run/go/go-fcgi.sock:", host: "go-demo.w4c.work"
パーミッションの問題
▼/main.go
・「Hellow World!」が表示された
・なぜ?
▼/indesx.go
・「Hellow World!」が表示された
テキスト内容を変更したら、二度と表示されなくなる
・恐らくパミッションの問題
・現状では、ソケットファイルはrootで作成される
・そのままではエラーになるため、nginxユーザへ変更する
・問題は、次にgoファイルを変更した際
・反映されなくなる。恐らくパミッションの問題。よく分かっていない
・Goでソケットファイル作成する際、nginxユーザかつパミッション777で作成したい
Go で書いた Web アプリケーションを UNIX ドメインソケットで公開
nginxユーザーのユーザIDやグループIDを表示してみる
# id nginx
uid=994(nginx) gid=992(nginx) groups=992(nginx)
$ go run index.go
mkdir /var/run/go/: file exists
chown not permitted
ファイル操作
mkdir
・既にある場合エラーとなるため、コメントアウト
下記ファイルは動作確認できたので、既に削除済
▼/var/www/◇◇/go-demo.w4c.work/index.go
package main
import (
"os"
"fmt"
"net"
"net/http"
"net/http/fcgi"
)
func handler(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, "Hello World!")
}
func main() {
// if err := os.Mkdir("/var/run/go/", 0777); err != nil {
// fmt.Println(err)
// }
os.RemoveAll("/run/go/go-fcgi.sock")
l, err := net.Listen("unix", "/run/go/go-fcgi.sock")
if err != nil {
return
}
os.Chmod("/run/go/go-fcgi.sock", 0777)
if err := os.Chown("/run/go/go-fcgi.sock", 994, 992); err != nil {//uid=994,gid=992
fmt.Println("chown not permitted")
}
http.HandleFunc("/", handler)
fcgi.Serve(l, nil)
}
下記ファイルは現在も運用中
▼/var/www/◇◇/go-demo.w4c.work/demo/a2.go
package main
import (
"os"
"fmt"
"net"
"net/http"
"net/http/fcgi"
"path/filepath"
)
func handler(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, "Hellow World! こんにちは 世界!")
}
func main() {
// if err := os.Mkdir("/var/run/go/", 0777); err != nil {
// fmt.Println(err)
// }
exe, err := os.Executable()
os.RemoveAll("/run/go/app/" + filepath.Base(exe) + ".sock")
l, err := net.Listen("unix", "/run/go/app/" + filepath.Base(exe) + ".sock")
if err != nil {
return
}
os.Chmod("/run/go/app/" + filepath.Base(exe) + ".sock", 0777)
if err := os.Chown("/run/go/app/" + filepath.Base(exe) + ".sock", 994, 992); err != nil {//uid=994,gid=992
fmt.Println("chown not permitted")
}
http.HandleFunc("/", handler)
fcgi.Serve(l, nil)
}
・Go言語入門(ファイル・ディレクトリ操作)
・逆引きGolang (ファイル)
コマンド起動
ファイル内容を変更する度に、下記コマンド入力が必要
$ sudo go run index.go
・最初にsocketファイル削除しないと動作しない・理由不明
▼index.go
package main
import (
"os"
"fmt"
"net"
"net/http"
"net/http/fcgi"
)
func handler(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, "113H33ello World!sss22")
}
func main() {
// if err := os.Mkdir("/var/run/go/", 0777); err != nil {
// fmt.Println(err)
// }
os.RemoveAll("/run/go/go-fcgi.sock")
l, err := net.Listen("unix", "/run/go/go-fcgi.sock")
if err != nil {
return
}
os.Chmod("/run/go/go-fcgi.sock", 0777)
if err := os.Chown("/run/go/go-fcgi.sock", 994, 992); err != nil {//uid=994,gid=992
fmt.Println("chown not permitted")
}
http.HandleFunc("/", handler)
fcgi.Serve(l, nil)
}
UNIX ドメインソケットファイルの置き場
ソケットファイルの置き場
・/var/run を経由するよう設定
注意事項(2018/8/16に追記)
・下記を設定しなくても、Go で書いた Web アプリケーションを UNIX ドメインソケットで公開できる
・しかし、何かのタイミングでCentOSを再起動した際、トラブルに見舞われる
・設定しておくに越したことはないが、内容が分かりづらいので、身をもってトラブルを体験してから試してみた方が良いかも
/usr/lib/tmpfiles.d/に設定ファイルを追記
・CentOS7再起動時に、/run 直下に作成したディレクトリを削除しないようにする
・「/run/go/app」ディレクトリを作成するようにしているが、「/run/go」ディレクトリで良かったと思われ
・d /var/run/app 777 [UID] [GID]
d /run/go/app 777 root root
最初にsocketファイル削除するか、終了時に(次回のために)UNIXソケットのファイルを削除するか
・Golang で書いた Web アプリケーションを UNIX ドメインソケットで公開
・golang製WAFのgojiでfastcgiを使ってnginxと連携する
・終了時にUNIXソケットのファイルを削除するようにするのは、なぜですか?
CentOS7 サービス登録 go
buildする「binary file」名を変更
buildする際、出力ファイル名変更する方法が分からない
・ファイル名自体を変更
・index.go → goweb.go
build実行
「goweb」バイナリファイルを出力
$ cd /var/www/◇◇/go-demo.w4c.work
$ go build goweb.go
▼/var/www/◇◇/go-demo.w4c.work/gowebbuild結果を移動
「goweb」バイナリファイルを、/opt/ディレクトリ直下へ移動
$ sudo mv /var/www/◇◇/go-demo.w4c.work/goweb /opt/goweb
$ cd /opt
$ ls -l
合計 6356
-rwxrwxr-x 1 ★★ ★★ 6504539 4月 29 10:50 goweb
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
Unit定義ファイル作成
/etc/systemd/system/ の下にUnit定義ファイルを作成
$ sudo vi /etc/systemd/system/goweb.service
・「ExecStart = /opt/goweb」で、サービス起動コマンドとして「/opt/goweb」ファイルを指定・「Restart = always」で、プロセスが異常終了した際は、サービスの再起動を行う
・「Type = simple」で、指定コマンドがフォアグラウンドで実行を継続する場合、コマンドを実行した らすぐに起動完了と判定する
[Unit]
Description = go web start
[Service]
ExecStart = /opt/goweb
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
Unit定義ファイル確認
UnitがServiceとして認識されたか確認
・今回はgoweb.serviceファイルを作成したので、ファイル名で検索してみる
$ sudo systemctl list-unit-files --type=service | grep goweb
goweb.service disabled
サービス起動
自動起動on して start
・ここまでくれば、普通のサービスとして取扱可能
自動起動on
・enable
$ sudo systemctl enable goweb
Created symlink from /etc/systemd/system/multi-user.target.wants/goweb.service to /etc/systemd/system/goweb.service.
起動
・start
$ sudo systemctl start goweb
ステータス確認
$ sudo systemctl status
● ■■.vs.sakura.ne.jp
State: degraded
Jobs: 0 queued
Failed: 1 units
Since: 月 2018-04-23 16:15:08 JST; 5 days ago
CGroup: /
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
├─user.slice
│ └─user-1000.slice
│ ├─session-1352.scope
│ │ ├─5450 sshd: ★★ [priv
│ │ ├─5452 sshd: ★★@nott
│ │ └─5453 /usr/libexec/openssh/sftp-server
│ ├─session-1341.scope
│ │ ├─5070 sshd: ★★ [priv
│ │ ├─5072 sshd: ★★@nott
│ │ └─5073 /usr/libexec/openssh/sftp-server
│ ├─session-1318.scope
│ │ ├─3721 sshd: ★★ [priv
│ │ ├─3723 sshd: ★★@pts/
│ │ ├─3724 -bash
│ │ ├─5530 sudo systemctl status
│ │ ├─5531 systemctl status
│ │ └─5532 less
│ └─session-1307.scope
│ ├─3586 sshd: ★★ [priv
│ ├─3588 sshd: ★★@nott
│ └─3589 /usr/libexec/openssh/sftp-server
└─system.slice
├─goweb.service
│ └─5525 /opt/goweb
├─uwsgi.service
│ ├─1769 /usr/bin/uwsgi --emperor /var/www/◇◇/python-demo.w4c.work/emperor --uid nginx --gi
│ ├─1770 /usr/bin/uwsgi --ini emperor.ini
│ ├─5159 /usr/bin/uwsgi --ini emperor.ini
│ ├─5160 /usr/bin/uwsgi --ini uwsgi.ini
│ ├─5161 /usr/bin/uwsgi --ini b.ini
lines 1-37
Webブラウザにて、アプリケーション内容の表示確認
http://go-demo.w4c.work/
113H33ello World!sss22
2018/8/21時点
build済の「binary file」名を確認
$ cd /opt
$ ls -l
合計 0
drwxr-xr-x 2 root root 33 5月 7 10:05 go
drwxr-xr-x. 2 root root 6 3月 26 2015 rh
$ cd go
$ ls -l
合計 19080
-rwxr-xr-x 1 root root 6508678 5月 6 11:04 a1
-rwxr-xr-x 1 root root 6508678 5月 6 11:04 a2
-rwxr-xr-x 1 root root 6508678 5月 7 10:02 a3
a1「binary file」内容を確認
$ less a1
"a1" may be a binary file. See it anyway?
y
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@^PjE^@^@^@^@^@@^@^@^@^@^@^@^@p^B^@^@^@^@^@^@^@^@^@^@@^@8^@
^@@^@$^@ ^@^F^@^@^@^D^@^@^@@^@^@^@^@^@^@^@@^@@^@^@^@^@^@@^@@^@^@^@^@^@0^B^@^@^@^@^@^@0^B^@^@^@^@^@^@^@^P^@^@^@^@^@^@^C^@^@^@^D^@^@^@<E4>^O^@^@^@^@^@^@<E4>^O@^@^@^@^@^@<E4>^O@^@^@^@^@^@^\^@^@^@^@^@^@^@^\^@^@^@^@^@^@^@^A^@^@
^@^@^@^@^@^D^@^@^@^D^@^@^@<80>^O^@^@^@^@^@^@<80>^O@^@^@^@^@^@<80>^O@^@^@^@^@^@d^@^@^@^@^@^@^@d^@^@^@^@^@^@^@^D^@^@
^@^@^@^@^@^A^@^@^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@@^@^@^@^@^@^@^@@^@^@^@^@^@<D0><E3> ^@^@^@^@^@<D0><E3> ^@^@^@^@^@^@^P
^@^@^@^@^@^@^A^@^@^@^D^@^@^@^@<F0> ^@^@^@^@^@^@<F0>`^@^@^@^@^@^@<F0>`^@^@^@^@^@E<93>ESC^@^@^@^@^@E<93>ESC^@^@^@^@^@^@^P^@^@^@^@^@^@^A^@^@^@^F^@^@^@^@<90><^@^@^@^@^@^@<90>|^@^@^@^@^@^@<90>|^@^@^@^@^@<C0>G^C^@^@^@^@^@8g^E^@^@^@^@^@
^@^P^@^@^@^@^@^@^B^@^@^@^F^@^@^@ <91><^@^@^@^@^@ <91>|^@^@^@^@^@ <91>|^@^@^@^@^@0^A^@^@^@^@^@^@0^A^@^@^@^@^@^@^H^@
^@^@^@^@^@^@^G^@^@^@^D^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@^@^@^@^@^@^@^H^@^@
^@^@^@^@^@Q<E5>td^F^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@^@^@^@^@^@^@<80>^U^De^@*^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^H^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^A^@^@^@^A^@^@^@^F^@^@^@^@^@^@^@^@^P@^@^@^@^@^@^@^P^@^@^@^@^@^@<B4><D1> ^@^@^@^@^@^@^@^@^@^@^@^@
^@^P^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@V^A^@^@^A^@^@^@^F^@^@^@^@^@^@^@<C0><E1>`^@^@^@^@^@<C0><E1> ^@^@^@^@^@^P^B^@^@^@^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^@^@^@^@^P^@^@^@^@^@^@^@G^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@^@<F0>`^@^@^@^@^@^@<F0> ^@^@^@^@^@
//以下略
・Systemd
GoWebアプリ複数起動するためには?
現状の問題点
1アプリ毎にサービス登録が必要
・面倒
やりたいこと
・GoアプリのWeb表示機能のみサービス登録
・goアプリ内容を上記の中で直書したくない
・あるいは、Python uwsgiのEmperor みたいな、複数ファイルに対応した監視機能が欲しい
現状の案
ソケット名の動的化
・取り敢えず、Pythonの時みたいに、ソケット名を動的にしなければいけないと思う
・現状「go-fcgi.sock」固定なので、常に同じ結果が表示される
その上で、GoアプリのWeb表示機能のみ、ビルドした上でサービス登録
・そこから指定ディレクトリのgoファイルを呼び出さなければいけない
・問題は、buildした実行ファイルから、buildしていない、かつ不定期で内容が変更するgoファイルを呼び出せるか
buildした実行ファイルから、buildしていない、かつ不定期で内容が変更するgoファイルを呼び出せるか
動作確認開始作業
ディレクトリ作成
$ pwd
/home/★★/go/src
$ mkdir 20180501
$ cd 20180501/
$ pwd
/home/★★/go/src/20180501
1ファイル内で関数呼出
$ vi main.go
package main
import "log"
func main() {
a()
b()
}
func a() {
log.Print("Hello func a")
}
func b() {
log.Print("Hello func b")
}
実行してみる
$ go run main.go
2018/05/01 09:01:27 Hello func a
2018/05/01 09:01:27 Hello func b
異なるファイルの関数呼出
分割してみる
$ mkdir b
関数は大文字から始めるようにする
・大文字から始まる関数は外部に公開される
$ vi b/b.go
package b
import "log"
func B() {
log.Print("Hello func b")
}
$ vi main.go
package main
import "./b"
import "log"
func main() {
a()
b.B()
}
func a() {
log.Print("Hello func a")
}
$ go run main.go
2018/05/01 09:14:15 Hello func a
2018/05/01 09:14:15 Hello func b
build結果ファイルより、異なるファイルの関数呼出
$ go build main.go
$ ls -l
合計 2060
drwxrwxr-x 2 ★★ ★★ 17 5月 1 09:07 b
-rwxrwxr-x 1 ★★ ★★ 2105323 5月 1 09:15 main
-rw-rw-r-- 1 ★★ ★★ 120 5月 1 09:11 main.go
$ ./main
2018/05/01 09:17:01 Hello func a
2018/05/01 09:17:01 Hello func b
build実行後に、異なるファイルの関数処理内容を変更した場合、反映されるか
$ vi b/b.go
package b
import "log"
func B() {
log.Print("Hello func b15")
}
反映されない
$ ./main
2018/05/01 09:20:05 Hello func a
2018/05/01 09:20:05 Hello func b
$ go run main.go
2018/05/01 09:22:49 Hello func a
2018/05/01 09:22:49 Hello func b15
$ ./main
2018/05/01 09:22:56 Hello func a
2018/05/01 09:22:56 Hello func b
・Go言語のpackageの作り方: 長くなったコードを別ファイルに切り出す方法
go言語の学習メモ9(ファイルを分割)
go runしても分割したファイルが認識されない
・build後に「分割したファイル内容を変更した場合」でも、build結果に反映させたい
go buildでは指定されたパッケージの依存関係を解決していきながらビルドしていくのでGoで書かれていれば含まれる
・この逆をやりたい
・パッケージの依存関係を動的対応したい
下記結果のmainファイルはバイナリ
・バイナリからgoファイル呼び出したい
・どうやら無理っぽい
$ go build main.go
調査した結果分かったこと
go buildでコンパイルした結果作成されたバイナリファイルは、実行時にソースコードを読んでいない
今の方式だと、1アプリ毎にサービス登録必須
・そんなのやってられない
go run
goファイル確認
$ cd src/
$ ls -l
合計 1980
drwxrwxr-x 3 ★★ ★★ 39 5月 1 09:15 20180501
-rwxrwxr-x 1 ★★ ★★ 2020012 4月 25 11:14 hello
-rw-rw-r-- 1 ★★ ★★ 77 4月 25 11:11 hello.go
$ cd 20180501/
$ ls -l
合計 2060
drwxrwxr-x 2 ★★ ★★ 17 5月 1 09:20 b
-rwxrwxr-x 1 ★★ ★★ 2105323 5月 1 09:15 main
-rw-rw-r-- 1 ★★ ★★ 120 5月 1 09:11 main.go
$ ./main
2018/05/01 23:13:01 Hello func a
2018/05/01 23:13:01 Hello func b
go run
自動的にコンパイル・実行するコマンド
・「go run hoge.go」でプログラム実行することができるが、go buildのようにカレントディレクトリ以下の全ファイルを読み込むわけではない
$ go run main.go
2018/05/01 23:13:27 Hello func a
2018/05/01 23:13:27 Hello func b15
ビルド対象から外す
$ vi b/b.go
// +build ignore
package b
import "log"
func B() {
log.Print("Hello func b15")
}
$ go build
main.go:3:8: local import "./b" in non-local package
ダメじゃん!・buildせず import出来るのかと思ったよ
go buildにはC言語のようにファイルごとにオブジェクトを作成しておいて、変更があったファイルのみ差分コンパイルする仕組みがありません。
つまりGoは必ず1つのパッケージ内では複数ファイルを同時にコンパイルして、ライブラリを作成するまでが仕様になっています。
・何れにしてもコンパイルは必要みたい
・Go Binary Hacks - go buildせずにビルドする #golang
・GoのBuild Constraintsに関するメモ
・あー、もー、分からない
・もういいわ
・goファイル内容変更する度、「go build」して、CentOS7サービスヘ登録した内容を再起動すればいいんやろ
・超面倒くさいわ。Go!
GOPATHについて - はじめてのGo言語
go ソケットファイル名 動的 / サービス登録で、問題発覚
go build 出力先指定
named files must be .go files
Goでディレクトリ&ファイル名を指定してビルドgo 実行ファイル名取得
ログから取得する方法
log.Lshortfile
・うまくいかない・理由不明
# go build goweb.go
# command-line-arguments
./goweb.go:21:29: cannot convert "/run/go/" (type untyped string) to type int
./goweb.go:21:29: invalid operation: "/run/go/" + log.Lshortfile (mismatched types string and int)
./goweb.go:22:45: cannot convert "/run/go/" (type untyped string) to type int
./goweb.go:22:45: invalid operation: "/run/go/" + log.Lshortfile (mismatched types string and int)
./goweb.go:26:25: cannot convert "/run/go/" (type untyped string) to type int
./goweb.go:26:25: invalid operation: "/run/go/" + log.Lshortfile (mismatched types string and int)
./goweb.go:27:35: cannot convert "/run/go/" (type untyped string) to type int
./goweb.go:27:35: invalid operation: "/run/go/" + log.Lshortfile (mismatched types string and int)
・[Go] ファイル名、行数、関数名、スタックトレースをランタイム時に取得する
Go で実行ファイルのパスを取得 - Qiita
Goのpathとfilepathでは動作が異なる Windowsでも正しくパスを扱う - Qiita
Big Sky :: Golang で物理ファイルの操作に path/filepath でなく path を使うと爆発します。
# cat /etc/nginx/conf.d/go-demo.w4c.work.conf
server {
listen 80;
server_name go-demo.w4c.work;
root /var/◇◇/w4c.work/go-demo.w4c.work;
#index index.php index.html index.htm index.go;
#listen.owner = nginx;
#listen.group = nginx;
#listen.mode = 0777;
#デフォルト 60秒を120秒までアップ
fastcgi_read_timeout 120;
#location / {
#fastcgi_pass unix:/run/go/go-fcgi.sock;
location ~ ^/demo.*/(.*)\.go$ {
fastcgi_pass unix:/run/go/$1.sock;
#fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
}
}
# go build goweb.go
# mv /var/www/◇◇/go-demo.w4c.work/demo/goweb /opt/goweb
mv: `/opt/goweb' を上書きしますか?
y
# go build goweb5.go
# mv /var/www/◇◇/go-demo.w4c.work/demo/goweb5 /opt/goweb5
1サービスに付き,1つ起動させる仕様
[Service] ExecStart 複数
・出来ない
# vi /etc/systemd/system/goweb.service
# systemctl restart goweb.service
# systemctl restart nginx.service
・serviceタイプUnitの設定ファイル
・systemdを用いたプログラムの自動起動 - Qiita
centos - CentOS7サービス登録する際、[Service] ExecStartで複数起動指定したい - スタック・オーバーフロー
・linux - Systemd with multiple execStart - Stack Overflow
・Controlling a Multi-Service Application with systemd - Ales Nosek - The Software Practitioner
3
# go build goweb.go
# mv /var/www/◇◇/go-demo.w4c.work/demo/goweb /opt/go/goweb
mv: `/opt/go/goweb' を上書きしますか?
y
サービス経由で起動すると、ソケットファイルが1つしか作成されない
# systemctl restart goweb.service
直接起動すると、ソケットファイルは複数作成される
# /opt/go/goweb
バイナリの種類を指定するも、効果なし
# env GOOS=linux GOARCH=amd64 go build goweb.go
# mv /var/www/◇◇/go-demo.w4c.work/demo/goweb /opt/go/goweb
mv: `/opt/go/goweb' を上書きしますか?
y
# systemctl restart goweb.service
・go buildとクロスコンパイル - Qiitanamed files must be .go files
# go build -o /opt/go/gowec gowec.go
・named files must be .go files · Issue #107 · gpmgo/gopm · GitHub1
$ sudo go build -o /opt/go/a1 a1.go
$ sudo go build -o /opt/go/a2 a2.go
$ sudo -s
# vi /etc/systemd/system/goa1.service
[Unit]
Description = go web start
[Service]
ExecStart = /opt/go/a1
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
# vi /etc/systemd/system/goa2.service
[Unit]
Description = go web start
[Service]
ExecStart = /opt/go/a2
Restart = always
Type = simple
[Install]
WantedBy = multi-user.target
# systemctl restart goa1.service
# systemctl restart goa2.service
http://go-demo.w4c.work/demo/a1.go
http://go-demo.w4c.work/demo/a2.go