読んだものメモ 2018/02/13

読んだものメモ

最近業務内外問わず色々な記事を読んだりして知見がたまってきてるが、アウトプットする時間がなかなか取れず、もったいないのでせめて、URLをメモっておいておこうという戦略。 メモして公開しておけば、後から探すときに探しやすくシェアもしやすいなと思ったので、やってみる。 日付にはこだわらず、そういえばこないだ読んだなーってのもてきとーに乗せてく。 後で読んだ感想とか、追記していけたらいいなー。

2018/02/13

友人のブログ

blog.pinkumohikan.com


16進数から色を当てるやつめっちゃムズイ

http://yizzle.com/whatthehex/


DRY原則のやつ、話題になってたので読んだ

speakerdeck.com

phpcon2017に参加した

phpcon2017に参加したのでざっくりメモ。

※参加しながらのメモなので随時更新します。

「OPcacheの最適化器の今」

スライド:

www.slideshare.net

PHPを実行時はバイトコード命令にコンパイルして逐次実行している。

OPchaceの役割

キャッシュ済みならキャッシュからバイトコード命令を実行する

キャッシュ済みでないならコンパイルしてキャッシュする

コンパイル時に最適化しておけばはやくなるんじゃね?これだ!!

PHP5.5の最適化

  • 定数式の置き換え
    • 計算が必要な定数をあらかじめ計算しておくなど
  • 条件分岐の置き換え
    • 実行時には条件分岐が決まってるので計算しておく
  • 連続ジャンプの短絡
    • 省略できるif文などは省略
  • 制御フローグラフ
  • グラフ構造を表現しておき、必要な命令だけを残す

PHP5.6の最適化

  • 関数呼び出しの効率化
  • 未使用リテラルの削除

PHP7.0の最適化

  • 関数スタックフレームの最適化 そんなに大きく変わってない

PHP7.1の最適化

  • コールグラフの構築
    • 関数間の呼び出し関係をグラフ構造に表現し、最適化する
  • データフロー解析に基づく最適化
    • プログラムの各点でデータが取り得る値を解析する

PHP7.2の最適化

  • 定数の伝播
  • 不要コードの除去
  • 未使用変数の除去
    • 使わない変数を除去する

PHP7.2にしよう!!

Lancersのバージョンアップ施策について

過去にもリプレースしようとしたが、2年かかる見積もりだったので、ペンドになった。 要因としてソースコードが肥大化していた。ソースコード全体で約60万行くらいあった。

目的

  • 開発リソースの最大化
  • サポートが終了している
  • Cake1.3もサポートが、、

バージョンアップの前準備として

今あるユニットテストを動くようにする。Nginx + php-fpmで動くようにする。

段階的にあげるように戦略を立てた。 推進者一人、インフラ担当一人、アプリエンジニア一人。

Cake1.3から2.8で詰まったところ

アップグレードシェルの実行だけでは動かなかった。変更点のドキュメントを読み修正していく必要があった。 ヘルパーの仕様が変わってた部分については、ラッパークラスを作成する事で対応していった。

進め方

アップデートしたブランチを作成し、そこで動作確認しつつ修正を加えていく。 毎週masterから差分を取り込むのが大変、、同じような修正が必要になる。 →オレオレUpgradeShellを作った。

事前にCakePHP1.3でできることは先にやっていく。

まとめて切り替えるのではなく、1コントローラーずつ以降していく事で安全に切り替える。 →1.3と2.8の同居をさせるためにindex.phpに細工を入れる。

今後の進め方

PHPのバージョンアップはカナリアテスト。CakePHPのバージョンアップは2バージョンを用意しながら少しずつ進めていく。Codeceptionを利用していく。ユニットテストも2バージョンを用意していく。

まとめ

  • 事前にできることはやっておく
  • Upgrade Shell が全てをやってはくれない
  • 実はバージョン同居できる

質問

  • どれくらいの以降期間を想定しているか?
    • 1年から1年半程度
  • エンジニアではない関係者にどのように説得したか?
    • 開発速度を早めることができますよ、今の施策やりながら裏でアップデートしますよ。というような伝え方。
  • 3系にあげる際の戦略はありますか?
    • 基本的には2系にあげる時と同じやり方を考えています。

Serverless FrameworkでAWSフルマネージドなツールをいくつか作って得たアーキテクチャ設計の知見

スライドは後日公開されるらしい

サーバーレスアーキテクチャ

※諸説ある - イベントドリブン - サーバ単位ではなくイベント単位 - ステートレス - 実行後のコンテナは破棄されるのでステートレスなアーキテクトが求められる

いわゆるLAMPアーキテクチャでは開発者がOSから環境まで、管理する必要がある。 それに対してサーバレスアーキテクチャではイベントを管理、実行を管理する必要がある。 開発者は動くための関数だけを管理すれば良い。

Serverless Frameworkとは何か

インフラもアプリも一括管理できるデプロイツール

サーバレスアーキテクチャで開発する際に気をつける事

  • LAMPアーキテクチャではない事を知る。
    • ステートをモテない
    • 安易にRDMSを使用するとアンチパターン
    • 画像などのバイナリの取り扱いは難しい(リクエスト・レスポンス制限)
    • 認証・認可の仕組み
  • マネージドサービスを知る

サーバレスアーキテクチャでの設計やアイデア

tipsみたいなもの - POST with config - 設定値もステートなので、POSTに含めてしまう - Reserved Timestamp ID - 実は一覧を作るのは難しい - S3を使っている - Instant Job Queue - S3 Object Tagging - Env Sync - デプロイ時の環境変数とfunctionが実行されるコンテナの環境変数に設定する

まとめ

サーバレスアーキテクトが得意なものとLAMPアーキテクトが得意なものは違う。サーバレスアーキテクトがハマると強力。 Serverless Frameworkを使うとインフラもコードで管理できる。

広告配信管理システムを支えるPHP ~ レガシーシステムからの段階的移行戦略

speakerdeck.com

価値あるコードをよりよくしたい

下準備

phpmd, phpcpd, phpdcd, phpcs, phan などを使い複雑そうなところを見つける

例外とハンドリング

  1. アプリケーションベース例外を定義
  2. アプリケーショングローバルな例外ハンドラを実装
  3. ロギングとエラー表示

アプリケーションベース例外にユーザ向けのメッセージを表示するためのメンバ変数を定義している。 ロギングも例外の中でやってくれるようにしているので、例外を投げるだけでいい。

NewRelicを使ってモニタリング

パフォーマンスモニタリングもできる。 エラーがどこでどれだけ起きてたかなどを見れる。

コードを消す

PHPStormつかってます。

phpcs + php7ccで洗い出しつつ基本はマニュアル読みながら修正。

どんどん使用していないものは削除。テストも合わせて消す。

遅いテストは生産性を落とす。

Redashにたよる。「それRedashでよくない?このクエリでデータ出せますよ」

「最良のコードは、コードなし」いらないコードはどんどん消そう。コードなしで機能を提供できるならない方がいい。

外部ツールにうまく頼ろう!!

実装ガイドラインを作る

PSR-1,2準拠 + php-cs-fixerのci組み込み

@deprecatedをうまく使い、非推奨なコードを明示。消す前に@deprecated入れて本番で出てないかログを見ることで安心して消せる。

まとめ

まずは守りを固めて、より良いコードをかける体制を作っていく。

DockerでPHPアプリケーションを本番リリースするまで

必要な事 - ローカルでコンテナを作成 - レジストリにコンテナをPUSH - 本番にリリース

K8S, GKE

マネージドな環境をつかうことで簡単にできる

Laravelで作る分析環境 ブースを回った

ここで差がつくエラー処理

メモ: 複数のphpのバージョンで実行結果を見ることができるらしい。便利そう。 3v4l.org

エラー

php7ではパースした時点でエラーになりうるものをエラーとして扱ってくれる。php7は賢いので。 (絶対実行されないif文の中でも)

例外

php5ではExceptionまたはExceptionを継承したクラス

php7ではThrowableを継承したクラス

エラーと例外(エラー)が混在していて扱いが面倒なので、例外(エラー)に統一してやると楽。

開発時、ユニットテストのときはE_ALLで指定してやって、本番ではE_ALL & ~E_NOTICE & ~E_DEPRECATEDしてやるとよい

ローカルのMacとリモートのCentOS7上のtmux2.5とクリップボード共有したい

背景

手元のMacBookPro上にtmuxを導入してクリップボード共有する記事はよく出てくる。 しかし、自分の場合VPS上で作業することが多いので、VPS上に環境構築をしたいと考えた。 (出先や、違うPCから作業することもあるため、手元のマシンに構築するのが面倒だった。) VPS上のCentOS7上にtmux2.5を導入した上でローカルマシンとクリップボードの共有しようとしたが、 意外と記事がなくハマったので記事として残しておこうと思う。

前提条件

ローカルマシン MacBookPro
リモートマシン CentOS7.3
tmux 2.5

※tmuxはすでに導入済みとする

手順

リモートマシン CentOS

xsel をインストールする

$ sudo yum install -y xsel --enablerepo=epel

ssh して使うのでsshの設定を編集
$ vim /etc/ssh/sshd_config

X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes

のようにしておく

sshd リスタート

$ sudo systemctrl restart sshd

tmuxから使えるように設定する
$ vim .tmux.conf

bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel “xsel -ib”

ローカルマシン Mac

x11 接続するために xquartz をインストール
$ brew update
$ brew cask install xquartz
インストール後 Mac再起動する(しないと環境変数DISPLAYがセットされない)
Xauthの作成
$ open /Applications/Utilities/XQuartz.app
# ~/.Xauthorityを作成してくれます
xhostに追加

$ sudo xhost your.server.name

動作確認

リモートマシンにログインして動作確認する。

リモート→ローカル

$ cat /etc/redhat-release | xsel -bi 実行後にローカルマシンで貼り付けして CentOS Linux release 7.3.1611 (Core) のように出ていれば問題ない

ローカル→リモート

ローカルで適当なものをコピーしてリモートで xsel -bo でコピーしたものが出力されていれば問題ない

tmuxで使う

上記の手順でtmuxの設定もしてあるので、そのままtmux上のキーバインドでコピペできます。
※tmuxの設定再読み込みしておくことをお忘れなく

お疲れ様でした。

crontab に設定してある php のバッチが実行されないとき

laravelのスケジュールをcronに設定したのに動かなかったので原因調査をした。 その時のメモ

状況

crontab は下記の状態

$ crontab -l
* * * * * php /project/path/artisan schedule:run >> /dev/null 2>&1

原因調査

cron の生存確認

とりあえずcronが動作しているかを確認した

$ systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-06-17 21:18:06 JST; 2 days ago
 Main PID: 1927 (crond)
   CGroup: /system.slice/crond.service
           └─1927 /usr/sbin/crond -n

→動いてそう

cronが実行されたときのログを見てみる

$ tail -f /var/log/cron 
Jun 20 18:08:01 133-130-116-162 CROND[17721]: (deploy) CMD (php /project/path/artisan schedule:run >> /dev/null 2>&1)
Jun 20 18:09:01 133-130-116-162 CROND[17773]: (deploy) CMD (php /project/path/artisan schedule:run >> /dev/null 2>&1)

→動いてそう

cron実行時のログを確認

出力する設定に変更し確認する

$ crontab -e
php /web/pengin-news/current/artisan schedule:run >> /project/path/storage/logs/cron.log 2>&1

$ $ tail -f /project/path/storage/logs/cron.log 
/bin/sh: php: command not found
/bin/sh: php: command not found

こいつや!!!!

解決編

どうやらcronが実行される際のpathが下記になっているようでした

# 確認方法
$ crontab -e
*/1 * * * * printenv > /tmp/printenv.txt
$ cat /tmp/printenv.txt
SHELL=/bin/sh
USER=vagrant
PATH=/usr/bin:/bin
PWD=/home/vagrant
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/vagrant
LOGNAME=vagrant
_=/usr/bin/printenv

PATH=/usr/bin:/bin
そう /usr/bin:/bin しか見てないのです。

crontab で pathを定義して解決

which コマンドで php のパスを調査しておき crontab に書いておけば大丈夫でした。

$ which php
/usr/local/php7/bin/php
$ crontab -e
PATH=/usr/bin:/bin:/usr/local/php7/bin

* * * * * php /project/path/artisan schedule:run >> /project/path/storage/logs/cron.log 2>&1
$ tail -f /project/path/storage/logs/cron.log
/bin/sh: php: command not found
No scheduled commands are ready to run.

お疲れさまでした。