OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu + Nginx + Puma + Rails5

#はじめに
一度やったら当分やらないようなインフラ設定の方法ってどんどん忘れていく。

というわけで、
ubuntu + unix + puma + rails5
構成を立ち上げるまでの備忘録です。

# unicorn と pumaの違いみたいな話
このあたりが参考になる。今回はPumaを選択しました。

Unicorn vs. Puma vs. Passenger: which app server is right for you?
http://blog.scoutapp.com/articles/2017/02/10/which-ruby-app-server-is-right-for-you

#version

$ nginx -V
nginx version: nginx/1.4.6 (Ubuntu)
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) 

$ rails -v
Rails 5.1.4

& puma --version
puma version 3.10.0

#やること

rubyapp -> puma -> nginx
という風に、socketの場所をpumaとnginxに設定することでrubyappをnginxから見れるようにする。
(下記の図のUnicornとpumaを入れ替えて考える)
あとpumaを起動するfileを用意するみたいな感じ。

![alt](http://blog.honeybadger.io/images/2015/07/socket-1024x541.png)
http://blog.honeybadger.io/how-unicorn-talks-to-nginx-an-introduction-to-unix-sockets-in-ruby/

#pumaの設定

railsのアプリディレクトリの中に
ファイルは存在しているのでsockで通信できるようにするために下記設定を足す

```ruby:app/config/puma.rb
_app_path = "#{File.expand_path("../..", __FILE__)}"
_app_name = File.basename(_app_path)
_home = ENV.fetch("HOME") { "/home/ubuntu" }
pidfile "#{_home}/run/#{_app_name}.pid"
bind "unix://#{_home}/run/#{_app_name}.sock"
directory _app_path
```

pidが出力されるdirを作る

```
mkdir /home/ubuntu/run/
```

#nginxの設定

nginxの場合はconf.dにアプリ名+.confというファイルを設置すると
設定を読み込んでくれる.


その前に
デフォルトだと
/etc/nginx/sites-available/defaultという
デフォルトファイルを設定に読みに行っていつまでたってもnginxの.htmlを読みにいくので、
書きをコメントアウトする必要がある。(またはdefaultを消す)

```/etc/nginx/nginx.conf
#コメントアウトする
#include /etc/nginx/sites-enabled/*;
```

```/etc/nginx/conf.d/appname.conf
upstream appname {
    server unix:///home/ubuntu/run/appname.sock;
}
```

```/etc/nginx/conf.d.appname.conf
server {
    listen 80;
    server_name 192.168.0.1; # 本番環境のipアドレス
    root /home/ubuntu/appname/public; # アプリケーション名
    location / {
        proxy_pass http://appname; # アプリケーション名
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    access_log /var/log/appname.access.log;
    error_log /var/log/appname.error.log;

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}
```
##再起動
```
& sudo service nginx restart
```

#起動ファイルの作成

```/etc/init.d.puma
#!/bin/bash

NAME=puma
USER=ubuntu
APP_NAME=appname
APP_DIR=/home/$USER/$APP_NAME
TMP_DIR=$APP_DIR/tmp
PID_DIR=$TMP_DIR/pids
SOCKET_DIR=$TMP_DIR/sockets
LOG_DIR=$TMP_DIR/logs
PUMA_BIN=/home/$USER/.rbenv/shims/puma

RAILS_ENV=staging

sudo -u $USER -H sh -c "mkdir -p $PID_DIR"
sudo -u $USER -H sh -c "mkdir -p $SOCKET_DIR"
sudo -u $USER -H sh -c "mkdir -p $LOG_DIR"

PIDFILE=$PID_DIR/puma.pid


start() {
  cd $APP_DIR;
  sudo -u $USER -H sh -c "echo \$\$ > $PIDFILE; RAILS_ENV=$RAILS_ENV $PUMA_BIN -C $APP_DIR/config/puma.rb -d"
}

stop() {
  echo -n "Stopping puma"
  kill -s SIGTERM `cat $PIDFILE`
}

restart() {
  stop
  start
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  *)
    N=/etc/init.d/$NAME
    echo "Usage: $N {start|stop|restart}" >&2
    exit 1
    ;;
esac
```
##起動
```
$ sudo /etc/init.d/puma start
```

#参考
https://www.gakusmemo.com/?p=608
mysqldumpでdumpしながらgzip圧縮をしつつSSHで別ホストに転送する

よく忘れて調べ直すのでメモ。というか単なる備忘録。
たぶんもっといい方法があると思うし、時と場合によって使い分けるべきかと。


#### ダンプ
```bash
/usr/bin/mysqldump -u[ユーザ名] -p[パスワード] --single-transaction --master-data --routines --databases [データベース名] [データベース名] [データベース名...] | gzip | ssh [転送先ホスト] 'cat > [だんぷファイル名.dump.gz]'
```

|オプション                   |説明                                                                   |
|:--------------------------:|:--------------------------------------------------------------------:|
|--single-transaction        |ロックせずにダンプを取得するオプション|
|--master-data               |スレーブ側からダンプする際に、マスター機のポジションデータも含めるオプション|
|--routines　                |ルーチンを再作成するためのCREATE PROCEDUREおよびCREATE FUNCTION文が含まれるオプション|
|--databases                 |複数データベースを指定するオプション|

gzipで圧縮しながらSSHに流し込むので、CPUをかなり食う。
ディスク領域やネットワーク帯域に余裕があるのなら、gzip圧縮せずに流したほうが速いかもしれない。

#### gzip圧縮したダンプファイルのリストア

```bash
zcat [だんぷファイル名.dump.gz] | mysql -u[ユーザ名] -p[パスワード]
```


毎回みてる参考ページ

mysqldump の結果をそのまま圧縮したり転送したりするコマンド例
http://bashalog.c-brains.jp/10/09/30-183733.php
AndroidStudioでjarファイルを作る


Android Studio 2.3.2 でJarファイルの作り方を簡単に説明します。

# 手順
Android StudioではJARファイル(Java Library)を単品で作る事は無理みたいなので、最初に適当なプロジェクトを作った後に、サブプロジェクトとしてJarファイル用のプロジェクトを作る必要があります。


## 適当なプロジェクトを作る

Jarを作るための捨てプロジェクトです。
デフォルトのままでもOKですが、分かりやすいように適当な名前をつけます。

Apllication Name: MyLibApp
Company Domain: com.qiita
最小SDK: 19
アクティビティは`Empty Activity`辺りを選択してフィニッシュ


## 次にJava Libraryのプロジェクトを作ります。
`File -> New -> New Module`を開く
`Java Library`を選択してNextを押す

![1.javalibrary2.png](https://qiita-image-store.s3.amazonaws.com/0/112253/73a316ef-efaa-273b-2d8d-41f8440a2115.png)


Library name: myLibrary
java class name: MyClass


![2.javalibrary2.png](https://qiita-image-store.s3.amazonaws.com/0/112253/917b56ab-639f-502e-7b6e-8dafbf678ee2.png)



にしてフィニッシュ


出来上がったクラスには何もありません。
そのままビルドしてjarを作っても良いですが折角なのでHelloWorldを追加します。

```java
package com.qiita;

public class MyClass {
    public void SampleMessage() {
        System.out.println("Hello World!");
    }
}
```



Gradle project を開きます(`View -> Tool Windows -> Gradle`からでもOK)
`:mylibrary -> Tasks -> build -> jar` をダブルクリックします。

![gradle_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/112253/ea6727a7-7822-f3f8-b565-8cba2e2064ae.png)









`MyLibApp/mylibrary/build/libs`にjarファイルが出来ています。
Router and Switch difference

而Router及Switch的功能是不一樣，Router主司路由，也就是該封包要怎麼被轉送到另一個子網路，而Switch是用於區域網路的交換，在區域網路裡，設備之間是用MAC去溝通而不是IP，另外，Switch的交換速度是很快的，路由器是相對較慢的。2012年3月26日

來源https://www.ithome.com.tw/node/72872

http://bluemuta38.pixnet.net/blog/post/45543357-%E9%9B%86%E7%B7%9A%E5%99%A8%28hub%29%E3%80%81%E4%BA%A4%E6%8F%9B%E5%99%A8%28switch%29%E3%80%81ip%E5%88%86%E4%BA%AB%E5%99%A8%E3%80%81%E8%B7%AF%E7%94%B1%E5%99%A8

http://blog.xuite.net/arcloveangel/lovestore/18474133-%E3%80%90%E7%B6%B2%E8%B7%AF%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98%E3%80%91%E8%B7%AF%E7%94%B1%E5%99%A8%28Router%29%E3%80%81%E4%BA%A4%E6%8F%9B%E5%99%A8%28Switch%29%E3%80%81%E9%9B%86%E7%B7%9A%E5%99%A8%28Hub%29%E7%9A%84%E5%88%86%E5%88%A5
AWSのウェブサイト構築チュートリアル解説を作ってみた はじめに

#経緯
会社で勉強会でAWSをやることになり、教えてもらったチュートリアルを使って環境構築を行った。
分かりやすいチュートリアルだったが、作業の意味などが書かれていないので、その部分を忘れないように解説形式で残すことにした。

#チュートリアルの前にすること
・アカウント作成
・アラート設定(課金が気にならない人はやらなくてもいい)
　※アラートは通知が来るだけでサービスを停止したりはしない。
　　上限を超えた通知が来たらAWSの請求コンソールで状況を確認し、必要に応じてインスタンスの停止などを行うこと

#チュートリアル
https://aws.amazon.com/jp/getting-started/projects/scalable-wordpress-website/

※チュートリアルの環境構築あと、インスタンスなどが残っていると課金が続く。チュートリアル内の後片付けを確認し、不要なインスタンス等は削除すること。

#チュートリアル全体の概要
以下の流れでAWSでWEBサービスの構築と拡張の基礎手順を学べる。
１．単一のwordpressインスタンスを作成
２．DBを別インスタンスに分離
３．WEBサーバの拡張しロードバランサーを設置
４．スレーブDBの追加

#解説
フェーズ1: サーバー 1 台構成で WordPress 環境を構築
https://qiita.com/towtow/items/f17b30571a53ebf3ef9b

フェーズ2: 拡張性を向上しつつ、DB 運用負荷を軽減する構成を構築(作成中)

フェーズ3: ロードバランサーを使った負荷分散環境を構築(作成中)

フェーズ4 （オプション）： フェーズ 3 の環境でスレーブ DB を追加（Amazon RDS を Multi-AZ 構成に変更）(作成中)
AWSのウェブサイト構築チュートリアル解説を作ってみた STEP1「サーバー 1 台構成で WordPress 環境を構築」

前：https://qiita.com/towtow/items/aeda3dab395b8ede2408

#チュートリアルページ
https://aws.amazon.com/jp/getting-started/projects/scalable-wordpress-website/01/
※チュートリアルに従って環境構築をして放置した場合課金状態が続く。
　作業後はチュートリアル内の後片付けを確認し、インスタンス等を必ず消しておくこと。

#チュートリアルの概要
ここでは、AWSのネットワークを新規作成し、そこにwordpressのインスタンスを作成するまでの作業を行う。
ネットワークに関しては、フェーズ2以降の構成のため、アベイラビリティーゾーン別にサブネットを生成している。本来なら、拡張が必要になったタイミグで別アベイラビリティーゾーン上にサブネットを生成する流れになるだろう。

#フェーズ 1-1: コンソールへのログインと VPC（ネットワーク） の作成
まずは今回の環境のVPC(仮想ネットワーク)作成を行う。このVPC上にAP、DBサーバのインスタンスを構築していくことになる。
チュートリアルでは、「1つのパブリックサブネットを持つVPC」を選んで作成しているため、ここでパブリックサブネットも同時に作成される。

#フェーズ 1-2: サブネットを追加作成
フェーズ２以降で使用するサブネットを生成している。
別々のアベイラビリティーゾーン(データセンター)に分けることで、片方のアベイラビリティーゾーンが使用できなくなった場合でもサービスが停止しないようにしている。
ここでは、パブリックサブネットとプライベートサブネットを作成している。パブリックサブネット上に作成したものがインターネット上に公開できるサーバとなり、プライベートサブネット上に作成したものはVPC上からのみアクセスできるサーバとなる。

#フェーズ 1-3: Amazon EC2 インスタンスの作成
今回は最初からwordpressがインストールされたインスタンスを使用し、最初にVPCとともに生成したパブリックサブネット上にインスタンスを配置する。
まずは、１つのインスタンスでwordpressを起動できる状態を作り、そこから冗長化を行っていく。
また、作成したインスタンスへのログインをキーペアで行うため、キーペアの作成も行っている。

#フェーズ 1-4: Elastic IP（固定 IP）の割り当て
外部から参照するためのパブリックIPを設定する。ここで割り当てたIPを使い、インターネット上からインスタンスに対してアクセスする。
Elastic IPはAWS上で未使用のIPが取得される。そのためいったん解放してから再取得すると別のElastic IPが取得される。
※Elastic IPを設定した時点で誰でもインスタンスに対してアクセスできる。しっかりセキュリティをかけていない場合はElastic IPをむやみに公開しないこと。

#フェーズ 1-5: WordPress のセットアップ
ブラウザ上からWordPressのセットアップを行い、接続確認をする。
※説明がわかりにくいが、DBのパスワードはwordpressを指定すれば次へ行ける。このDBはあとのフェーズで無効化するのでとりあえずパスワードを気にしなくてもいい。
ブラウザ上から設定後、SSHクライアントを使いログインして、RPMパッケージをアップデートしている。
※「sudo yum update」は「管理者権限でRPMパッケージをアップデート」を実行するコマンド。用語集に一応詳細を記述したが、分からない人は調べてほしい。

#用語解説
・VPC
AWSの仮想ネットワーク構成を指す。このVPC上にAP、DBサーバのインスタンスを構築していくことになる。
ネットワークの大枠と考えればよい。なおVPCはAWSの独自の名称である。

・EC2
AWS上で仮想マシンを生成するサービスのこと。

・EC2 インスタンス
AWS上で生成された仮想マシンのこと。EC2が「仮想マシンを生成するサービス」でインスタンスが「生成された仮想マシン」を示す。

・リージョン
今回の環境が物理的にどのエリアにあるかを示す。またVPCを作成する場合、リージョンは1つしか指定できない。
※ただし、リージョンごとにVPCを作成し、それを繋ぐことは可能。今回のチュートリアルではそこまでやらない。

・アベイラビリティーゾーン
リージョン内の個々のデータセンターを示す。例えば「リージョン：日本、アベイラビリティーゾーン：AAA東京」ならば、
現在の環境が「日本のAAA東京というデータセンター」に有ることになる。
※1つのVPCの中に複数のアベイラビリティーゾーンを持つことは可能。チュートリアルでも2つのアベイラビリティーゾーンを指定している。

・サブネット
VPCの中でさらに分割したネットワーク。サブネットごとにアベイラビリティーゾーンやインターネットへの公開、非公開などの設定ができる。

・パブリックサブネット
インターネットへアクセスできるサブネット。APサーバ等はここに配置する。

・プライベートサブネット
インターネットに公開していないサブネット。DBサーバ等をここに配置し、同一のVPC内部の別サブネット等からアクセスして使用する。

・キーペア
秘密鍵とそれに対応する公開鍵を使った認証方式の１つ。事前に対応するキーを生成しておき、ログイン時に対応するキーを指定することでログインできる仕組み。

・Elastic IP
AWSで割り当てられるグローバルIPアドレス。これにインスタンスを紐づけることで外部からIPアドレスを通じてインスタンスにアクセスできるようになる。
チュートリアルではwordpressのサーバとElastic IPを紐づけることでアクセスできるようにした。

・SSH、SSHクライアント
SSHはサーバーとやり取りする際の通信プロトコル。
SSHクライアントは、SSHで通信するためのクライアント側のツール。
SSHクライアントはいろいろな種類があるので、好きなものを使用すればよい。

・RPM（Redhat Package Manager）パッケージ
Red Hat系Linaxのアプリケーションと設定ファイル、ドキュメントなどがまとめられたもの。このパッケージに対してインストール、アップデート、アンインストールなどを行う。
　
・sudo
Linuxコマンドの1つで、一時的に別ユーザの権限でコマンドを実行するためのコマンド。一般的にはroot(管理者)ユーザの権限で実行するために用いられる。

・yum
Linuxのパッケージを取得して操作を行うためのコマンド。「yum コマンド」の形式でコマンドを入力する。
Tableauメモ

随時更新

# MAKEDATEは抽出でしか使えない（Tableau10.3現在）
データソースとの接続がライブの場合、MAKEDATEは使えないのでDATEや、DATEPARSEで代用する必要がある。
## 例
MAKEDATE(2014, 3, 18) → DATE('2014/3/18')
# nullなセルを0として集計する
zn(lookup(sum([目的の値]),0))
参考：http://akiyah.hatenablog.com/entry/2016/04/27/003026
擬似クラス　カラムレイアウトでの留意点

# 要件に縛られたカラムレイアウトでの留意点
カラムレイアウトに対して、擬似クラスを用いることで感覚的にレイアウトを適用できるが、複数のデザインパターン（要件）がある場合、適用方法など留意点があるので投稿いたします。

## 純粋な２カラムレイアウト
２カラムの間のボーダーを適用するのに
- nth-child(odd){border-right: ...}か
- nth-child(even){border-left: ...}かどちらを選択するか

![image.png](https://qiita-image-store.s3.amazonaws.com/0/192967/84f1742d-3ebe-fca6-9a64-aab31962df64.png)
見た目だけで考えればどちらを適用しても同じです。
（box-sizing: border-boxは適用されてるとする）

ですが、「画像が一枚になって、真ん中に寄るパターンもあり得る」という要件が増えることを想定したとき、画像が一枚でもnth-child(odd){border-right}は適用されてしまいます。  
このことから、２カラムの間のボーダーを適用するのには、
nth-child(even){border-left: ...}を選択する方が適切だと考えます。 

## 連結した2カラムレイアウト
画像と説明文を１つのリンク範囲内、かつ、画像間と説明間のボーダー色が違う場合、
border-leftの適用をどの要素に持たせるのか
![image.png](https://qiita-image-store.s3.amazonaws.com/0/192967/4277c641-fe5d-6d3c-a517-c7c070ce4759.png)

```html
<ul class="list">
  <li class="item">
    <a class="link">
      <div class="gazou">画像</div>
      <div><p class="desc">画像に対する説明</p></div>
    </a>  
  </li>
	<li class="item">
    <a class="link">
      <div class="gazou">画像</div>
      <div><p class="desc">画像に対する説明</p></div>
    </a>
  </li> 
</ul>
```

```css
.item:nth-child(even) .gazou {
  border-left: solid 1px white;
}
.item:nth-child(even) .desc {
  border-left: solid 1px gray;
}
```

挙動に関しては、[擬似クラス nth-childとnth-of-typeの特徴と違い](https://qiita.com/kudo_kk/items/8277c1f0eae18e15dd64)をご確認いただければ、説明は不要かと思います。



パーシャル化されたcss等を使用していて、様々なデザインパターンに適用させたい場合、自由に整数値指定（nth-child(2)など）できないため、このような手段が必要になってくるかと思います。
絶賛マサカリ募集中。
ASTRIA Div1000関数

会計では,単位調整のため1000で割ることが何度もあります.
関数を作ったのですが、非常に苦労したのと非常に有用なのでUPしてみました。

以前にも、単純な関数を作ったことはあります。
[ASTERIAで日付同士の差引きを求めるには？](https://qiita.com/nacopon/items/2e67406469d999eacfc0)

# 会計ではDecimal型を使うことが基本です.
Decimal型のデメリット
計算速度が遅い

Decimal型のメリット(Integer型の欠点の裏返し)
計算が正確(IntegerならBanker Roundとかありえる)
扱える範囲が大きい(Integer型は21億ぐらいで限界です。好調な中小企業でも、売上高21億ぐらいはあるのでしょう)

特に扱う範囲が大きい会計系や勘定系では,Integer型を使わないのが通例です.


# 単純な1000で割る関数を作ってみた.
![ETL-2017-10-23-2.png](https://qiita-image-store.s3.amazonaws.com/0/180419/a9eb46c0-1eae-f930-282c-3a028890c889.png)

てんとう虫絵柄のシミュレーションを使うと,ダミーデータをわざわざ作らなくて済むので便利です.

```
15000 ÷ 1000 = 1.50000000 
0 ÷ 1000 = 0.00000000
(空文字) ÷ 1000 = 0.00000000    ★
-15000 ÷ 1000 = -1.50000000 
```

空文字を1000で割ると0になってしまう。
**0とNULLを明確に分ける会計の世界では, 非常に不都合.**

★の結果が
(空文字) ÷ 1000 = (空文字)
になるように作り直してみた。

# 新しく作った関数
![ETL-2017-10-23-4.png](https://qiita-image-store.s3.amazonaws.com/0/180419/ab71c4eb-0b5b-8664-7a31-a47a22927c4f.png)

## 関数内では, Branch系Switch系のコンポーネントが使えないらしい.

条件分岐は、Ifコンポーネントで,
その結果をChoiceコンポーネントで受けてあげるといいようだ.

ただこれらのヘルプを読んでも正直よくわからない...
[Ifコンポーネントのヘルプ](http://stgetlweb01.infosys.cyberagent.local:21381/help/ja/flow/designer/index_function.html#IF.html)
[Choiceコンポーネントのヘルプ](http://stgetlweb01.infosys.cyberagent.local:21381/help/ja/flow/designer/index_function.html#CHOICE.html)

## 空文字かどうかの判定
RegexpMatchコンポーネントの
正規表現の値を **^$**  とすればよい。

 
== の絵柄のEqualコンポーネントを
"" や(空文字) でしても,空文字に反応しなかったので注意が必要である.


個人的にはめちゃくちゃ良く使う関数になりました.
kitchen-docker を断念した人は kitchen-dokken を試してみよう

# Test Kitchen ドライバに kitchen-dokken を使う

## 確認環境
- Ubuntu 16.04, macOS Sierra
- ChefDK v2.3.4
- (テスト対象: Ubuntu 16.04)

## kitchen-dokken
Chef Cookbook のテストフレームワークである [Test Kitchen](http://kitchen.ci/) のドライバの一つで、docker を使った仮想環境で Cookbook テストができるもの。デフォルトのドライバである Vagrant よりも高速に仮想環境を立ち上げられる。

### kitchen-docker ? dokken ?
[`kitchen-docker`](https://github.com/test-kitchen/kitchen-docker) ではなく、[**`kitchen-dokken`**](https://github.com/someara/kitchen-dokken)。パット見で野良ドライバに見えてしまいそうだが、[ChefDK](https://docs.chef.io/kitchen.html) にも同梱されておりちゃんとメンテされているドライバである。kitchen-docker のハマりどころに対応した、provisioner の限定されたドライバになっている。 

※ 自分は kitchen-docker の `service` 周りでハマることが多かった (`Errno::ENOENT: No such file or directory - /sbin/status` や service `:enable` 系) が、kitchen-dokken では解消できた


VM ではないのでコレひとつで完全なテスト環境になるものではないが、`kitchen-docker` よりはコンテナ固有の問題にハマりにくく、特定のケースでは `kitchen-vagrant` の良い代替になると思われる。

## 設定
### ローカルテストおすすめ設定

なるべく余計なところでハマらないように

- `pid_one_command` を指定する
- カスタマイズされた [dokken-images](https://github.com/someara/kitchen-dokken#using-dokken-images) を使う
- privileged コンテナを使う
- verifer には InSpec を使う
- (kitchen-dokken に限らないが) ChefDK パッケージで一式インストールする

```
---
driver:
  name: dokken
  chef_version: latest

transport:
  name: dokken

provisioner:
  name: dokken

verifier:
  name: inspec

platforms:
  - name: ubuntu-16.04
    driver:
      image: dokken/ubuntu-16.04
      privileged: true
      pid_one_command: /sbin/init

suites:
  - name: default
    run_list:
    - recipe[mycookbook::default]
    verifier:
      inspec_tests:
        - test/smoke/default
```

### 注意
#### Verifier

https://github.com/someara/kitchen-dokken#tmpfs-on-tmp にあるように、Bats や Serverspec を使う場合は `verifier` の指定がいる。

```
verifier:
  root_path: '/opt/verifier'
  sudo: false
```

### あくまでコンテナ

環境が docker コンテナゆえに daemon 系プログラムや networking の挙動は期待通りにならないかもしれない。Chef を使うときは VM を想定していることが多いと思うので、そういった場合の受け入れテストとしては使えない。
ISUCON7に参加したのでその雑記

# ISUCONとは

http://isucon.net/
WEBサービスのチューニングのうまさを点数化して全国で競い合うコンテスト

# 今回の問題

今回はチャットシステムでした

* ユーザー登録・編集
* チャットグループの作成
* チャット閲覧・投稿

運営から3台サーバを渡されて自由に使って良いという感じ
一応2台アプリケーションサーバ、1台DBサーバという感じ

# チーム

チーム名: バナナマンさん
言語: `Ruby`

去年・一昨年と同じチームで挑みました（[去年の記事](https://qiita.com/yamamoto_hiroya/items/b8113931a662721e6bf5)）
毎年付き合ってくれる2人に感謝

* ミドルウェア・インフラ周り担当
* アプリケーション担当
* DB担当

みたいなざっくりした分担で臨みました
僕はDB担当

# やったこと

* 土曜9時半に集合したものの運営のトラブルにより開始が13時にズレる
* 午前中とても暇だったがゆっくりレギュレーション読み直したりチームメンバーと方針・分担の最終確認ができたりとそこそこ有意義だった
* 待ち時間中のDiscordのチャットのやりとりが面白かった
* 13:13開始
* 開始1時間は当日マニュアルの熟読、アプリケーション構造の把握、WEBアクセスしアプリの仕様把握、ソースをgit管理、DBをSequelProで接続しtableの把握、などの下準備
* とりあえず初期状態でベンチ走らせたら素の状態で7000点出て瞬間最高1位を記録！ｗ
* その後rubyに切り替えて実行したところ初期スコア4000点
* ようやく出揃ったところでミドルウェア担当がボトルネック調査用のツール群を入れ始める
* その間にアプリケーションソースを読む
* iconがくっそ重い、N+1クエリが結構な数ある、インデックス貼られてないところがある…というのがパッと分かったこと
* 2時間経過くらいで作戦会議、iconをnginxで静的ファイルとして返す・N+1クエリ直す・インデックス貼る、という方針でいくことに
* アプリケーション担当がN+1クエリを直すのに苦戦していたので手を貸すことに（何回ベンチ走らせてもベンチツールがエラーを吐く…）
* デバッグしないと埒が明かなかったので手元にsinatraの環境を構築、sinatraを普段使いしてないので手間取った…
* ruby配下のソースだけ持ってきてもだめで、その上に配置されていたpublicを持ってこなきゃいけなかったのでscp
* 手元で動くようにしてようやくデバッグ開始→MySQLのエラーだったりrubyのエラーだったりとまちまちだった
* その間にiconの静的ファイル化が完了しベンチ→12000点にアップ
* `/fetch`アクションのN+1クエリを解消→15000点にアップ
* アプリケーションが落ち着いたのでようやくDBに戻る、channel_idやmessage_idなど主要なところにインデックスを貼る→23000点
* `/fetch`の`sleep`を外してみる→効果なし
* このあたりで徐々に点数が停滞しはじめる…（18時頃）
* その後他のN+1クエリを直すも効果なし
* 土壇場になってRedis導入しキャッシュ化しようとしたがうまくいかず
* 結局最後はベンチマークツールのブレ幅を見て複数回ベンチガチャを回して29000点をマークしたところで終了

瞬間最高1位の図
![スクリーンショット 2017-10-21 13.53.07.png](https://qiita-image-store.s3.amazonaws.com/0/67471/17b782f1-fdb1-6100-d738-aded565b25fb.png)

# 結果

| 初期スコア | icon静的化 | N+1解消 | インデックス付与 | 最終スコア |
|:-:|:-:|:-:|:-:|:-:|
| 4097  | 12438  | 15558  | 23297  | 29758 |

# 感想と反省

* 瞬間最高1位を記録できたのがよかった
* 開始遅れによりモチベのチューニングに失敗し、18時過ぎたあたりから集中力がガクッと落ちた（言い訳とも言う）
* `Sinatra`の素振りが足りなかった
* インデックス付与後のアクションが鈍かった
* キャッシュ化に着手するのが遅かったし`Redis`の素振りも足りなかった
* ベンチマークツールのブレ幅が結構あり、修正が効いてるのかどうか判断に迷うことが多かった
* 前回はgit管理→プルリク→マージのフローを採用してスピードに欠けていたので今回はgit管理→セルフマージで行うことでスピードは出た
* ただしスピードが出た分failになる頻度が高く、結果としてやりたい改修になかなか着手できなかった
* サーバ上でvimで直接編集してもデグレしない力が欲しいと感じた
* 一言にキャッシュ化と片付けていたが基本的な知識が足りない気がする…
* 開始1時間での目のつけどころは予選突破チームとほぼ一緒なので、着眼点は良かったが改修する力が足りなかった

# おわりに

今回も問題・ベンチツールの仕様が全然違うので直接点の比較はできないですが、前回15000点だったのが29000点に上がったので着実に上ってるという感じでした
今年は参加するかどうか悩んだが、やはり参加すると楽しい:smile:
来年出るかどうかは微妙なところですが、機会があれば是非出たいと思います！
Macでのenvsubstの利用について

## 概要
Macでenvsubstコマンドを利用しようとしたら、
コマンドが無いと言われて使えなかったので調べた内容をメモする。

## envsubstコマンド
Macでコマンドを実行してみるとエラーになりました。

```sh:ターミナル
$ envsubst --version
-bash: envsubst: command not found

$ gettext --version
-bash: gettext: command not found
```

インストールされていないかと思い、インストールを実行してみる

```sh:ターミナル
$ brew install gettext
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
No changes to formulae.

Warning: gettext 0.19.8.1 is already installed
```

既にインストール済みとのことですが、コマンドは見つからないというエラーは改善せず。
下記参考サイトを参考に、brew link コマンドを実行してみる。

* [envsubst: command not found on Mac OS X 10.8](https://stackoverflow.com/questions/23620827/envsubst-command-not-found-on-mac-os-x-10-8)

```sh:ターミナル
$ brew link --force gettext 
Linking /usr/local/Cellar/gettext/0.19.8.1... 185 symlinks created

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.bash_profile
```

パスが通ったようで、コマンドが使えるようになった。

```sh:ターミナル
$ which gettext
/usr/local/bin/gettext

$ which envsubst
/usr/local/bin/envsubst
```

以上

## 参考サイト
* [Mac App Store - Install gettext on Mac OSX](http://macappstore.org/gettext/)
* [envsubstを使ってDockerで設定ファイルに環境変数を埋め込めこむ汎用的なパターン](https://qiita.com/minamijoyo/items/63ae57b99d4a4c5d7987)
* [低機能でポータブルなテンプレートエンジンが欲しい→そこでenvsubstですよ](https://qiita.com/hnw/items/3d8bad7852510c3a84d7)
* [gettext - GNU Project - Free Software Foundation (FSF](https://www.gnu.org/software/gettext/)
* [Wikipedia - gettext](https://ja.wikipedia.org/wiki/Gettext)
* [gettext のコマンドラインツールを使おう: SuperTuxKart を例に](https://qiita.com/okano_t/items/da2ba18a65f46b31b699)
Headless CMS

## **Headlessとは？**

---

## **Google先生に聞いてみる**

```
グラフィカルユーザインタフェースなしで
デバイス上で動作することができるソフトウェアである。

このようなソフトウェアは、入力を受け取り、
ネットワークなどを介して出力を提供します。
```
Wikipedia - Headless software
※ https://en.wikipedia.org/wiki/Headless_software

---

## **Headless CMSとは**
（ <font color="green">デカップルドアーキテクチャ</font>とも言われる ）
　
言葉から推測すると

```
REST APIを使ってコンテンツを提供するCMS
```

※VIEWなどのプレゼンテーション機能なし

---

## **利用されている場所**

CMSを提供するアプリで積極的に推進

* <font color="green">Plone</font> (Python)
* <font color="green">Drupal</font> (PHP)
* <font color="green">WordPress</font> (PHP)

など

---

## **Headless CMSの実現**

・ <font color="green">フロントエンドとバックエンドの分離</font>
　 (decouple)
・ <font color="green">REST API準拠のストレージバックエンドの作成</font>
　 (APIファースト)
・ <font color="green">コンテンツを全てAPI経由で提供する</font>
　 (Content as a Service)

---

## **HeadlessCMSの背景**

ユーザー体験の向上 (様々なチャネルへの配信)

* ウェブサイト
* シングルページアプリ
* ネイティブアプリ
* ウェアラブルデバイス
* 音声アシスタント端末

---

## **これまでのCMS**

![current.png](https://qiita-image-store.s3.amazonaws.com/0/142279/90b78435-5f2e-e52d-d290-d9ed23a4ff18.png)
こんな感じが・・・

---

## **Headless CMS**

![structure.png](https://qiita-image-store.s3.amazonaws.com/0/142279/2b0c4a5f-dedc-794a-afc5-d2519a2c6ee8.png)
こんな感じに・・・

---

## **今までのコンテンツ配信との違い**

　
　<font color="green">補助的な仕組み</font> として扱われていた
　（ RSS、Atom ... ）
　　　　　　　　　↓　↓　↓
　<font color="green">あらゆる表示をAPI経由でCMSから取得</font>する
　※ APIファーストを主軸とする考え方

---

## **HeadlessCMSのメリット**

・ <font color="green">フロントエンド側の自由度が高まる</font>
　※ PHP,JavaScript,アプリなど自由に開発可能

・ <font color="green">配信対象の拡大</font>
　※ いろいろなチャンネルへ配信可能

・ <font color="green">フロントとバックエンドの開発分離</font>
　※ 片方に集中でき、専門的になる(高機能)

---

## **HeadlessCMSのデメリット**

・ <font color="green">開発が専門的になり、開発工数が増加する</font>
　※ RESTful APIなど専門的な知識が必要
　（使い勝手の良いAPI → 設計が難しい）

・ <font color="green">APIの品質への要求が高い</font>
　※ 速度低下や高負荷対策(cache, scale)
　※ 不正アクセスや攻撃への対応

---

## **まとめ**

・APIファーストで魅力的なアーキテクチャ

・小規模のサイト開発には合わない（コスト大）

・学習コスト、開発コストが高い
　※ RESTful APIなど専門知識
　※ APIを使っても無理のないUI設計
　（ 好き勝手なUI設計は、ページ速度↓ ）

---

## 参考資料
* [Toward a 2017 Plone Roadmap](https://plone.org/roadmap/2017-plone-roadmap/)
* [WordPress as a Headless CMS](https://blog.daftcode.pl/wordpress-as-a-headless-cms-b4144c626695)
* [ヘッドレスCMSとは何者か？](https://www.10nin.com/20170317.html)
* [マルチデバイス・OneToOneマーケ時代のCMS](https://webtan.impress.co.jp/e/2017/05/23/25810)
* [Headless CMSというトレンドにDrupalは...](https://annai.co.jp/article/api-first)
* [Dupalにおけるデカップルド・アーキテクチャ](https://knowledge.sakura.ad.jp/5776/)
* [PloneをHeadlessCMS化](http://sssslide.com/speakerdeck.com/zenich/plone-wo-headless-cmshua-dekatupurudoakitekutiya-nituitefalsekao-cha)
* [Content as a Service](https://ez.no/jp/Blog/6)
AWS-CLIの初期設定のメモ

## 概要
aws-cliを使い始めたので、設定について軽くメモを残す。

## AWS-CLI準備
下記マニュアルを参考に、awsコマンドをインストールしてコマンドが使えるようにする。

![aws-cli.png](https://qiita-image-store.s3.amazonaws.com/0/142279/bf7a1006-4f31-28c4-52c4-4c27a841aae0.png)
※ [AWS CLI のインストールと設定](http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)

### aws-cliインストール（Mac)
Windowsの場合は、マニュアルに記載されている MSIのダウンロード を参照

```sh:ターミナル
$ sudo pip install awscli

or

$ brew install awscli
```

### aws-cliインストール（Linux)
Linux環境にインストールする場合の例です。

```sh:ターミナル
# pythonのバージョン確認 (Python 2.6.5+ or Python 3.3+ )
$ python --version

# pipインストール
# ※ --user で、pipのスクリプトを ~/.local/bin にインストール
$ curl -O https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py --user 
$ echo export PATH='~/.local/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
$ pip --version

# aws-cliインストール
# ※ --user で、pipのスクリプトを ~/.local/bin にインストール
$ pip install awscli --upgrade --user
$ aws --version
```

**インストールを確認**

```sh:ターミナル
$ which aws
/usr/local/bin/aws

$ aws --version
aws-cli/1.11.174 Python/2.7.10 Darwin/16.7.0 botocore/1.7.32
```

### aws-cliの設定

```sh:ターミナル
$ aws configure --profile user1
AWS Access Key ID [None]: {アクセスキー(各自)}
AWS Secret Access Key [None]: {シークレットアクセスキー(各自)}
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## IAMユーザーを確認してみる

```sh:ターミナル
$ aws iam list-users
{
    "Users": [
               ・
               ・
               ・
    ]
}
```

## IAMグループを確認してみる

```sh:ターミナル
$ aws iam list-groups
{
    "Groups": [
               ・
               ・
               ・
    ]
}
```

## プロファイルの確認

現在のプロファイル（デフォルト）

```sh:ターミナル
$ aws configure list
```

指定のプロファイル

```sh:ターミナル
$ aws configure list --profile user1
```

## プロファイル切り替え（一時的）

```sh:ターミナル
$ aws s3 ls --profile user1
```

## プロファイル切り替え（デフォルト）

```sh:ターミナル
# デフォルト変更
$ export AWS_DEFAULT_PROFILE=user1

# 確認
$ aws configure list
```

または、

```sh:ターミナル
# デフォルト変更
$ export AWS_PROFILE=user1

# 確認
$ aws configure list
```

## 参考資料
* [AWS CLI のインストールと設定](http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)
* [Linux に AWS Command Line Interface をインストールします](http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/awscli-install-linux.html)
* [AWS CLIのインストールから初期設定メモ](https://qiita.com/n0bisuke/items/1ea245318283fa118f4a)
* [AWS CLIで使える認証情報とオプションの設定方法まとめ](https://dev.classmethod.jp/cloud/aws/how-to-configure-aws-cli/)
* [AWS CLI 環境変数チートシート](https://qiita.com/n-oshiro/items/4a7774ee6e1d11bb55d2)
* [awscliの設定切り替え](https://qiita.com/ryuzee/items/e3ce493f132f1981f57a)
* [【AWS】CLIの初期設定について（認証情報とコマンド補完）](http://www.task-notes.com/entry/20141026/1414322858)
* [AWS ドキュメント - Linux に AWS CLI をインストールする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-linux.html)
AWSのアカウントについてのメモ

## 概要
AWSを使い始めたので、初歩となるアカウントについて調べた結果をメモする。

## AWSアカウント
作成方法は、下記AWSのマニュアルを参照(省略)

![account.png](https://qiita-image-store.s3.amazonaws.com/0/142279/ac055884-f53f-56f5-5043-b43d8e6dc021.png)
※ [AWS アカウント作成の流れ](https://aws.amazon.com/jp/register-flow/)


## IAMユーザー作成
ユーザーは、各スタッフごとに作成
![iam-admin.png](https://qiita-image-store.s3.amazonaws.com/0/142279/b10ffb4e-ecf5-c33a-7bc8-bb90c30a1dc3.png)
※ [最初の IAM 管理者のユーザーおよびグループの作成](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/getting-started_create-admin-group.html)
　( 管理者 IAM ユーザーおよびグループの作成 (コンソール)を確認 )

## マネジメントコンソールへのログイン(IAMユーザー)
<font color="red">IAM → ユーザー → 各ユーザー</font> へ移動し、
「認証情報」タブをクリックしてサインイン認証情報を確認
![iam.png](https://qiita-image-store.s3.amazonaws.com/0/142279/505e1280-802d-9548-4835-b8a2ec47cb2f.png)
※ ユーザー作成の際、「AWS マネジメントコンソールへのアクセス」にチェック必要
※ コンソールログインのリンク の欄にあるURLへアクセス

## 参考資料
* [最初の IAM 管理者のユーザーおよびグループの作成](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/getting-started_create-admin-group.html)
* [IAMによるAWS権限管理運用ベストプラクティス](https://dev.classmethod.jp/cloud/aws/iam-bestpractice-1/)
* [AWS再入門 AWS IAM (Identity and Access Management) 編](https://dev.classmethod.jp/cloud/aws/cm-advent-calendar-2015-getting-started-again-aws-iam/)
* [AWSにおけるマルチアカウント管理の
手法とベストプラクティス](https://d0.awsstatic.com/events/jp/2017/summit/slide/D4T2-2.pdf)
Wordpress+Nginxのパーマリンク設定

#Wordpressでパーマリンク設定を変更すると404になる

誰もが経験したことのあるパーマリンク設定の404。
ページがナッシングだぜでお困りのそこのあなた。
Nginxの設定を書いておきます。

## Wordpressのパーマリンク設定

設定を以下のようにしてみた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/8f1d2d20-1ee8-360a-45b7-8522be5ed758.png)

これで、各個別記事、管理者画面、ログアウト画面で４０４になります。

## Nginxの設定

```/etc/nginx/conf.d/domainname.conf
server {
    listen       80;
    client_max_body_size 20M;
    server_name  domainname.net;
    root         /var/www/html/domainname;
    index        index.php index.html;

    location ~ \.php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME /var/www/html/domainname$fastcgi_script_name;
        #fastcgi_param  PATH_INFO $fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_read_timeout 180;
    }


    include /etc/nginx/default.d/*.conf;

    location / {
        try_files $uri $uri/ @wordpress;
    }
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html/domainname$fastcgi_script_name;
        include fastcgi_params;
    }

    location @wordpress {
        fastcgi_index index.php;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME  /var/www/html/domainname/index.php;
        include       fastcgi_params;
    }

    # redirect server error pages to the static page /40x.html
    #
    error_page 404 /404.html;
        location = /40x.html {
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

}
```



こんな感じにすると直りました。
Carthageでforkしたリポジトリを使う

# 概要

Carthageでforkしたリポジトリを使う方法を調べたので備忘録として残しておきます。

# 結論

- `rm -rf ~/Library/Caches/org.carthage.CarthageKit/`を実行(自分の場合はうまくいかなかったため)
- 下記のようにCartfileで指定して`carthage update`を実行

例

```text:Cartfile
github "EndouMari/TabPageViewController"
```

これを

```text:Cartfile
git "https://github.com/TakkuMattsu/TabPageViewController.git" "master"
```

追記
↓でもいけた ( @toshi0383 さんのコメントより )

```text:Cartfile
github "TakkuMattsu/TabPageViewController" "master"
```

のようにする

## 参考

- [Carthage always fetch the original repo instead the forked one?](https://github.com/Carthage/Carthage/issues/1204)
自宅サーバWindows化の際の作業メモ

基本は https://qiita.com/hayamiz/items/f4a889d0694a8b4cd077 に書いてあるものにしたがって必要なソフトウェアを入れている。

# パーティション構成

* 240GBのSSDをシステム領域にしてWindowsインストール
    * ほかのディスクはインストール時にはつながない（予約済み領域を勝手に作成されてしまう）
* 960GBのSSDx2 をWindowsのミラーリングボリュームで作成
    * Mirroring は Windows 10 Pro じゃないとできないので、Home の場合は Microsoft store からアップグレード版を購入する
    * コンピューターの管理からミラーリングボリュームを作成して、適当なドライブレターを割り当てる
    *
ランダムにごにょごにょする


Random一覧
https://docs.unity3d.com/jp/540/ScriptReference/Random.html


## Random.insideUnitCircle
https://docs.unity3d.com/jp/540/ScriptReference/Random-insideUnitCircle.html


半径1の円の中でランダムな位置を返す（2次元）

## Random.insideUnitSphere
https://docs.unity3d.com/ja/540/ScriptReference/Random-insideUnitSphere.html

半径1の球の中でランダムな位置を返す（3次元）

> 参考
http://blog.livedoor.jp/akinow/archives/51755954.html


## Random.onUnitSphere

https://docs.unity3d.com/jp/540/ScriptReference/Random-onUnitSphere.html

半径1の球の表面上でランダムな位置を返す（3次元）


## 比較

```c:RandomRotator.cs
using UnityEngine;
using System.Collections;

public class Done_RandomRotator : MonoBehaviour 
{
	public float tumble;
	
	void Start ()
	{
		// 回転速度も回転方向もランダム（3軸）
		GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere * tumble;

		// 回転速度も回転方向もランダム（2軸）
		GetComponent<Rigidbody>().angularVelocity = Random.insideUnitCircle * tumble;

		// 回転速度は一定で、回転方向はランダム（3軸）
		GetComponent<Rigidbody>().angularVelocity = Random.onUnitSphere * tumble;
	}
}
```

`angularVelocity`は、ずっと待っていると空気抵抗で止まる。
止めたくない場合は`Angular Drag`を0にする。

> 参考
[チュートリアル > スペースシューター > Creating hazards](https://unity3d.com/jp/learn/tutorials/projects/space-shooter-tutorial/creating-hazards?playlist=45993)



ユニティ・テクノロジーズ・ジャパン‏さんのツイート
https://twitter.com/unity_japan/status/471135621142945792

```
速度は同じだけどランダムな方向に剛体を飛ばしたい場合
Random.onUnitSphere

速度も方向もランダムにしたい場合
Random.insideUnitSphere
```

## その他

### Random.value

https://docs.unity3d.com/jp/540/ScriptReference/Random-value.html

returns float 0 ~ 1


### Random.Range

https://docs.unity3d.com/jp/540/ScriptReference/Random.Range.html

function (float min, float max)


### Random.InitState

https://docs.unity3d.com/jp/540/ScriptReference/Random.InitState.html

ゲームが再生されるたびに同じ "ランダム" パターンを生成したい場合
仕訳データの摘要から科目予測

会計ソフトからCSV形式でデータをエクスポートして、その内訳にある摘要から借方科目の予想をします。
CSVファイルをJTF-8に変換保存する。

import pandas as pd
filename = "siwake_utf2.csv"

df = pd.read_csv(filename, sep=',', skiprows=0)

読み込んだデータから「摘要」「科目」「科目名」の使用するデータを選択する。

columns = ["摘要", "借方科目", "借方科目正式名称"]
df_counts = df[columns].dropna()

摘要のデータについて形態素解析(Janomeをインストール）により、文字データをベクトル化します。
Azure IoT Hubのチュートリアルを動かす時のリンク集

# 準備
node.jsをセットアップする。

* [Macにnode.jsをインストールする手順。 - Qiita](https://qiita.com/akakuro43/items/600e7e4695588ab2958d)
* [High SierraにアップデートされたMacでHomebrewがうまく動かない時 - Qiita](https://qiita.com/takustaqu/items/65aa67286345baac363e)

# 参考リンク（実施順）
1. [Azure IoT Hub の使用 (Node) | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-node-node-getstarted#create-a-simulated-device-app)
* [IoT Hub メッセージを Azure データ ストレージに保存する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-store-data-in-azure-table-storage)
* [Azure IoT Hub から取得したリアルタイム センサー データの視覚化 – Power BI | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-live-data-visualization-in-power-bi)
* [Azure IoT Hub から取得したリアルタイム センサー データの視覚化 – Web Apps | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-live-data-visualization-in-web-apps)
* [Azure Machine Learning で IoT Hub からのデータを使用して天気予報を行う | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-weather-forecast-machine-learning)

# 注意事項
* PowerBIのアカウント作成はフリーメールは使用できません。企業・組織のメールアドレスが必要です。
Lollipopより前の端末でCardViewに余白が入らないようにする

CardViewを作成する際、Lollipopより前の端末だと、カード周りに余白が入ってしまいます。
もともと余白のあるデザインであればそんなに気になりませんが、ImageViewをカードいっぱいに持つデザインの場合には調整が必要です。

|Lollipop以降  |Lollipopより前  |
|---|---|
|<img src="https://qiita-image-store.s3.amazonaws.com/0/33071/5ddf0c1a-ee47-e88c-6294-f343e4cf4c71.png"/>|<img src="https://qiita-image-store.s3.amazonaws.com/0/33071/82374477-dcb8-c653-3233-54d73c716ad6.png"/>|

# 対応
SupportLibraryのバージョンが24.2.0以降であれば、CardViewへ

```xml
app:cardPreventCornerOverlap="false"
```
を追加するとLollipopより前の端末でも余白がなくなります。

https://developer.android.com/reference/android/support/v7/widget/CardView.html#setPreventCornerOverlap(boolean)

公式によると、「Lollipopより前の端末ではカードの角丸とカード上のViewの境界が重なるのを避けるために、勝手にPaddingを追加するよ」とあり、falseにするとPaddingを追加しなくなります。

> On pre-Lollipop platforms, CardView does not clip the bounds of the Card for the rounded corners. Instead, it adds padding to content so that it won't overlap with the rounded corners. You can disable this behavior by setting this field to false.

注意：これでPaddingはなくなるのですが、ImageViewが角丸になるわけではないので、[RoundedImageView](https://github.com/vinc3m1/RoundedImageView)ライブラリを使うなどして角丸にしてあげる必要があります。

# 補足
上記オプションは、Lollipop以降の端末には基本的に影響がありません。```app:cardUseCompatPadding="true"```を指定して、Lollipop前の挙動に設定している場合には、影響を受けます。

> Setting this value on Lollipop and above does not have any effect unless you have enabled compatibility padding.

# 参考
https://stackoverflow.com/questions/27668635/unnecessary-padding-in-cardview
BeanUtils#copyProperties()のソースリーディング

Commons BeanUtils 1.9.3 のうち BeanUtilsBean#copyProperties() のソースコードを読んだ記録です。この記事をご覧の方はご存知と思いますが、リフレクションを利用してオブジェクトの全プロパティをコピーするメソッドです。

* [公式](http://commons.apache.org/proper/commons-beanutils/)
* [GitHub](https://github.com/apache/commons-beanutils/tree/BEANUTILS_1_9_3/src/main/java/org/apache/commons/beanutils)
* [Javadoc](https://commons.apache.org/proper/commons-beanutils/javadocs/v1.9.3/apidocs/index.html?org/apache/commons/beanutils/BeanUtils.html)

# 目的
* Optional&lt;T> と T との相互変換に対応していないのでよろしくやらせたい。
  * → <font color="#800000">BeanUtilsBean を継承して手を加えるか同等のものを書き直さないと難しそう。 </font>
* @lombok.Builder への書き込みにも対応させたい。[^1]
  * → <font color="#000080">BeanIntrospector を書けば対応可能。</font>

[^1]: かつて[Lombok.Builderのメソッド名を変えるPR](https://github.com/rzwitserloot/lombok/pull/1066)もありましたが、お蔵入りになった模様

# 主要クラス
* BeanUtilsBean
  * PropertyUtilsBean : プロパティの get / set, PropertyDescrtiptor (メタデータ)管理
     * *BeanIntrospector* : オブジェクトの
 PropertyDescrtiptor を列挙
     * *Resolver* : 「path.to.value[2]」等の複雑なプロパティ名の解決
  * ConvertUtilsBean
     * *Converter*

BeanUtilsBean 以外はいずれもコンストラクタ引数や getter / setter で設定可能です。

# シーケンス図 (POJO 同士の場合)
上記の通り、プロパティの読み取り/書き込み自体は PropertyUtilsBean が行います。BeanUtilsBean のやっていることは PropertyUtilsBean / ConvertUtilsBean の呼び出しと一部ログ出力程度です。

![copyprops-seq.png](https://qiita-image-store.s3.amazonaws.com/0/207347/88413818-0e6e-d318-daed-909f82a951cc.png)

* PropertyUtils はリフレクション API の Method クラスを介してプロパティを読み書きします。
  * 元の dest, orig にないメソッドは呼ばせられません。
  * メソッド名自体は(それに対応した BeanIntrospector を書けば)なんでも良いです。
* Converter が引数に取るのは　Class オブジェクトです。
  *  Type 型ではないので、型パラメータは取れません。<br>(プロパティの型に当該ジェネリック型のサブクラスを指定した場合は別)
* 読み取り不能または書き込み不能なプロパティは単純に無視されます。

# シーケンス図 (DynaBean 同士の場合)
ResultSet 等に利用できる DynaBean というものがあって、こちらを使うと Proxy クラスの get / set メソッドを介してプロパティを読み書きさせられます。

![copyprops-dyna-seq.png](https://qiita-image-store.s3.amazonaws.com/0/207347/16ba7cc3-f1fd-542a-bafc-dfe4f912b6a2.png)

* なぜか BeanUtilsBean が DynaBean#get() を直接呼びます。

* WrapDynaBean はその名の通り通常の POJO をラップしたものですが、これを copyProperties() の引数に与えると下記の通り __アンラップした上で__ POJO と同様のアクセス権限チェックが行われるので注意が必要です。
  * WrapDynaBean を継承して元の POJO にないプロパティを追加しても恐らく無視されます。移譲すれば通ると思いますが。

```java:PropertyUtilsBean.java#L1374-1378
        // isReadable()
        // isWritable() も同様

        // Treat WrapDynaBean as special case - may be a write-only property
        // (see Jira issue# BEANUTILS-61)
        if (bean instanceof WrapDynaBean) {
            bean = ((WrapDynaBean)bean).getInstance();
        }
```
Python3でバスケット分析

#バスケット分析(basket analysis)

バスケット分析を使う機会があったので、Python3で簡単に実装したやり方をメモ。<br>
バスケット分析は簡単に言えば「同じカゴに入れられる品物を見つける」ための手法。<br>
[pyfpgrowth](https://pypi.python.org/pypi/pyfpgrowth)を使えばすごく簡単<br>
#Code
```Python:basket_analysis.py
import pyfpgrowth

#5人分の買い物リストを作成。2とか3とかが商品。それぞれのリストが買い物カゴだと思って欲しい。
buy_list = [[2,3,4,13,11],\
            [16,3,4,7,14],\
            [9,3,4,1,18],\
            [7,12,11,13,3],\
            [8,3,5,17,20],\
            ]

#分析開始
patterns = pyfpgrowth.find_frequent_patterns(buy_list, 3)
rules = pyfpgrowth.generate_association_rules(patterns, 0.7)

print(patterns)
print(rules)
```
実行結果
```
{(3,): 5, (4,): 3, (3, 4): 3}
{(4,): ((3,), 1.0)}
```
ここで気になるのは引数の値。<br><br>


find_frequent_patternsの__3__は出現回数を表してるっぽい。<br>
(3,): 5　→　「３は5回登場してますよ」<br>
(4,): 3　→ 「4は3回登場してますよ」<br>
(3, 4): 3　→「(3,4)のペアは3回登場してますよ」<br><br>

generate_association_rulesの__0.7__は信頼度。<br>
(4,): ((3,), 1.0)　→　「4が来て3が来る信頼度は1.0ですよ」<br>
Ubuntu16.04+NVIDIAドライバを入れた時のメモ

## 前提
### 環境
* PCは「mouse NEXTGEAR-NOTE i5730」
* スペックは下表の通り。

|            |Name or capacity              |
|:-----------|:----------------:|
|OS          |Windows 10 Home|
|CPU         |Intel® Core™ i7-7700HQ|
|GPU         |GeForce GTX 1070|
|メモリ|16GB|
|SSD|240GB|
|HDD|500GB|

* Windows 10 HomeはSSDにインストールされている。

### 目的
* Windows 10 HomeとUbuntu 16.04のデュアルブート
* Ubuntu 16.04にNVIDIAドライバ375とCUDA 8.0をインストール

## 本記事の概要
### はまったこと
* UEFI Boot:EnabledだとUbuntuのUSBブートができず、インストールできない。
* UEFI Boot:DisabledだとUbuntuをインストールできるが、NVIDIAドライバをインストールするとログインループが発生する。

### 解決策
* MSHybrid or DISCRETE switchを「DISCRETE」にする。

## Ubuntuのインストール
* [Ubuntu16.04 + Windows10 のデュアルブート環境を構築する - 俺とプログラミング](http://www.iandprogram.net/entry/2015/09/15/115918)を参考に作業

### Windowsのドライブを縮小
* Windows 10 Homeを起動
* [Windows]+[x]キーでスタートメニューを表示
* 「ディスクの管理］ をクリック
* Cドライブを右クリックし、「ボリュームの縮小」を選択
* 100GBを圧縮し、SSDにUbuntuをインストールする容量を確保

### Ubuntuインストールメディアの準備
* 作成方法は省略（[参考URL](http://www.iandprogram.net/entry/2015/09/15/115918)などをみてください）
* 今回はPCにDVDドライブがないためUSBメモリを準備

### BIOSの設定
* PCを再起動し、mouseのロゴ画面が表示されている間に[F2]キーでBIOS画面を表示
* 以下の設定を確認
    1. 「BOOT」タブの「UEFI Setting」で「UEFI Boot」がEnabled
    1. 「Security」タブの「Secure Boot」がDisabled
    1. 「Advanced」タブの「Advanced Chipset Control」で「MSHybrid or DISCRETE Switch」がDISCRETE

### (ドハマりしたところ)
「MSHybrid or DISCRETE Switch」の設定のせいでとても苦労した…。
違いは(【ゲーミングPC Lab.】マウス、「G-TUNE NEXTGEAR-NOTE i5910」 ～GPU処理をGeForce GTX 980Mに固定可能。互換性のみならず性能もアップ - PC Watch)[https://pc.watch.impress.co.jp/docs/column/gpl/741458.html ]を読むとGPUの使い方らしい？
MSHybridが設定されていると、「UEFI Boot」がEnabledでUSBブートができなかった。正確にはGRUBメニューは表示されるが、Ubuntuが起動しない。
「UEFI Boot」をDisabledにすると、UbuntuのインストールはできるがNVIDIAドライバをインストールするとログインループが発生する。最新のNVIDIAドライバでも同様。
OS再インストールする際にBIOS設定を見なおしてDISCRETEを設定すると、UEFIでUSBブートができて、NVIDIAドライバをインストールしても安定動作しています。
あとMSHybridかつ「UEFI Boot」がDisabledの場合の挙動は調べてないです。

### Ubuntuのインストール
* 詳細省略、空き容量にswap領域と予約済みBIOSブート領域とUbuntuのインストール領域を設定し、インストール。

### NVIDIAドライバのダウンロード
* 詳細省略、[NVIDIAドライバダウンロード](http://www.nvidia.co.jp/Download/index.aspx?lang=jp)からダウンロードしてインストール

```text
sudo systemctrl stop lightdm
sudo bash NV~
sudo shutdown -r now
```

* 動作確認

```
nvidia-smi
```

以上
最も基本的なベイズ定理のpython実装

# はじめに
当記事は講談社発行の[「ベイズ推論による機械学習入門」](http://www.kspub.co.jp/book/detail/1538320.html)のP.15からの例題を理解するためにPythonでコーディングしたものです

詳しいく知りたい方はぜひ同書籍を購入してみてください

# 事後確率推定
## 問題
- 赤玉と白玉が入った袋が2つ存在する（それぞれA,Bとする）
- 袋Aには赤玉が2つ、白玉が1つはいっている
- 袋Bには赤玉が1つ、白玉が4つはいっている
- 主催者はA,Bどちらかの袋を選ぶが、どちらが選ばれたかは不明である
- 参加者は袋から玉を取り出し、色を確認したら袋に戻す
- 参加者が取り出した玉の色から、選ばれた袋がA,Bのどちらであるか推定せよ

# ベイズ定理
ベイズ定理の言葉自体は知っている方も多いかと思います。
下記の数式で表現され、事前確率と尤度比から事後確率を算出する例のアレですね

```math
p(X | Y) = \frac{p(Y | X) p(X)}{p(Y)}
```

数式に不慣れな方はこれだけみても「？？？」だと思いますが、やっていることは非常に簡単です

1. p(X)　= 袋が選ばれる確率（事前確率）。今回はA,Bの２つがランダムで選ばれるので０．５ですね
2. p(Y | X)　= 赤白玉が選ばれる確率。袋Aで赤が選ばれたのであれば2/3ですね
3. p(X | Y) = 玉が選ばれた後に、それがどの袋かを表す確率（事後確率）。

つまりランダムでしかなかった確率に、取り出した玉の確率をかけて補正してるだけなんですね
これを袋A,Bの２通り計算し、その比率を計算すればA,Bのそれぞれが選ばれた確率が求まるわけです
（p(Y)については今回の結果に影響を与えないため省略しています）

# python実装
エンジニアならコードで語れ！ってことで上記の実装をしてみました。これでどれだけ簡単なことをやっているかは理解していただけるかと思います

まず最初に袋と玉が選ばれた際の確率を定義します

```py
# 袋の種類
BAG_A = 0
BAG_B = 1

# 玉の色
BALL_RED = 0
BALL_WHITE = 1

# 袋を選ぶ確率
_prob_bag = []
_prob_bag.insert(BAG_A, 1/2)
_prob_bag.insert(BAG_B, 1/2)

# 袋内の玉の色を選ぶ確率
_prob_ball = []

_prob_ball_a = []
_prob_ball_a.insert(BALL_RED, 2/3)
_prob_ball_a.insert(BALL_WHITE, 1/3)
_prob_ball.insert(BAG_A, _prob_ball_a)

_prob_ball_b = []
_prob_ball_b.insert(BALL_RED, 1/4)
_prob_ball_b.insert(BALL_WHITE, 3/4)
_prob_ball.insert(BAG_B, _prob_ball_b)
```

次に事後確率を計算する関数を定義します
先程説明したとおりそれぞれの袋で事前確率を、選んだ玉の確率で補正をかけていくだけですね

```py
# 事後確率を計算する
def posterior(ball_list, bag):
    if len(ball_list) == 1:
        return _prob_ball[bag][ball_list[0]] * _prob_bag[bag]
    else:
        return _prob_ball[bag][ball_list[0]] * posterior(ball_list[1:], bag)

# 袋Aが選ばれる確率を計算する
def posterior_a(ball_list):
    return posterior(ball_list, BAG_A) / (posterior(ball_list, BAG_A) + posterior(ball_list, BAG_B))
```

たったこれだけです。非常に簡単ですね
じゃあ実際に計算してみましょう

まずは赤玉が１つだけ選ばれた時の確率です

```py
ball = [BALL_RED] * 1
posterior_a(ball)
```

```sh
0.7272727272727273
```

赤玉が多い袋Aの確率があがりましたね
じゃあもっと赤玉が選ばれ、赤５個/白３個選ばれた場合はどうなるでしょう

```py
ball = [BALL_RED] * 5
ball.extend([BALL_WHITE] * 3)

posterior_a(ball)
```

```sh
0.9221091861712114
```

92%と飛躍的にあがりましたね

じゃあ同じ比率だけど試行回数が５倍になった場合はどうなるでしょう

```py
ball = [BALL_RED] * 5 * 5
ball.extend([BALL_WHITE] * 3 * 5)

posterior_a(ball)
```

```sh
0.9999956995134158
```

ほぼ袋Aだといってよい状況になったかと
同じ比率でも試行回数が増えれば増えるほど確率が変化することがわかります

# 最後に
ベイズ定理の公式自体はわかりにくいかもしれませんが、やっていることは非常に簡単だということがわかったかと思います
我々エンジニアは数式で理解して、コーディングして理解を深めるってやり方が一番腹落ちしやすいのかなあということでやってみました
Pythonで文字列入力を受付け、入力内容を出力するだけのコード

やってることはまったくもって大したことはないんだけど、input()の仕様がPython 2とPython 3で違ってたため、最初「？？」という状態に。
Python 2ではraw_input()を、Python 3ではinput()を使うというようにした。
で、バージョンの判別はsix.PY2の結果を使うことで実現。

```echo.py
#
# coding: utf-8

import six

def main():
    PyVer2 = six.PY2
    if (PyVer2 == True):
        a = raw_input()
    else:
        a = input()

    print(a)


if __name__ == '__main__':
    main()
```
リバースプロキシ越しのnginxで国外IPアドレスからのアクセス拒否

# はじめに
WordpressのVPSへの移行に伴って、ついでに国外IPアドレスからのアクセスを拒否することにした。（`wp-login.php`へのブルートフォースアタックがまじうざい）この時、wordpressが以下のようなdockerコンテナの多段構成の下で動いているので、中心のnginxコンテナでIPアドレスフィルタリングをすることにした。

```
nginx-proxy <--(front bridge)--> nginx <--(wordpress用back bridge)--> wordpress
```

※ただし、nginx-proxyにnginxからパラメータ渡せばそっちでフィルタリングできる気もする。

設定状況はすべて以下の記事に準じているので、先にそっちに目を通してほしい。
参考：[さくらのレンタルサーバからConoHa VPSのdocker環境へWordpressを引っ越しメモ](https://qiita.com/jqtype/items/1d3c3d285b9583d17cd1)

# `allowip.conf`の作成

国内からのアクセスのみを許すための、nginx設定ファイル`allowip.conf`を作成する。まずは、https://ipv4.fetus.jp/ さんより日本のIPアドレスリストを手に入れる。

```
$ cd /tmp
$ wget https://ipv4.fetus.jp/jp.txt
```

それを加工して許可するIPアドレスプールの設定ファイルを作成する。nginxのルールだと、ホワイトリスト形式は、allow→deny all。形式は、`allow 192.168.0.1/24;`という感じ。

```
$ sed -e "/^#\|^$/d" jp.txt| sed -e "s/^/allow /" -e "s/$/;/" > allowip.conf
$ echo "denly all;" >> allowip.conf
```

最後に、nginxのconf.dへ放り込む。

```shell-session
$ cp allowip.conf ~/apps/wordpress/setting/nginx/conf.d/
```

# `default.conf`の編集
リバースプロキシ越しだと、nginxから内部のプライベートIPアドレスが見えている。そのため、実際のクライアントアドレスは見ることができない。httpヘッダに転送されてきたクライアントの実IPアドレスが乗っているので、nginxでプライベートアドレスをその実IPアドレスに書き換えてしまう(remote_addrの書き換え)。

具体的には`nginx/conf.d/default.conf`の以下の4点をチェックする
- `set_real_ip_from` (serverディレクティブ)
- `real_ip_header` (serverディレクティブ)
- `proxy_set_header X-Real-IP` (locationディレクティブ)
- `proxy_set_header X-Forwarded-For` (locationディレクティブ)

実際の設定ファイルは以下のような状態。

```setting/nginx/conf.d/default.conf
（前略）

server {
  listen 20092;
  server_name <your_domain>;
 
（中略）

  set_real_ip_from 172.18.0.0/16; # ここ
  real_ip_header X-Forwarded-For; # ここ
  
  location / {
    try_files $uri @proxy;
  }

  location @proxy {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr; # ここ
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # ここ
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";
    proxy_pass_header Server;

    proxy_pass http://wordpress:80;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }
  error_page 500 501 502 503 504 /500.html;
}
```

# nginxの再起動
最後にnginxを再起動。(以下の例ではまるごと再起動している)

```
$ docker-compose restart
```

# まとめ
ZenmateなどのVPNサービスを利用して国外からのアクセスが弾かれていることを確認してみよう。docker logsで見ると以下のようなログが吐き出されていて、ruleによりfobiddenなため、http 403を返しているのがわかる。

```shell-session
$ docker logs wordpress-proxy
[error] 5#5: *31 access forbidden by rule, client: *.*.*.*, server: *.*, request: "GET /favicon.ico HTTP/1.1", host: "*.*", referrer: "*.*"
"GET /favicon.ico HTTP/1.1" 403 (後略)
```

なお、IPアドレスの国別割当は割と動的らしいので、適宜アップデートしてやると良い。
gitのルートディレクトリに手軽に移動するラッパー関数


## 作ったきっかけ
gitのルートディレクトリに移動したい❗
深い階層に潜っていると戻るのが面倒臭い😩
自分で書けばいいや😄

# ラッパー関数

## 以下のようなディレクトリ構造で例えます。

```
git-root
┣━ foo
┃	┗━ bar
┗━ baz
```

- カレントディレクトリが `git-root` 以下のときに `cd /` で  `git-root` に移動
- カレントディレクトリが `git-root` の場合は `cd /` で `/`に移動
- カレントディレクトリが `baz` のときに `cd /foo/bar` で `git-root/foo/bar` に移動
 - `git-root` 以下に対象のディレクトリが無ければ、`/` 以下を探す
 
## ラッパー関数を作る
```.zshrc
gitcd() {
	# 引数が / で始まらない
	# または ホームディレクトリの path で始まる場合、普通に cd
	if [[ ! "${1}" =~ "^/.*" || "${1}" =~ "^${HOME}.*" ]]; then
		builtin cd "${@}"
		return
	fi
	
	# プロジェクトディレクトリの中じゃなければ普通にcd
	local insideProject=`git rev-parse --is-inside-work-tree 2>/dev/null`
	if [ ! "${insideProject}" = "true" ]; then
		builtin cd "${@}"
		return
	fi
	

	local currentDir=`pwd 2>/dev/null`
	local projectRoot=`git rev-parse --show-toplevel 2>/dev/null`
	
	# git-root に居れば / に移動
	if [ "${currentDir}" = "${projectRoot}" -a "${1}" = "/" ]; then
		builtin cd "/"
		return
	fi
	
	# /path/to が git-root 以下にあれば git-root/path/to に移動、
	# 無ければ /path/to に移動
	if [ -d "${projectRoot}${1}" ]; then
		builtin cd "${projectRoot}${1}"
	else
		builtin cd "${@}"
	fi
	return
}

alias cd=gitcd
```

これで完成です✨

## 今後の課題
`git-root` 以下で `cd /` とタイプしたときに `git-root` 以下のディレクトリを補完したい😣
ということでそのうち補完も効くようにしたいです、、、が補完周りはよくわからないのでしばらく先になりそうです😵

## 最後に
私の[dotfiles](https://github.com/yasuto777/dotfiles)です。よかったら参考にしてください。
シェルスクリプトは痒いところに手が届いて気持ちいいですね🙌
aws-sdk-goを使ってハマった体験談(SQS)

# 概要
aws上でgoのフロントサーバとSQSで、サービスを展開していたのですが、その時にハマった体験談を書きたいと思います。

#　構成図
端末からリクエストをフロントサーバが受けてSQSに書き込み、バックエンドサーバがSQSから取り出して処理をするだけのシンプルな構成です。
サーバ(EC2)は随時autoscaleしています。
<img width="500" alt="スクリーンショット 2017-10-22 23.41.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/202960/41107312-5b50-948d-9fe2-d6302f91ca8d.png">

# ハマった所
インスタンスが起動する時に、SQSへの接続に失敗して書き込みが出来ない事が度々あり、その間のリクエストがロストしてしまいました。
NW的な問題かとも思いましたが、調査が難しくアプリケーション側で対応を入れることにしました。

# アプリケーション側の問題点
aws-sdk-goでは、クライアント作成時には接続に行かず、メッセージを送信する時に、接続がなければ接続に行く実装になっているため、実際に送信してみないと接続できるのかが分からないためでした。

## 参考までにコード
### クライアント生成
```go
// クライアント生成時にerrorを返さない
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SQS {
	c := p.ClientConfig(EndpointsID, cfgs...)
	return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
}
```
[実際のコード](https://github.com/aws/aws-sdk-go/blob/master/service/sqs/service.go#L46)

### 書き込み
```go
// こちらはerrorを返す
func (c *SQS) SendMessage(input *SendMessageInput) (*SendMessageOutput, error) {
	req, out := c.SendMessageRequest(input)
	return out, req.Send()
}
```
[実際のコード](https://github.com/aws/aws-sdk-go/blob/master/service/sqs/api.go#L1556)

# 解決方法
無理矢理ですが、クライアント生成直後にテスト用メッセージをSQSに送信して、失敗した場合は、ELBに入れない仕組みを実装しました。
もちろん、バックエンドサーバ側でテスト用のメッセージを捨てる実装も入れました。
もっといい方法を知っている方がいらっしゃいましたら教えて下さい・・・・。

# 最後に
SQS等のサービスは、すごく便利な反面、問題が起きた場合に調査が難しいため、アプリケーション側で上手く実装することが重要だと実感しました。
さくらVPSのスケールアップができない(リンクがない)

#結論

- スケールアップできた
- さくらVPSのコントロールパネルにログインではなく、会員メニューの「サーバ設定」から移動するとリンクが表示されていた...
- 会員メニュー： https://secure.sakura.ad.jp/menu/service/


#状況

- さくらVPSのスケールアップのリンクが出ないため、スケールアップできない
https://vps-news.sakura.ad.jp/scaleup/
- 電源が切れていないためかと思ったが、電源を停止しても導線が出ない


<img width="677" alt="スクリーンショット 2017-10-23 0.16.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/92339/094a85ea-007b-8683-befa-43bd22038973.png">
▲ 導線がない表示

<img width="613" alt="スクリーンショット 2017-10-23 0.26.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/92339/d1f0359a-b6c7-aa69-5a0c-c072d09193f2.png">
▲ 会員メニューのログインし、「サーバ設定」からVPSのコントロールパネルを表示すると導線があった