いがにんのぼやき

WEBエンジニアのブログ。IT、WEB、バンド、アニメ。

だいたい新卒エンジニア向け技術交流会 vol.13に参加、発表してきた

dark.connpass.com

だいたい新卒エンジニア向け技術交流会 vol.13で 発表してきた。
資料はこちら。

qiita.com

完全にネタ枠のつもりで行ったので技術的なことは一切ない。
楽しんでもらえたようなので良かった。

前回のLT会のときも発表させていただいて、その時はCMSエンジニアについて話した。
前回、今回と前職のお話をしていて、ある程度前職のお話を話し切った感はある。(今は勉強期間&転職活動で無職です。)

LTや記事に書き起こすことによって、その出来事に区切りをつけることができると思っていて、今回はこの場を借りて発表させていただいた。
これで前職に関して一つの区切りを付けられた。
明日からまた次の一歩を歩んでいけるような気がしている。

がんばるぞ!!!

以下は雑な他の方の発表のメモ

dev.toの速さについての小話@hi-sa

  • 今話題のdev.to
  • fastlyやマウスオーバー時の先読みHTMLは強い

最新技術のキャッチアップ@speech

  • TECH FEED知ってはいたが使ってみようかなって思った
  • 新卒にしか見えない資料辛い

何も準備せずにノリで上海に行ったら大変だった話@bird_nitryn

Docker使ってますか?@tunamaro

  • 開発環境DBの切り替えと便利そう

おいしいカクテルの作り方@14万(sota1235)

  • 14万!!!!!!!!
  • ポジティブは大切

休職したときに受ける損害とその軽減方法@equal_001

  • 診断書が5000円とかするとか、高いのね
  • 企業によっては出社8割満たないと有給が貰えない
  • 心が弱っているときに交渉事をしなければいけないのは大変だと思った

人材業界中の人が語る若手エンジニアの転職活動@momotomo

  • エージェントさんは面倒な交渉事、日程調整をやってくれたり有難い
  • 内定承諾を待つ期間が短いので面接が集中するので注意

P.S

無事14万を渡すことが出来てよかったです。

PhpStorm + Docker for Windowsを試す

Docker for Windowsの設定を開き、Generalタブを選択する。
Expose daemon on tcp://localhost:2375 without TLS にチェックをつける。

f:id:igatea:20171211185955p:plain

PhpStormのDockerの設定を行う。
設定を開きDockerと検索し、Build, Execution, DeploymentのDockerを選択する。
プラスボタンを押し、TCP socketを選択するとウィンドウ配下に接続可能か検証結果が表示される。

f:id:igatea:20171211190108p:plain

Connection succesfulと表示されれば成功。

再度、設定を開きPHPと検索。
Languages & Frameworksの中のPHPを選択し、CLI Interpreterの...をクリック。

f:id:igatea:20171211190558p:plain

Docker(またはDocker Compose)が選択されていることを確認し、Serverを先ほど作成したDockerの設定を選択する。

PHP veresin: Not installedと表示される。

f:id:igatea:20171211190946p:plain

おそらくDockerをビルドしていないからだと予想。
該当ディレクトリでdocker-compose build

それでもエラーが出ているのでdocker-compose up -dで立ち上げてみる。

やはりだめ。

com.github.dockerjava.api.exception.BadRequestExceptions: {"message":"invalid environment variable: =::=::\\"}

f:id:igatea:20171211204031p:plain

MobyLinuxVMではなく、別にHyper-V上にDocker Machineを立ててやってみようとしたけど駄目だった。

Docker Compose経由を諦めて、Docker単体で動作させてみた。

Testing started at 2:43 ...
docker://laravelsampleblog_php:latest/php vendor/phpunit/phpunit/phpunit --configuration /src/phpunit.xml --teamcity
Could not open input file: vendor/phpunit/phpunit/phpunit

Process finished with exit code 1

パスが解決できてないっぽい?
どうもここから進まない。

Windowsにすることによって、Ubuntuのときよりも構築障壁が高くなりすぎている。
.Net系以外は仮想環境でUbuntuでも立てて、そこで開発するようにするか検討しようと思う。

2017/12/18追記
f:id:igatea:20171218172449p:plain Include parent environment variablesのチェックを外したら正常に動作しました!!

f:id:igatea:20171218172937p:plain

この一番上の変数がよくないようだ。
だけどこれがどこで定義されているものなのかがわからない。
コマンドプロンプトPowerShellか、変数が定義されているのかと思って確認してみたがそれらしいものは無し。
とりあえず動かすことができてよかったが、もやもやが残っている。

WindowsでDocker toolboxを使用してVisual Studioと連携しようとして失敗した

まず言っておこう。
Docker for Windowsを使おうな!!!

事の発端

最初は僕もDocker for Windowsを素直に使ってみようと思っていた。

Docker Store

上記からDocker Community Edition for Windowsを入手し、インストール。
インストールを進めていたところ、下記のようなエラーに遭遇した。

f:id:igatea:20171210043903p:plain

Hyper-Vがないために発生するエラーのようだ。
どれどれ、Hyper-Vをインストールしようじゃないか。
よしよし、このリンクにインストール方法が載っているぞ。

docs.microsoft.com

 

ん?

 

f:id:igatea:20171211161024p:plain

 

は?

 

f:id:igatea:20171211161258p:plain

 

 

はああああ~~~~~~~!!!???

 

PC購入当時、1万円をケチったことを後悔していく。
Docker for WindowsではHyper-Vが必要で、Windows Home Editionでは動作させる方法がない。
そんなとこからHome Editionでも使用可能なDocker toolboxを使用してみる。

ここからはただただ心を折っていく出来事に立ち向かい、心が折れていく様を記載するだけである。

失敗

一度、最終的なゴールに立ち返ってみる。
最終的にはVisual Studio 2017 CommunityでASP.NET CoreのDockerコンテナの実行を可能にしようというものだ。
新規でASP.NET Coreプロジェクトを作成し、デバッグ無しで実行を正常に行うことができるようにする。
それに向かっていきながら発生したエラーを叩き潰していくという作業を行っていった。
Docker toolbox自体のインストールは事前に済ましておいた。

Powershellにパスを通す

PowershellにはDockerのパスが通っていないので、パスを通す。

github.com

docker-machine env default | Invoke-Expression

Dockerが実行されていない

Visual Studioからサンプルアプリケーションを作成し、デバッグ無しで実行しようとしてみると下記のエラーが発生。

重大度レベル   コード   説明  プロジェクト  ファイル    行 抑制状態
エラー       Visual Studio コンテナー ツールでは、コンテナー化されたプロジェクトをビルド、デバッグ、実行する前に、Docker が実行されている必要があります。

詳細については、http://aka.ms/DockerToolsTroubleshooting をご覧ください  docker-compose  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets 314 
1>------ ビルド開始: プロジェクト: docker-compose, 構成: Debug Any CPU ------
1>docker ps --filter "status=running" --filter "name=dockercompose16224944752208736737_dotnetcore02_" --format {{.ID}} -n 1
1>error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.33/containers/json?filters=%7B%22name%22%3A%7B%22dockercompose16224944752208736737_dotnetcore02_%22%3Atrue%7D%2C%22status%22%3A%7B%22running%22%3Atrue%7D%7D&limit=1: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets(314,5): error : Visual Studio コンテナー ツールでは、コンテナー化されたプロジェクトをビルド、デバッグ、実行する前に、Docker が実行されている必要があります。
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets(314,5): error : 
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets(314,5): error : 詳細については、http://aka.ms/DockerToolsTroubleshooting をご覧ください
1>プロジェクト "docker-compose.dcproj" のビルドが終了しました -- 失敗。
========== ビルド: 正常終了または最新の状態 0、失敗 1、スキップ 0 ==========

Docker MachineはDocker toolboxのQuick Installを実行した時点でdefaultというものが作成されているので存在はしているし、開始されているはず。

docker-machine create box

上記コマンドで新規に作成しても変わらず。
最初にPowerShellでパスを通した通り、Visual Studioでも参照できるようパスを通さなければいけないのかもと思い、仮でユーザー環境変数を設定してみた。

f:id:igatea:20171210170200p:plain

これをするとエラーは出なくなり出力が変わった。

dotnet SDKが見つからない?ボリューム共有が無効?

========== 起動中 ==========
docker ps --filter "status=running" --filter "name=dockercompose16224944752208736737_dotnetcore02_" --format {{.ID}} -n 1
40cc4dbd74c0
docker exec -i 40cc4dbd74c0 dotnet  --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages --additionalProbingPath /root/.nuget/fallbackpackages2  bin/Debug/netcoreapp2.0/DotNetCore02.dll
docker inspect --format="{{json .NetworkSettings.Ports}}" 40cc4dbd74c0
{"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"32768"}]}
Did you mean to run dotnet SDK commands? Please install dotnet SDK from: 
  http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
ボリューム共有が有効になっていません。Docker CE for Windows の設定で、ボリューム共有を有効にしてください。

詳細については、http://aka.ms/DockertoolsTroubleshooting をご覧ください。

dotnet SDKが入っていないとのことなので入れてみる(VIsual Studioのインストールで入ってるぽいけどなんでだろ?)

www.microsoft.com

入れようとしたらすでに入ってるよって出るので一度スルー。
ボリューム共有に取り掛かってみる。
VirtualBoxの共有フォルダーを設定するだけだとdocker-machineの再起動時に変更されるため駄目みたい。

f:id:igatea:20171210173706p:plain

下記にある通り、永続化と自動マウントを設定してあげればいいようだ。

docs.docker.com

f:id:igatea:20171210174056p:plain

設定後docker-machineを再起動

docker-machine restart default

そのままだとできなかったのでVisual Studioを再起動もしてみた。
残念ながらエラーは変わらずだった。
ここらへんで心が折れた。

github.com

このissueコメントを見ているとやっぱりtoolboxはダメみたいだ。
ここでWindows Pro Editionをインストールし、Hyper-Vを有効化、Docker for Windowsを入れて再度やってみたら今までのエラーが嘘かのようにすぐ実行できたのであった・・・。

失敗を糧に生きていくぞ!!!

おまけ

Hyper-V上にMobyLinuxVMが存在するのにdocker-machine lsで表示されなかった。

f:id:igatea:20171211160038p:plain

PS C:\Windows\system32> docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

下記を見ると、docker-machineはリモートに使用するとき以外は使わないっぽい。

forums.docker.com

PHPで画像に使用するユニークな名前を用意する

画像に一意な名前を付けたいと思って、PHPのダミーデータ作成ライブラリのFakerを参考にしてみた。

github.com

// Generate a random filename. Use the server address so that a file
// generated at the same time on a different server won't have a collision.
$name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));

上記はFakerでのダミー画像作成時のファイル名の生成コード。
手順としては下記である。

  1. $_SERVER['SERVER_ADDR']でサーバーのIPを取得
  2. それを先頭文字としてuniqid()で一意な文字列を生成
  3. 一意な文字列をmd5()でハッシュ化

各関数について

uniqid

PHP: uniqid - Manual

マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID を取得します。

とあるとおり、現在の時刻に基づいて作ってくれるようだ。

md5

PHP: md5 - Manual

入力値をハッシュ化する。
同じ入力であれば同じ値に、少しでも違えば全く違う値が生成されるようになっている。

Fakerでのファイル名生成について

コメントにもあるとおり、同じ時刻に別のサーバーでファイルが生成されたとしても同じ名前にならないようにサーバーのIPをuniqid()の先頭文字として使用して、それをハッシュ化するという手法をとっている。

Docker上での、GitサブモジュールによるNode.jsエラー

igatea-Ubuntu-PC:co.tech igatea$ docker-compose exec php npm install
npm ERR! Error while executing:
npm ERR! /usr/bin/git ls-remote -h -t git://github.com/jeroennoten/webpack-stream.git
npm ERR! 
npm ERR! fatal: Not a git repository: ../.git/modules/src
npm ERR! 
npm ERR! exited with error code: 128

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2017-11-14T06_51_41_841Z-debug.log

GitのサブモジュールのディレクトリをDockerコンテナ上に共有しているのが問題だった。
この場合はsrcディレクトリをサブモジュールとしていた。
単純にサブモジュールだけじゃなく、Git全体を含める形で解決した。
そもそもサブモジュールを使用せず、指定のディレクトリをgitignoreに追加してそのままそのディレクトリにリポジトリを展開しても良いかもしれない。

UbuntuでVirtualbox、Vagrantのエラー

Dockerを使用してnpm runをしようとするとPermission deniedが出る問題あり。やったことを残すためにこの記事は残しておきますが、参考にしないでください。

sh: 1: webpack: Permission denied

自分用メモ。

Virtualboxを入れるのもひと手間だった。 具体的な記述に残していないが、下記で行けた。

askubuntu.com

Secure bootを無効にするとかだった気がする。

また、UbuntuVagrantを使用するときに、外部ディスクを使用するときにパーミッションエラーが出るための対応。
こんな感じのエラーがでる。

The private key to connect to this box via SSH has invalid permissions
set on it. The permissions of the private key should be set to 0600, otherwise SSH will
ignore the key. Vagrant tried to do this automatically for you but failed. Please set the
permissions on the following file to 0600 and then try running this command again:

/media/igatea/TOSHIBA-1TB/Vagrant/centos7/.vagrant/machines/default/virtualbox/private_key

Note that this error occurs after Vagrant automatically tries to
do this for you. The likely cause of this error is a lack of filesystem
permissions or even filesystem functionality. For example, if your
Vagrant data is on a USB stick, a common case is that chmod is
not supported. The key will need to be moved to a filesystem that
supports chmod.

GUIで外部のHDDのマウントの設定をしていたが、パーミッションの変更ができないっぽい。
なので下記を参考にマウント設定のfstabをいじっていく。

hakushisky.blog.shinobi.jp

askubuntu.com

最終的に/etc/fstabに下記の行を追加して再起動。

UUID=B07E713F7E710000 /media/igatea/TOSHIBA-1TB auto auto,users,permissions 0 0

その後、Vagrantディレクトリのprivate_keyがrootの777になっているのでパーミッションを変更してあげて終了。

chown igatea .vagrant/machines/default/virtualbox/private_key 
chmod 600 .vagrant/machines/default/virtualbox/private_key 

ユーザーがrootのままだと下記のエラーが発生する

The private key to connect to the machine via SSH must be owned
by the user running Vagrant. This is a strict requirement from
SSH itself. Please fix the following key to be owned by the user
running Vagrant:

/media/igatea/TOSHIBA-1TB/Vagrant/centos7/.vagrant/machines/default/virtualbox/private_key

ISUCON7に参加した

参加しました。

事前に練習会をやったのでそのままの流れで。 igatea.hatenablog.com

最終スコアは15164、ベストスコアは33272でした。

f:id:igatea:20171022153957p:plain

トップは云十万単位のスコアを出していて、壁は厚いなあと思った。

チーム構成

担当は練習会と同じ感じ。

言語はPHPです。

今回のISUCONの課題

今回は掲示板のような、チャットのようなサイトでした。
しかもサーバーが3台構成。
このサーバーをどう扱っていくかが重要だった気がします。

どんなことをやったか

僕らは1台をWEB、1台をDBとして活用した。
余った1台は実験サーバーになってて何かうまく使いたかったが時間的に出来なかった。

やったこととして最初はサーバーへの接続確認。 確認できたところでミドルウェアやアプリケーションと言った、設定含めた各ファイルのバックアップ。

そこらへんは他の方にお願いした。
その間に最初の30分で僕は仕様の把握。
こんなかんじ。

f:id:igatea:20171022211745j:plain

前回予選の問題よりもかなり複雑だった。

その後はnginxのログをうまくデータとして扱ってくれるツールとしてalpを使用した。
alpから重いところ探してアプリケーションの改善に力を入れた。

一番重かったのが画像表示だったけど、メンバーが早々に画像がDBに入っているところを発見して、それをファイル出力にするということに取り組んでくれた。
ここらへんめっちゃありがたかった。
ので、自分は他を俯瞰的に。

ちょっと困ったのが前回の予選問題だとここを改善すれば凄く早くなるなってところが局所だったんだけど、今回は画像のところ以外分散していて困った。

有効だった対策

ベンチのスコアが変動しすぎて(ベンチガチャとか言われてた)どれが有効打になっているのか判断つきづらかった。
なので、これは凄くスコアが上がったっていうものと恐らくスコア上がっただろうっていう取り組みに分けてみる。

凄く上がった
  • SELECT句のカラムを徹底的に絞り込み
  • SQLの発行回数を少なくするように結合を活用

基本的にSELECT句のカラム指定の*は全て削除して、カラム指定するようにした。
getのhistoryとmessageは無駄にクエリを投げまくっていたのでアプリケーションコードを一部書き換えた。
ここらへんで1万、2万スコアが上がった。

恐らく上がった
  • 同じループを2回以上やっているところの解消
  • initialize時にSQLのキャッシュを作るために先にクエリを発行

正直スコアが変動しすぎて効果があったのかわからないレベルだった。

もっとうまくやりたかったなあって点

ベンチ設定ミス

設定を保存を押してなくてずっとベンチを回すサーバーを間違ってた。
てっきりチェックボックスつけとけばいいのかと思っててメンバーに指摘されて気付いた。
上がらないからとマージしなかったブランチをマージしていったらガンガン点数が上がって最高だった。

根本解決

クエリとかロジック周りは直したつもりだけど、それ以上スコアの上昇が見られなかった。
もっと根本的に改善しなければこれ以上上がらないなという壁を感じた。
例えば今回は3台のサーバーが用意されていたわけだけど、それをフルに使用することができなかった。
画像をWEBサーバーに書きだしたことにより、DBへの負荷は軽くなったんだけど、WEBサーバーがCPUが100%に張り付いている状態だった。
自分たちはWEBサーバー1台を余らせている状況だったので、もったいなかったなあと。
終わったあと話してたのはそのサーバーを画像配信サーバーにできたらよかったかもってこと。
今回メンバー的にインフラ、ミドルウェア周りに詳しいという人がいなかったので取り組むにはとても難しい状況だった。

得た知見

仕事上、ガンガンサーバー設定をいじるわけでも無いし、ましてやWindow Serverの方が触ることが多かった。
しかもあまりアプリケーション改善もDB周りへの配慮を実務でするということがなかったので物凄く経験になった。
これはまた別に記事を書きたいと思う。

最後に

凄く楽しいコンテストだった。
メンバーが色々サポートしてくれて、かなり自由にアプケーション側を弄っていけて最高でした。
一緒に組んでくれたごまさん、くーむさん、本当にありがとうございました!
めちゃくちゃ勉強になりました!