2021年10月2日土曜日

phpcon2021 day1,day2

コロナ禍の中今年もオンラインで実施されたphpcon2021。
ナマクラPGが自分がエンジニアだということを忘れないようにするためだけの年1回のイベント。オンライン開催でいいのは合間に家事が出来ることだと思う。会場で交流するような性格でもないので、知識のアップデートだけならオンライン開催は便利だと思います。
discord(チャットやチャンネルなどのコミュニケーションアプリ)をはじめて使いました。ボイスチャットとかできるみたいですが、slackみたいなものですね。
いくつかのセッションを拝見しましたが、備忘録も兼ねて少しだけメモ。やっぱり自分の立ち位置上、業務改善だとかバージョンアップ対応だとかに興味が行きがちなんですけどね。
今回は「20年モノの巨大Webサービスの開発継続戦略」が一番刺さりました。3年前から今に続いた失策を叱責されているようでした。よし、タイムマシンだ

●レガシーシステムにおけるPHP8バージョンアップのアプリ対応記録
<大事なこと>
・全量把握し、対策を練る
・品質担保に対し、費用対効果を考慮したテスト設計をする
<影響の多かった変更点>
・緩やかな比較演算子の挙動変更
 文字列が数値形式でない場合数値が文字列に変換され比較結果が反転する
 0 == "" で比較している場合、7だとTRUE 8だとFALSE
  他、演算子や配列関数、ソート関数など
・警告レベルの変更
<対応案>
・以前と同様の挙動をする関数(ラップ関数)を作成しすべての箇所を置き換える→新たなコード負債
・すべての箇所を複数パターンでテストし問題の箇所を修正→膨大な時間がかかる
<選択した対応策>
・演算子に対する対策:修正対象を絞る、チェック関数で調査
・警告レベル:通過テストで確認
 挙動は自動テスト・手動テストで確認
<今後について>
・自動テスト追加(デメリットはコスト面)
・静的な型を意識した実装を行う
・こまめなリファクタリングは重要

●20年モノの巨大Webサービスの開発継続戦略 - ミドルウェアのバージョンアップとの向き合い方
<どうしてMWバージョンアップをするか?>
・サービスが売れるかどうかは企業の生存に直結する
・サービスは売れ続ける必要がある
<サービスの価値とは>
・お金を稼ぐ力
・ユーザにとって価値があること
<2つの開発と価値>
・価値を増やすための開発
 →サービスを増やす
・価値を落とさないための開発
 →脆弱性対応、バージョンアップやリファクタリング
<こんな経験ない?>
価値を落とさないための中身を整理するための改善の開発をやろうとすると
組織から
・コストを回収できない
・コスト外のメリットの可視化が難しい
・過去十数年分の技術的負債、何年も過ぎる納期、増加する不具合、開発組織以外からはつらさが見えにくい
・開発組織への信用の低下(により認めてもらえない)
・顧客から怒られるのは営業や販売、
 →コード上の改善は新規の価値を生み出していない、機会損失ととらえられてしまう
・ポジショントークにとらえられる
<中身の改善のハードルが高い!>
・組織は価値の向上を優先したい、改善のメリットを評価できない
・組織全体の問題。システムの疲弊のリスクが安く見積もられている。こまめに改善する組織はこうなりにくい
<例外はMWバージョンアップ>
・やらないと明確に価値が下がる
 EOL対応はしないと損失になる。脆弱性、売れなくなる、やらないことの損失がわかっているためそれを回避する
・改善は差し迫った損失を避けるモチベーションで承認され、開発者たちはこれが改善のチャンスと誤解してしまう
<MWのバージョンアップがつらい理由>
・影響も規模も大きすぎて途方に暮れる
・問題が大きいのに期間が短い
・過去の作業の経験がない
・つらいPJになりそう
・求められているのはMWバージョンアップ、改善ではない、コストはかけられない
 問題が山積みのソースコードを直せるのに・・・
 →という認識のギャップに気づく
<大事なことは生き残ること>
・今もそのレガシーシステムは価値を生み出している、今ある問題はこれまで解決できていなかったもの。同時に対応するには荷が重い
・とりあえず生き残ることが大事。MWバージョンアップの際は、それ以外を目的とせず、システムが生き延びることを考える。次のバージョンアップまでの時間が手に入る
<MWバージョンアップの際に心がけること>
・バージョンアップ作業は最速で、修正は最小化で、開発案件をバグの洗い出しに活用、修正作業はバージョンアップ案件対応
・修正は最小化する、バージョンアップ以外の修正に囚われたらいけない
・問題はなるべく分割すること

●新規プロジェクトの開発スタート前にやっておくべき環境整備たち

「俺の考えた最強」を目指すことは間違いじゃないが、最初からそれだけに集中したりリーダーだけが突っ走るのは間違い
<やるべきこと>
・ユーザに価値を届けることが最も本質的で重要
・よい技術選定、設計、実装は本質ではないが楽しみを見出す
・開発しやすい環境を整備する
・上の2つに集中しがち、最初のうちに環境整備をするのは肝心
・コードとコミュニケーションの環境整備を行う
<コミュニケーションの環境整備>
README
・ドキュメントのルートとしてREADMEを充実させること
 リポジトリの概要、位置づけ、環境構築の仕方、QAの補足説明など
 リポジトリに置くことで迷子にならない、新規メンバーが入りやすい、レビューできる。
 社内サーバなどに置いてしまうとだんだん迷子になってしまう。ポイントは詳細を書きすぎないこと
Github Discuttions
・QAサイトのようなもの
・TODOリストやPRのレビューコメント
・なぜ?tips、方針、議論などがいろいろなところに散らばってしまうのを集約化する
GitHubテンプレート
・PullRequest, issueのテンプレートなど
サンプルコード
・「俺の考えた最強」を一気通貫のサンプルコードとして用意
 ディレクトリ構成、変数、など・・・
・真似するだけで基本方針は最低限担保される

これらについて、チームの環境や技術力に合わせて環境を取捨選択すること

PHPで書いて覚える非同期処理
<JavascriptとPHP>
・JavaScriptは非同期処理、PHPは同期処理と言われるが向き不向きではなくその目的の違いにより最適化されているだけ
・とはいえPHPの非同期処理はあまり必要とされない
<PHPの非同期処理の成功例>
・Guzzle Promiseを使った非同期処理によるAPIコールの高速化
・PHPにおけるI/O多重化
・同時に実行しても問題ないIO処理を束ねる
・それでもあまり多くはなくPHP単体だと非同期処理の出番はない
 →なぜ非同期フレームワークが必要なのか?
<PHPで非同期実装の感覚を養う>
・システムコールと組み合わせて非同期処理を使う(Socket通信 など)
・IOモデルを理解するためにEchoサーバーをかいてみるといいかも
・写経をおすすめ
・ブロッキングIO、ノンブロッキングIO、IO多重化
 非同期処理はシステムコールやIOと一緒に学ぶと理解が深まります
・Generator:PHPのコルーチンを使ってみる→チャットがつくれるらしい(PHP7系なら動く)

ステップ実行だけじゃないXdebug
<Xdebugの機能について>
・ステップ実行やコードカバレッジだけではない

<Xdebugの導入>
・PHPの拡張
・Xdebug3の設定はxdebug.modeに有効な項目を列挙する
・xdebug_info()を使うと現在のmodeや設定がわかる

<開発ヘルパ>
・var_dump()やエラー、例外情報の表示強化
 HTMLタグ付与、出力情報の追加
・CLIでも表示を見やすく
・xdebug_time_index()
 処理開始からコールされるまでの経過時間を取得する
・xdebug_get_monitored_functions()
 指定された関数の利用状況を取得する
 どこで呼ばれているのか?を知りたいときに

<ファンクショントレーシング>
・関数のトレース情報を分析する
・xdebug_start_trace, xdebug_stop_traceを使用
 実行されたタイミングとメモリ使用量

<プロファイリング>
・実行状況のプロファイリングを行う
・xdebug.start_with_request
・Phpstorm
 path mapping設定によりプロファイルからコードのジャンプが可能

<コードカバレッジ>
・Code Coverage Analysis
・xdebug_start_code_coverage()
・PHPUnitにて利用が多い

<ガベージコレクション分析>
・ガベージコレクションの実施状況の分析
・xdebug.start_with_request

<ステップ実行>
・ステップ実行
・xdebug.start_with_request, xdebug_break()

SPAセキュリティ入門
<SPAとは?>
・SinglePageApplicationのこと
・従来のウェブはMPA(Malti-Page Application)
・MPAはjsで代入した値は次でリセットされる
・SPAはページ遷移をしないのでjsの変数は保持される、ただしページ遷移などではリセットされる→セッション管理あるいはlocalStrageにより認証状態などのデータを引き継ぐ

<SPAとCORS>
・フレームワーク任せのCORS(オリジン間リソース共有)対応は落とし穴がある
・現在のブラウザは邪悪なコンテンツによるjs実行→cookieつきのリクエストを送信してしまう、ただしCORSヘッダーがないと値を返さない水際の対策ができる
・Cookieを伴うXHRは厳しい
・現在のフレームワークはどうなっているか?pythonのFlask, jsのExpressなどは不十分
・Laravelはどう?初期状態では送信されないがcookieを使うためにオンにするとやばい
・cookieよりヘッダーで対応する方が安全

<Firebase REST APIで学ぶJWT (じょっと)>
・Firebaseとはgoogleが提供するサーバーレスプラットフォーム
・自前のサーバを用意することなく従量課金で利用可能
・認証、DB(非SQL)、ホスティングなど
・Firebase Authenticationについて
・JWTの構造:ヘッダー、ペイロード、署名
・JWTとは認証トークンの標準フォーマットのひとつで、base64エンコード
 認証連携をする際に認証情報の持ち運びに利用される
・トークンに署名つけないなんてありえない
 →そんなことない
 セブンペイの不正利用を受けて外部IDからアプリログインを一時停止した措置について、脆弱性のひとつに認証連携の機能の不備があった
 オムニセブンについては署名がない独自のやり方だったためIDの不正書き換えができてしまった
・JWTはサーバ問い合わせなくログイン状態を持ち運びできる
 サーバー側でセッションを破棄できないので有効期限、リフレッシュなどで対応
・FirebaseのJWTのデフォルトの有効期限は1時間
・有効期限が切れた状態でアクセスすると401エラー

<SPAとXSS>
・ウェブAPIの静寂性はContent-type:Application/jsonにしておけば基本的に問題ない
・JavaScriptのXSSは気をつけることが多い
・evalインジェクション
<SPAとCSRF>
・ヘッダにトークンを入れておけば脆弱性は混入しない
 Cookieでセッション管理している場合に注意
・フレームワークの機能で対策しよう
<CookieとlocalStrageはどちらがよいか>
・一長一短
・WebサーバとAPIサーバが一体の場合は古典的なセッションを使うのが比較的無難である
・クロスドメインでCookieは使わないほうが良い

2021年9月23日木曜日

突然のBad Requestの原因とその対応

ある日突然、自社の社内Webシステムにアクセスすると「Bad Request」が出るようになってしまいました。
しかもChromeユーザだけ。
私はFirefoxなので全く気づきませんでしたが、後輩が隣で悶絶しておりまして。
そこから1日がかりで解決したので(後輩が)パイセンのせめてもの務めとして記録しておきたいと思います。

<エラー内容>
ページにアクセスすると下記エラーが表示される
Bad Request
Your browser sent a request that this server could not understand.

これだけでググっても原因はブラウザのキャッシュだとかCookieだとかそんなことしか出てこないので原因究明に手間取りました。
Chromeユーザの全社員のブラウザキャッシュが飽和することはちょっとありえないので原因はサーバ側なんです。そこはわかる。

<原因>
1.Webサーバ側のApacheのリクエストヘッダー数の制限が20だった
2.Chromeバージョンアップで送信するリクエストヘッダーが増えた

<詳細>
Apacheはsecurity.confあたりにある「LimitRequestFields」という設定で
受信可能なリクエストヘッダー数を制限できます。
セキュリティ対策として使われる設定値で、これがWebサーバの納品時に20になっていたようです。ケチなのかトレンドなのか。
Chromeのバージョンアップのタイミングで自動送信するリクエストヘッダーが追加されたらしく
それにプラスして社内サイトは色々と認証だのなんだの制限をかけており、超えてしまったのが原因。

ちなみにChromeで追加されていたのは UA-CHというもので
===========
sec-ch-ua: "Google Chrome";v="93", " Not;A Brand";v="99","Chromium";v="93"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
===========
などなど将来的にUA文字列に取って代わるヘッダー情報ぽいですね。
Firefoxでエラーにならない理由もわかりました。

でも発現したタイミングが気になったのでもう少し調べてみたらそもそもChrome 89以上で既にUser Agent Client Hints(sec-ch-*関連)が送信されるようになっていたようです。
現在93なので今回サイトが超えたのはたまたまタイミングだったのかな・・・?ちょっとわかりません。
バージョンアップでExperimental Web Platform featuresの中の何かがデフォルトで有効になったのか、単にこっちのWebサーバ側で送り出すヘッダ情報を増やしたか(後輩が)
しかし何も変えてないからこそ後輩は突然殴られて悶絶したわけでうーん

そもそも明示的にクライアント側から送ってるヘッダーなんてそんなにないはずなんです。
強いて言うならCakePHPのフレームワーク関連とか。
情報が中途半端で恐縮なんですが、何かの参考になればと思います。

参考:LimitRequestFields ディレクティブ
https://httpd.apache.org/docs/2.4/ja/mod/core.html#limitrequestbody

LimitRequestBody ディレクティブは、 サーバ管理者が HTTP リクエスト中において許可するリクエストヘッダフィールド数を 指定します。(略)クライアントにより使われた要求ヘッダーフィールドの数が 20 を超えることはほとんどありませんが(略) オプションの HTTP 拡張はリクエストヘッダフィールドを使って表される場合が 多くあります。

2021年9月12日日曜日

開花

川が さらら
花は はらら

6月頃に紫陽花も見納めと生田緑地に行ったら駐車場が行列で、やむなく近くの東高根森林公園に行ったら駐車場が有料で、なぜか緑税みたいなものも上乗せされ、それと引き換えにもらったひまわりの種。を、撒いた。
100円の鉢を買い、100円の土を買い、100円の支柱を買い、スコップまで買って毎日毎日水をやりたまに栄養剤をあげてアブラムシをせっせと駆除してそのうち面倒になりながらも3ヶ月成長を見守り続けたこいつらが先日ついに開花した。
5個中発芽したのは4つ、1つは間引いてしまったので3つ。ほとんど発芽するなら複数撒きしなきゃよかったかな。緑税で貰った種が優秀だったということでしょう。さすが!





左の鉢の右の芽を間引きました。

菜箸でなんとかなるだろうと思ったらなんとかならなかった。


あまり水をやりすぎるのもよくないのかなと少し減らし気味にして二日目くらい、夜に帰宅したら全員ぐったりしてた。水をいっぱいあげたらちゃんと元に戻りましたが、植物ってすごい。

親方!蕾が出てきました

ちょっとした目玉。

開花!

千葉ポートタワー

千葉ポートタワー。
天気のせいか実物より砦感がありますね。


公園は広い。緑が多い。
公園の感想の語彙が死んでる。



子供に大人気恐竜パーク。


広さ:★★★
緑の多さ:★★★★
静かさ:★★★
その他加点:恐竜がいる

八幡岬公園

勝浦は八幡岬(はちまんみさき)公園。
ついに千葉を横断してやりました。遠かった・・・!でも長距離ドライブにも慣れてきた。




残念ながら立入禁止。登りたかった。でも海は十分美しかった。

地元のグルメ勝浦タンタンメン。この店の前にもう一軒行ったのだけど1時間半待ちと言われて諦めました。しょうゆラーメンにラー油と玉ねぎをぶちこんだラーメン。社食で食べてそれなりに美味しかったのでいつか本場で、と憧れていたもの。味はしょうゆラーメンにラー油と玉ねぎをぶちこんだ味です。


小松川境川の優しいザリガニ

小松川境川親水公園。


横になが~い公園

水辺の公園というか遊歩道というか。で、今回は。

夏のアクティビティ。

ザリガニ釣り。

死ぬほど暑い日でした。まさかこの歳になって公園で糸の先にスルメくくりつけてザリガニ釣るとは思わなかった。まあ釣果はなかったのですが。
この川自体、ザリガニがいなかったのではなく(少なかったけど。カモがパトロールみたいにキョロキョロしながら川を往復していたので、ザリガニ結構食べられているのではないかなあと・・・)なかなか釣り上げるまでが難しかったです。釣れそうで釣れないザリガニに弄ばれましたね。
でもなんか、夏の暑い日に友人たちとのんびり川に糸を垂らして「いたいた」って騒いで。
歳を取ると過ごした時間がご褒美になると言うけど、その通りだと思う。
しばしば辛いこともある現実で、いつか果たされるかもしれない約束が心の支えになるように。
なんだか夢のようだった。

手前から歩いてきてた子供がザリガニ入った虫かご抱えてたのですがとても釣れたと思えない。なので持ち帰りたい人は網が必要です。というより網にスルメ置いたほうが圧倒的に早い。

2021年8月8日日曜日

運転免許からの道 -逆行の夏

いつもの梨を同僚がくれたその日、私は梨を受け取ると予定より一時間早くその場所を出発していた。理由のひとつは梨がたまらなく食べたかったということ。
豪雨の中、いつもとは違うインターから高速にのってすぐ、私と後続車の間に白の覆面クラウンが割り込んでこなかったら、スピードオーバーを犯していることには気づかなかっただろう。
「こんにちは、すみませんね」と男はスピーカーからの轟音とは一転、愛想のいい態度で言った。私は心底怯えて彼を見た。どうしてだか知らないが、彼は私に対していきなり恐縮してみせたのだ。
「ちょっといいですか」と彼、それだけで言いっぱなしにさせるわけにはいかなかった。限度ってものがある。「あの、どうしたらいいですか?」
「交通機動隊です」
男は私を運転席から連れ出すと、風が吹き荒れて裏返しになっている傘を差し掛けてくれた。
-----

(要約)
スピード違反ではじめて捕まりました。戒めのために記録しておきます。

大井インターから湾岸線に乗り、前に車がいなかったのでアクセルを踏み込んだら、突然後ろから鳴り響くサイレン。一瞬で「あ、自分だ」と察しました。咄嗟にメーターも見ました。でも85キロって高速普通じゃない?結果そこは高速ではなかったのですが。
どうしていいのかわからず減速し、車線を左に寄せて止まりかけたら止まらないでと後ろから叫ばれる。オーディオのボリュームを落としても、何を言われているのか聞き取るのがとても大変で、いっそ緊急時に警察用割り込み信号でメッセージがカーナビに表示されるようにすればいいのにと後から思いました。いやよく考えたらこれ怖いな。やめよう。
道路脇に止めて、申し訳なさそうなお兄さんにエンジンかけたままワイパーだけ止めて後ろの車に移るように指示をされる。そして免許を確認され、スピード違反に伴うありがたいお説法を頂戴しました。
「ここ速度制限60キロなの知ってました?」「いいえ」
「メーター見てました?」「いいえ」
「今日こんな天気だし、気をつけて運転しないとね」「はい」
「今日はどこまで行くんですか?」「●●まで」
「ちょっと遠いですね。急いでたんですか?」「いいえ」
「これから気をつけて運転してね」「はい、承知いたしました」
そしてサインを2回書き、指紋を取られ、振込票を渡され、開放していただけました。
指紋。
前科一犯の重み・・・

心の底から高速だと思っていただけなんですうううう!
だってETCも入り口でなんかムニャムニャ言ってたもんんんん!
という心の底からの叫びも虚しく2点マイナス、反則金15000円。
梨の代金にしては高すぎる。シャインマスカットか。
しかし、勉強になりました。急いでもおらず人を乗せてもおらず何よりこれが派手な事故とかでなかったことに心の底から安堵しました。今日一日で心の底絞りきりました。
車を出発してもしばらく後ろにつかれ、まさかこのまま●●までついてくるんかい・・・とビビりましたがそんなことはない。
別れ際助手席の人が会釈をしてくれました。優しい人でした。再犯だとこうはいかないかもしれんが。
 
帰路は高速に乗る元気がなかったので一般道で。でも気を抜くとやっぱり
357の直線でブッちぎりそうになる。これ道路が悪くない?To err is human! To forgive divine! 悪いのは組織かシステム、神よそれに道路を追加されたし。
それまで無事故無違反でしたので、明日から3か月間、無事故、無違反なら点数は加算されないとのことです。お天道様はいつもあなたを見ていますの精神で、スピードと一時停止と信号を守ります。国道357号、てめえのツラ覚えたかんな。

-----
免許がもう二度と昨日と同じ色の免許に戻らないことは明白だった。私は運転を愛し、そして多くのもの(まだ見ぬゴールド免許と社会的信用)をそこに捨て去ったのだという気がした。

(John Varley,  Retrograde Summer.)

余談:
先日実家に帰宅した際父親にこの出来事を話したら
「これから運転するときは気をつけろよ、ちゃんとバックミラーみて、うしろのやつが『二人組じゃないか』と『青い制服着てないか』しっかり確認するんだぞ!」
と、斜め上のアドバイスをもらった。何の役にも立ちやしないよ、お父様・・・。

2021年7月25日日曜日

長柄ダム

長柄(ながら)ダム。横浜市某区から1時間半。市原SAでトイレと給油挟んだので2時間。
結局料金はオリンピックで上がったのかどうなのか不明なままアクアラインを突っ切り一路長柄へ。今日は遠くまで行くケツイをしていたので苦ではなかったですが結構遠かった。
でもまあ行った甲斐はありました。

カフェ的なものがありました。長柄ダムと間違えた。


長柄ダム駐車場。この車のなさ。これぞ千葉。

周辺案内。が、ない。目の前の景色が全てってことですね。

さすがにこれは広すぎて歩けない。歩くケツイは持ってこなかった。

Googleマップに載ってた写真。これを降りてみたかったけど立ち入り禁止でした。残念。

360度森と湖のほんとにいいところでした。私がいた時間はほぼ人がいなかった。唯一、YouTuberみたいなのが自撮り棒持っていた。ほら独り占め、あな二人占め。

2021年7月23日金曜日

彩湖・道満グリーンパーク

友人の家に近かったこともあり前から行ってみたかった彩湖・道満グリーンパーク。ここ埼玉だったんだ、板橋かと思ってた。会社のウォーキングイベントのノルマも兼ねて。




撮れ高が足りなかったので駐車場を。


広いは広いです。歩きごたえはちゃんとあります。バーベキューとかも。変わった柄のTシャツかと思いきや全部スミだったみたいなやんちゃな兄さんとか見ました。トラックの売店もありました。冬はあんまりやらないですけど夏だと耐え難くやりたくなる、買い食い(みかんのかき氷)。

町田リス園

久しぶりの町田。はじめての町田リス園。いつもと趣が違う。駐車場はほとんどないので薬師池東第1駐車場に止めると良いと思います。


癒やしか・・・毛の生えたペットに興味のない自分でもモルモットくらいなら飼えるかもしれない

ここの目玉です。来場者参加型アトラクション「タイワンリスに餌をやる」
朝早いとお腹をすかせたリスたちが飛びかかってきます。餌をやるというか格闘するというかひとつ100円の餌で思う存分リスとどつきあえ触れ合えます。
餌のところで鍋つかみみたいな手袋を貸し出してもらえますが、絶対に長ズボン、生地の厚い長袖、なんなら袖のところが止められるような防御力の高いやつがいいです。飛びかかってきたリスに腕とか胸のど真ん中を駆け上がられて跡になったりします。気づいたら腕が傷だらけ。

写真取るのも命がけです。肌が露出したら一瞬で殺られます。でも多少の傷なんかどうでもいいくらい楽しめました。

本土寺

紫陽花も最後と千葉は本土寺へ。
噂に違わぬあじさい寺でした。駐車場が全然足りてないので寺の周りのあちこちに有料駐車場があります。それでも早めに行ったほうがいいですね。自分はコーヒー屋さんの駐車場に500円で停めさせてもらいました。


満開ギリギリのところでした。青や白、紫のスタンダードな色から濃ピンク色まで綺麗に咲いてました。やっぱりあじさいっていいな。




食欲に負けてすももと草だんごも食べました。休憩スペースもあってお茶が無料なのが嬉しい。

2021年6月28日月曜日

生田緑地(n)

もう何回目かわからない(n)けどあじさいの季節は必ず一度は来るようにしています。年々あじさいが少なくなっているような気も・・・生田緑地の維持のためのボランティアとか募集してるらしいのでやってみようかな。





今回ここははじめて。枡形山展望台です。

展望台からの景色を撮りそこねました。というのも展望台で景色を撮ろうとスマホを取り出したら職場で事件が起こっていたので・・・
今年はあじさいに見送られながら職場に急行するというおまけつきでした。