恥知らずのウェブエンジニア -web engineer, shameless

これは一歩を踏み出すことができない者たちのブログ

jenkinsの表示が真っ白になった、そんな時の解決法

ある日、jenkinsにアクセスしたら、表示が真っ白になりました・・・

テキストは表示されるのですが、css,imageが404になっておりレイアウトが崩れてました。

事象

  • jenkinsの表示で、cssやimageが404になり、真っ白の表示になる

原因

  • jenkinsのuiのファイルが、/tmp以下に作られるのでサーバーの設定によってファイルが削除されるため

対応方法

  • 【取り急ぎ系】jenkins再起動すればuiファイルは作りなおされます
  • 【根本解決】Javaのオプションでtmpファイルを作る場所を別に指定する必要があるようです


参考にさせて頂きましたm(_ _)msnickerjp.blogspot.jp


普通にJENKINS_HOMEの下に作ってくれればいいのに・・・



感謝致します。

f:id:ogataka50:20150513180812j:plain

理論から学ぶデータベース実践入門を読んだメモ

読んだので気になった点をいくつかメモ。

全体としては、
RDBのもととなっているリレーショナルモデルの解説と、
それを軸にRDBでよく起きる問題に対する解説がされているようなイメージでした。

タイトル通り理論が中心で読み物っぽい印象。

肝心のリレーショナルモデルは書いてあることの意味はわかるんですが、
まだまだ実感をもってはら落ちするまでできなかったので、
いつかRDBで行き詰まった時に読み直してみたいです。

以下、気になった箇所メモ。

インデックス

  • インデックスは左端から順にソートされる
  • 左端の文字からindexを作成していく
    • WHERE LIKE "a%" => index効く
    • WHERE LIKE "%a%" => index効かない
  • 複合インデックスの場合も左端から順にソートされるので、カラムの並び順が重要

パーティショニング

  • 範囲やキーでパーティショニングを分割
  • パーティショニングが適しているケース
    • キーのカーディナリティが低い場合
    • それ以外の場合はインデックスで十分な場合が多い
    • 最新のデータへのアクセスが多いアプリの場合、日付でパーティショニングするのは有効。パーティショニングごとにindexが作成されるので
  • インデックスはクエリが決まってから検討する
  • 下記の場合は、インデックスを貼らずにテーブルスキャンをしたほうがよいケースがある
    • 実行頻度が低い
    • テーブルのサイズが小さい
    • 検索結果が非常に多くの行にヒットする

インデックスの付け方

  • where句から

SELECT * FROM t WHERE col1 > 100 AND col2 = 'abc';
(col1, col2)の複合インデックスより、(col2, col1)のほうが効率がいい
col1 > 100 は膨大な数ヒットする可能性がある

  • join,サブクエリでもインデックスは有効なので、joinする条件サブクエリのWHERE句からインデックスを検討する

ソート

  • WHERE col1 = 100 AND col2 = 200 ORDER BY col3

という条件なら、インデックス(col1, col2, col3)でインデックスだけで解決できる
インデックスはcol1 -> col2 -> col3の順でソートされ作成されているので、
WHERE col1 = 100 ORDER BY col3
になると遅くなる

ORに対するインデックス

  • WHERE col1 = 100 OR col2 = 200

の時は(col1),(col2)の2つのインデックスが必要。インデックスマージされ検索される

インデックスはカラムの並び順が重要

  • 同じカラムの組み合わせでも並び順が異なるインデックスを作る時がよい時もある

カーディナリティ

  • WHERE句でcol1,col2,col3が条件となっていても、col1,col2でカーディナリティが高ければ、(col1, col2)だけのインデックスで十分なケースもある。
    • インデックスが増えれば、更新時のオーバーヘッドが発生するため。

インデックスは

  • どのカラムを含めるべきか、カラムのカーディナリティ、テーブルのサイズ、更新時のオーバーヘッド、クエリの実行頻度から総合して考える


やはりインデックスとかすぐに実践できる系のやつが気になっちゃます><


感謝致します。

f:id:ogataka50:20150506143458j:plain

PHPerが始めるgo言語入門 〜言語仕様〜

続いてgo言語の言語仕様を確認していきます。
五月雨でアレですが。

コメントアウト

1行
//

複数行
/*

*/

行末のセミコロン

ステートメント最後のセミコロンは省力可能。コンパイラが適切に挿入してくれる

インポート

import (
	"fmt"
	"strings"
)

import (
    f "fmt" //fという別名を使う
    _ "os" // _は対象パッケージを使わないことをコンパイラに明示する。使っていないパッケージがあるとコンパイルエラーになる
    . "strings" // .でパッケージ名を省略できる
)

変数の宣言

var 変数名 型 = 値
var message string = "hellow world"

複数同時に宣言

var hoge, foo, bar string = "hoge", "foo", "bar"

var (
	a string = "a"
	b		 = "b"
	c		 = "c"
)
同じ型なら2つ目以降は省力可能

関数内部での変数宣言

:=で型推論で宣言できる

func main() {
	// 同じ意味
	// var message string = "hello world"
	message := "hello world"
	fmt.Println(message)
}

定数

constで定数に
const Message string = "hello world"

初期値なしで宣言

var i int // i = 0
int => 0
float => 0.0
bool => false
string => ""
配列 => 要素0の配列
構造体 => プロパティが0の構造体
その他 nil

if文

if hoge > foo {
	
} else if hoge < foo {
	
} else {
	
}

3項演算子はなし
if1行だけもなし

ループ

ループはforだけ

for i := 0; i < 10; i++ {
	
}

いわゆるwhile的なfor
i := 0
for i < 10 {
	fmt.Printf("i = %d\n", i)
	i++
}

break,continue

i := 0
for {
	i++
	if i > 10 {
		break //ループ抜ける
	}

	if i % 2 == 0 {
		continue //偶数なら次のループへ
	}
	fmt.Println(n)
}

switch文

switch i {
	case 1:
		fmt.Println("1")
	case 2, 4:
		fmt.Println("2 or 4")
	case 5 < i:
		fmt.Println("greater 5")
	default
		fmt.Println("default")
}

switchで比較もオッケー
phpだとcaseに入ってもbreakを書かないと次のcaseへ進むが、golangは1つcaseが実行されたら、switchを抜ける
逆に1つcaseを実行されても次のcaseに行きたい時は[fallthrough]と書く

switch i {
	case 1:
		fmt.Println("1")
		fallthrough
	case 2, 4:
		fmt.Println("2 or 4")
		fallthrough
	default
		fmt.Println("default")
}

関数

func 関数名(引数 型) 戻り値の型 {
	
}


func sum(i, j int) { //sum(i int, j int)
	fmt.Println(i + j)
}


func sum(i, j int) int { //sum(i int, j int)
	return i + j
}
func main() {
	n := sum(1, 2)
	fmt.Println(n) //3
}


func change(i, j int) (int, int) {
	return j, i
}
func main() {
	x, y := 3, 4
	x, y = change(x, y)
	fmt.Println(x, y) //4 3
}

名前付きの戻り値

func div(i, j int) (result int, err error) {
	if j == 0 {
		err = errors.New("divied by zero")
		return // return 0, errと同じ
	}
		result = i / j
		return // return result, nilと同じ
}

無名関数

func main() {
	func(i, j int) {
		fmt.Println(i + j)
	}(2, 4)
}

配列

goの配列は固定長
var arr1 [4]string //4つの要素がある配列
arr[0] = "a"
arr[1] = "b"
arr[2] = "c"
arr[3] = "d"
fmt.Println(arr[0]) // a

// 宣言と同時に初期化
// どちらも同じ
arr := [4]string{"a", "b", "c", "d"}
arr := [...]string{"a", "b", "c", "d"}

関数に配列渡す時は値渡し

スライス

可変長の配列
var s []string

s := []string{"a", "b", "c", "d"}
fmt.Println(s[0]) // "a"

値追加
var s []string
s = append(s, "a") // 追加した結果を返す
s = append(s, "b")
s = append(s, "c", "d")
fmt.Println(s) // [a b c d]

s1 := []string{"a", "b"}
s2 := []string{"c", "d"}
s1 = append(s1, s2...) // s1にs2を追加
fmt.Println(s1) // [a b c d]

range

先頭から順番に処理
いわゆるforeach的な感じ

arr := [...]string{"a", "b", "c", "d"}

for i, s := range arr {
	// i = 添字, s = 値
	fmt.Println(i, s)
}

値の切り出し

s := []int{0, 1, 2, 3, 4, 5}
fmt.Println(s[2:4]) // [2 3]
fmt.Println(s[0:len(s)]) // [0 1 2 3 4 5]
fmt.Println(s[:3]) // [0 1 2 3]
fmt.Println(s[3:]) // [3 4 5]
fmt.Println(s[:]) // [0 1 2 3 4 5]

可変長引数

phpでもこういうのできるようになりますね
可変長で引数を取ることができる
func sum(nums ...int) (result int) {
	// numsは[]int型
	for _, n := range nums { //添字は捨てる
		result += n
	}
	return
}

func main() {
	fmt.Println(sum(1, 2, 3, 4)) // 10
}

マップ

ハッシュ的なやつです
キーと値で、格納

var month map[int]string = map[int]string{}

month[1] = "January"
month[2] = "February"
fmt.Println(month) // map[1:January 2:February]

month := map[int]string{
	1: "January",
	2: "February",
}
fmt.Println(month) // map[1:January 2:February]


値の取得
jan := month[1]
fmt.Println(jan) // January

2つ目の戻り値に値があるかboolで返してくれる
_, ok := month[1]
if ok {
	// データがあった場合
}

マップから情報を消すのはdelete

delete(month, 1)
fmt.Println(month) // map[2:February]

かなり雑でアレですが。。。



感謝致します。
f:id:ogataka50:20150421003559j:plain

PHPerが始めるgo言語入門 〜インストール〜 

これまでperlちょぴり、ほぼphpでお仕事をしてきたのですが、
このままだともろもろ幅が広がらない危機感を感じていました。

とはいえ、C,javaとかやるのもなー
rubyやってもなー
な感じで行動に移していなかったのですが、
最近go言語が広まりつつあり、
静的型付け,コンパイルで処理が高速,並列処理が容易とのことで、
phpとは違う知識がつけれそう+おいおい仕事にもつながる可能性もありそうなので、
ちょっと本腰入れて取り組んでみようと思います。


なので、何はともあれインストールから。

Go言語のインストール - golang.jp
こちらを参考にインストール

  • ソースをDL、解凍
  • PATH設定
  • インストール確認

ソースはこちらから
Downloads - The Go Programming Language

cd /usr/local
wget https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz
tar -xzf go1.4.2.linux-amd64.tar.gz

vi /etc/profile
    export PATH=$PATH:/usr/local/go/bin
go version
go version go1.4.2 linux/ad64

でインストール完了!

続いてhello world

hello.goを作成します。

vi hello.go

package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

実行してみます
go runでコンパイルせずに実行できるそうです。

go run hello.go

>hello, world

問題なさそうです。

今回は一旦ここまで。
次回からは、

  • 言語仕様の確認
  • 並列処理してみる
  • WEBアプリつくってみる

とかとかやっていければと思います!



以上となります。

感謝致します。
f:id:ogataka50:20150419221410j:plain

Mackerelで3分で始める簡単サーバー監視~apache,mysql,redisとか監視~

前回に引き続きMackerel的なアレを。


Mackerelで3分で始める簡単サーバー監視 - 恥知らずのウェブエンジニア

今回は監視対象にapache,mysqlなどのミドルウェアの状況を監視対象にしてみます。
手順は簡単でメジャーなミドルウェアであれば、公式のプラグインがあるので、
それをインストールして、ちょっぴり設定を修正するだけです。

公式プラグインインストール

まるっとyumでインストール

yum install mackerel-agent-plugins

ソースもgithubで公開されています。

mackerelio/mackerel-agent-plugins · GitHub

apache

mackerel-agent-plugins/README.md at master · mackerelio/mackerel-agent-plugins · GitHub
公式の通りにserver-statusにアクセスできるようapacheのconfを修正します。

Listen 1080
ExtendedStatus On
<VirtualHost 127.0.0.1:1080>
  <Location /server-status>
      SetHandler server-status
  </Location>
</VirtualHost>

/etc/mackerel-agent/mackerel-agent.confに下記のように追記します。
/usr/local/bin/mackerel-plugin-apache2 -p 1080を直接実行することで結果等も確認できます

[plugin.metrics.apache2]
command = "/usr/local/bin/mackerel-plugin-apache2 -p 1080"
type = "metric"

mysql

mackerel-agent-plugins/mackerel-plugin-mysql at master · mackerelio/mackerel-agent-plugins · GitHub
デフォルトだとrootで実行されるので、専用のユーザを一応作りました。

GRANT ALL PRIVILEGES ON *.* TO mackerel@localhost IDENTIFIED BY '****' WITH GRANT OPTION
GRANT ALL PRIVILEGES ON *.* TO mackerel@127.0.0.1 IDENTIFIED BY '****' WITH GRANT OPTION

FLUSH PRIVILEGES

またまた/etc/mackerel-agent/mackerel-agent.confに下記のように追記します。

[plugin.metrics.mysql]
command = "/usr/local/bin/mackerel-plugin-mysql -username=mackerel  -password=****"
type = "metric"

redisとか

同じ要領で/etc/mackerel-agent/mackerel-agent.confに下記追記しました。というかコメントアウトを解除。

# Plugin for Linux
[plugin.metrics.linux]
command = "/usr/local/bin/mackerel-plugin-linux"

# Plugin for Redis
#   By default, the plugin accesses Redis on localhost.
#   Currently AUTH password has not been supported yet.
[plugin.metrics.redis]
command = "/usr/local/bin/mackerel-plugin-redis"


でこれらが終わったらmackerel-agentを再起動。

sudo /etc/init.d/mackerel-agent restart 

もし失敗した際は、/var/log/mackerel-agent.logを確認してください。
またApikeyがconfの下に書いてある場合は、上部に持ってくる必要があるみたいです。



これだけでリソースなど下記のようにグラフ化されます。
開発サーバーなので、動きがなくてアレですがちゃんとモニタリングできているようです。
f:id:ogataka50:20150222222501p:plain

f:id:ogataka50:20150222222526p:plain

なんて簡単・・・
ありがたいです。




感謝致します。
f:id:ogataka50:20150222223029j:plain

Mackerelで3分で始める簡単サーバー監視

会社などでは、サーバーの監視でzabbixやnagios、muninなどが使われているかと思いますが、
個人や小さいプロジェクトでは特にサーバー監視などしてないことも多いのはないでしょうか。

自分も個人のはサーバー監視していない状態でした。
特に必要が出たわけでもないのですが、Mackerelで簡単に監視できるそうなのでやってみました。

Mackerel(マカレル)とは

サーバーの監視やアラート、グラフ化をしてくれるサービスです

Mackerel: 新しいアプリケーションパフォーマンスマネジメント

手順

  1. Mackerel登録
  2. mackerel-agentをインストール
  3. サービスとかロールを設定

Mackerel登録

何はともあれ登録します。
普通に登録するだけです。
Mackerel: 新しいアプリケーションパフォーマンスマネジメント

mackerel-agentをインストール

監視対象のサーバーにmackerel-agentをインストールします。
mackerel-agentが定期的に諸々の情報をMackerelに送るようです。

スタートガイドのままです。

//リポジトル追加
curl -fsSL https://mackerel.io/assets/files/scripts/setup-yum.sh | sh
//yumでインストール
sudo yum install -y mackerel-agent

//設定ファイルにapikey追記
sudo sh << SCRIPT
cat >>/etc/mackerel-agent/mackerel-agent.conf <<'EOF';
apikey = "***********************"
EOF
SCRIPT

//agent起動
sudo /etc/init.d/mackerel-agent start

サービスとかロールを設定

サービスはそのままサービスやプロダクト単位のもを設定
ロールはwebとかdbなどサーバー単位の役割を登録します

そしてそれらをサーバーに紐付けます。


これだけで完了・・・

f:id:ogataka50:20150221221901p:plain
これだけで↑的な基本的なサーバーリソースの監視とアラートの設定等ができます。
会社的にやるとなるとセキュリティ的なアレですんなり行かないかもしれないですが、
個人の場合はありがたく使わせて頂きたいですね!


通知もメールやhipchat,slackにも送れるとのこと。
またプラグインを入れることでapachemysqlの監視もできる模様。
データをAPIに送ることで任意のデータの監視等も可能だそうです。

次はapache,mysqlの監視をしてみたいと思います。


監視といえばコレ

Denki Groove - Nothing Gonna Change [Berlin ...


感謝致します。
f:id:ogataka50:20150221222726j:plain

jenkinsでLDAP認証とジョブごとの権限設定

jenkinsは便利ですが、最初の「とりあえずやってみようぜ」的な流れのまま、
そこそこ危険なジョブも誰でも実行できたりと権限周りがアレな状態なので整理してみました。

なので、認証はLDAPを使い、LDAPのグループで大まかな権限設定行い、
細かいのはジョブごとに権限設定してみました。

バージョン

Jenkins 1.598
LDAP Plugin 1.11

LDAP認証設定

普通にGUIから設定

  • Jenkins -> Jenkinsの管理 -> グローバルセキュリティの設定
  • ユーザ情報 -> LDAPをチェック
  • LDAP情報設定
設定項目 内容
サーバー LDAPサーバー(必要あればポートも) 10.9.**.***
root DN 検索するroot dc=hoge_ldap
Group search base 検索対象のグループ ou=hoge_Group
Group search filter 検索グループフィルター cn=*_hoge

※最初は権限管理を「全員に許可」にしておいてから、LDAPログインできるか確認する。
もし設定に不備があると、ログインできなくなる可能性があります。
その場合、/var/lib/jenkins/config.xmlを直接修正する必要があります。

グループごとの権限設定

グループごとの権限設定は、Jenkins -> Jenkinsの管理 -> グローバルセキュリティの設定から行います

  • 権限管理 -> 行列による権限設定(プロジェクト単位)にチェックを入れる
  • 対象のグループごとに権限を設定(ここの設定でおおまかな設定を行い、後述のジョブごとの設定で細かい設定を行う)

ジョブごとの権限設定

  • 各ジョブの設定 -> 権限設定(プロジェクト単位)の有効化をチェックする
  • ここでジョブごとにグループの権限を設定します。

これで取り急ぎ、誰でも何でもできるとかjenkinsだけユーザ作るとかは必要なくなりそうです。


感謝致します。

f:id:ogataka50:20150217143251j:plain