write ahead log

ロールフォワード用

golangでTwitterもどき書いた

デザインを考える段階でいつも飽きる.

リファクタリングもテストも書いてないけど, 自分用のサンプルコードぐらいにはなるしGitHubに入れておいた.

github.com

CentOS7でsystemdを使ってgolangで作ったプログラムをデーモン化する

0. 始めに

CentOS7で試します.

UbuntuUpstartを使った例の延長です.

UbuntuでUpstartを使ってプログラムをデーモン化する

1. プログラムを作る

プログラムは前回と同様のサンプルを使います.

挨拶するだけの単純なものです.

package main

import (
        "net/http"
        "fmt"
)

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

func helloHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello\n")
}

これをhelloというプログラム名でビルドします.

$ go build -o hello

2. Unitファイルを作る(ディレクトリ位置)

CentOS7の場合は下記に作ります. 他のOSも同じかな?調べてませんが.

/etc/systemd/system

実は下記にもUnitファイルがあり, 上記を優先して利用する仕組みだそうです.

/usr/lib/systemd/system

管理者が変更する場合は/etc下へコピーして変更で運用するようです.

3. Unitファイルを作る(作成)

シンプルな例を探して試しました.

これを

/etc/systemd/system/hello.service

として保存します.

;はコメント
#もコメント

[Unit]
# 説明文
Description = Hello Server            

[Service]
# サービス起動時のコマンド
ExecStart = /opt/hello-svr/hello      

# サービス停止コマンド$MAINPIDはメインプロセスのPID参照に利用できる
ExecStop = /bin/kill -HUP $MAINPID    

# サービス再起動コマンド$MAINPIDは上述通り
ExecReload = /bin/kill -HUP $MAINPID && /opt/hello-svr/hello 

# alwaysを指定するとプロセスが死んだ際に常に自動起動する
# デフォルトのnoなら死んだまま
Restart = no                          

# 起動完了の判定条件.
# フォアグラウンドで起動するプログラムはとりあえずsimpleでいい様なので指定.
# forkしてコマンドが終わるタイプはforkingにすればいいらしい
Type = simple                         


[Install]
# 旧来のrunlevelの概念にあたるようです.
# multi-user.target: runlevel:3に相当
# graphical.target: runlevel:5に相当
# 他はman読む方がよさそう
WantedBy = multi-user.target

4. プログラムの配置

当然ですが.

$ sudo cp ~/hello /opt/hello-svr/hello

5. Unitの認識を確認

$ sudo systemctl list-unit-files --type=service | grep hello
hello.service                                 disabled

6. 自動起動をONにする

$ sudo systemctl enable hello

7. サービスを起動する & 確認する

$ sudo systemctl enable hello
Created symlink from /etc/systemd/system/multi-user.target.wants/hello.service to /etc/systemd/system/hello.service.
$ systemctl status hello
● hello.service - Hello Server
   Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: disabled)
   Active: active (running) since 月 2017-07-17 19:03:03 PDT; 21s ago
 Main PID: 30660 (hello)
   CGroup: /system.slice/hello.service
           └─30660 /opt/hello-svr/hello

8. 動作チェック

$ curl localhost:8080
Hello

9. サービスを再起動する

$ sudo systemctl restart hello

10. サービスを停止する

$ sudo systemctl stop hello

感想

他にも色々出来そうですが, とりあえず今はこれが精一杯.

参考

Systemdを使ってさくっと自作コマンドをサービス化してみる

Systemd入門(4) - serviceタイプUnitの設定ファイル

man systemd.unit の訳

ubuntuにvim8をソースからインストールする

aptで入れるvimは7系で古かったのでソースから入れた.

1. ソースを取得

# git clone https://github.com/vim/vim

2. ncurses-devを入れる

必要といわれるので

# aptitude install ncurses-dev

3. configureを実行

オプションは好みでセッティングなんでしょうが, よくわからない部分も多いので適当にサイトを回ってある程度最低限っぽいものに絞りました.

./configure \
 --enable-fail-if-missing \
 --with-features=huge \
 --disable-selinux \
 --enable-cscope \
 --enable-fontset \
 --enable-multibyte

4. makeを実行

まぁ, 普通に.

# make

5. make installで配置

こちらもまぁ, 普通に.

# make install

6. alias入れとく

.bashrcか.bash_profileを編集する.

alias vi=/usr/local/bin/vim

golangをvimで書くためにプラグイン入れた

プラグインは使わない主義でずっとやってきたけど, 便利すぎるので流石に負けた.

ついでにMarkdownも良く書くからプラグイン入れた.

1.Vundleのインストー

git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

2. vimrcを編集する

" Plugin設定
" vundle.vimを使う
set rtp+=~/.vim/bundle/Vundle.vim/
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'

" golang用
Plugin 'fatih/vim-go'
Plugin 'nsf/gocode', {'rtp': 'vim/'}

" Markdown用
Plugin 'godlygeek/tabular'
Plugin 'plasticboy/vim-markdown'

call vundle#end()

3. プラグインのインストー

まず, vimを開きます.

$ vim

インストールコマンドを実行

:PluginInstall

プラグインが依存するgoコマンドのインストール.
(これ, すごい機能)

:GoInstallBinaries

4. 使ってみる

golint

lintできます.

:GoLint

gofmt

保存するだけでfmtされます

godef

カーソル位置で以下のコマンドを打つと, 定義へジャンプ出来るようになります.
(Windows10 + Msys2だと正しく動かなかった…..)

:GoDef

コード補完

C-x + C-o でオムニ補完に対応できるようになりました.

5. [余談]vimrc全体

ずいぶん変わった.

gistadcec8abec12ad3398d0

退屈だしgolangでmemcachedサーバもどき作った

memcached, 使ったことないけどね.

最近仕事はExcelばかりで, 面白くないので.

f:id:twinbird_htn:20170713231329g:plain

github.com

感想とか

分散はしないし, クライアントは無いしでなんか中途半端感がある.

本当は分散させたりしてみたいんだけど, 今の自分には厳しそう.
DHTとかそのうちやりたいかも.(ChordとかCANとか)

とはいえネットワークプログラミングってあまり経験がないので, 楽しめた.
(コマンド解析がすごい適当だったのが唯一心残りかも)

あとはまぁ月並みだけど, goroutineはこの手の処理書くのには便利かなと.

簡単な割に楽しめるので, 好きな言語とか新しく始める言語でちょろっと作るのにはおすすめかもしれないです.

完璧に作ろうとすると大変だけどね.

参考文献

さくらインターネットの解説.さすが詳しい.ここでの知識が7割占めてる.

memcachedプロトコルについて « さくらインターネット研究所

公式の解説.例外系とかはやはり本家が良い.

memcached/protocol.txt at master · memcached/memcached · GitHub

CentOS7にMariaDBを入れる

最初から入ってるかもしれない.

簡単だったけど, やったことなかったしメモ.

1. yumでインストー

入ってたら必要なさそうだけど.

# yum install mariadb mariadb-server

2. エンコーディング指定を変える

UTF8へ.

必要ならどうぞ.

# vi /etc/my.cnf

[mysqld]
....
character-set-server=utf8   #<= 追記

3. systemctlに設定

# systemctl enable mariadb.service
# systemctl start mariadb.service

4. Mariadbの初期セットアップ

# mysql_secure_installation

[Y/n]がたくさん出るけど手抜きの時は基本全部[Enter]
rootパスワードだけは入力した.
解説が親切なので特別心配も要らない.

5. 接続確認

普通にmysqlコマンド使えるんすね.

# mysql -u root -p
Enter password:[rootのパスワード]
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 5.5.52-MariaDB MariaDB Server

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

表示がMariaDBになっててようやく気付くレベル.

互換性意識されててよい.というかまぁ, forkだもんね.

DBマイグレーションツール gooseを使う

データベースのマイグレーションツールで自分に合ったのを探していて, 割といいのを見つけたので使い方をメモしておく.

自分としては

  1. SQLで書ける
  2. 開発言語に依存しない
  3. 開発環境に依存しない
  4. テストデータ投入まで規約がある

を備えているのが欲しかった.

gooseは最後の以外は満たしているのでかなりいい感じ.

インストー

ここは定番で.

$ go get bitbucket.org/liamstask/goose/cmd/goose

ただし, Windowsの場合SQLiteを使うせいかビルドエラーになる.

$ go get bitbucket.org/liamstask/goose/cmd/goose
# bitbucket.org/liamstask/goose/cmd/goose
C:\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1
/usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingwex が見つかりません
/usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingw32 が見つかりません
/usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingwex が見つかりません
/usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingw32 が見つかりません
collect2: エラー: ld はステータス 1 で終了しました

ここで書いた時の現象と一緒だし, たぶんそう.

解決するにはTDM GCCを入れてコマンドプロンプトからgo getを実行しなおせばいい.

(MSYS2だと動作しないので注意.たぶんCygwinもじゃないかなぁ)

設定

何がともあれディレクトリを作ります. 名前はdbでないとダメなようで.(-pathオプションで変えられますが)

$ mkdir db

設定ファイルが必要になるが, 面倒なのでサンプルをコピーしてくる.

$ cd db/
$ cp $GOPATH/src/bitbucket.org/liamstask/goose/db-sample/dbconf.yml ./

後は接続先に合わせて変更する.

サンプルはPostgresだったので, ここではMySQLにしておく.
(mymysqlは誤植ではない, 使うgolangのドライバを明示的に指定している)

development:
    driver: mymysql
    open: [DB名]/[ユーザ名]/[パスワード]

MySQLにログインして, データベースも作っておきましょう.

> CREATE DATABASE demo;

接続確認のために状態確認する.

$ goose status
goose: status for environment 'development'
    Applied At                  Migration
    =======================================

使う

ここまで来るとかなり単純.

というか単純なものが欲しかったんだけど.

テーブルを作る(upする)

マイグレーションファイルを作るには以下のコマンドを使います.

$ goose create [テーブル名] sql

とりあえずUsersテーブルを作ってみる.

$ goose create users sql
goose: created C:\msys64\home\twinbird\dropbox\lab\sample\db\migrations\20170623171909_users.sql

出来たファイルを編集.

$ vi db/migrations/20170623171909_users.sql

こんなのが出来てます.シンプルでいいっすね.

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied


-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

それぞれ編集します.

-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied

CREATE TABLE users(
    id SERIAL,
    name varchar(20),
    email varchar(20)
);

-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

DROP TABLE users;

いよいよ, マイグレーションしましょう.

$ goose up
goose: migrating db environment 'development', current version: 0, target: 20170623171909
OK    20170623171909_users.sql

うまくいきました.

戻す(downする)

そのままです.

$ goose down
goose: migrating db environment 'development', current version: 20170623171909, target: 0
OK    20170623171909_users.sql

バージョンを見る(dbversion)

バージョンはタイムスタンプそのままみたいですね.

$ goose dbversion
goose: dbversion 20170623171909

最新バージョンに上げ直す(redo)

過去のコミットまで戻った時は便利そうです.

$ goose redo
goose: migrating db environment 'development', current version: 20170623171909, target: 0
OK    20170623171909_users.sql
goose: migrating db environment 'development', current version: 0, target: 20170623171909
OK    20170623171909_users.sql

感想

自分が求めていたものが大体満たされていて非常に良い感じ.

自作しようかと思っていたけど, 作らなくてよかった.

ドキュメント読むとGo Migrationsってのもあるけど, これは使いそうにないなぁ.