だらだらと思いついたこととか書くブログ

エンジニア的なネタとか備忘録とかを書いていく予定

2025年のふりかえりと2026年の抱負

はじめに

長かったように感じて、終わってみるとあっという間だった2025年。 自分には40歳になるという節目の年だった。

この一年を振り返りつつ、新たな一年について考えてみる (というかいつもの年一記事)

2025年について

妻の仕事の変化や子の成長といった家族イベントはもちろん、仕事面でも悩むことや葛藤も大変な一年だった 昨年も「大変だった」と言っていたが今年はそれよりも大変だったように感じた(けど、毎年そう思うのかも・・) 一方で会社の同僚とは何とかやれていたり一緒にイベントを楽しんだり出来たし、今年は犬も含めた家族で旅行にいったりお出かけしたりと楽しい思い出もいっぱいあってそういう面で変わらず環境に恵まれた一年であった。

夫として・父として

"夫として"は正直、「何ができたのかな」という思いは昨年に続きあり、特に家事、その中でも掃除や料理といったことは妻に任せてしまったりと負担を掛けてしまったことが多かったように思う。

ただ妻は変化もあり、相当大変であったであろうこの1年を一緒に乗り切るためのサポートなどは多少できたのかなと考えている。

また妻の変化により、子どもの世話や面倒を見させてもらう機会や時間が昨年に比べて増えた。

これはもちろん大変ではあり、時にはツラいときもあった

ただ、小さな子どもと過ごせる大事な時期少しでも携われて良い思い出もいっぱいあった

幸い、子どもも自分には懐いてくれているように見えてとても嬉しい。これは何よりものかけがえのない幸せである。

一方話を戻して"夫として"は、妻の「推し活」を応援してあげるくらいしか出来なかった気がする。

もっと自分の目指す夫、求められている夫の解像度を上げる必要があるかなと感じた。

父としては、 - 休日に二人きりもしくは家族で一緒に外で遊ぶようになった - 保育園への送迎をする機会が増えて、先生やクラスメイトのママ、パパとの関わりをより持てるようになった - 妻が予定がある際に自分だけでもそれなりに面倒が見れるようになった

などなど、大したことはないかもしれないが自分としては大きな成長・進歩だった

また家族と過ごす時間を積極的に取れるように、仕事をいったん早めにあがって一緒にごはんやお風呂をしてから、また仕事という生活スタイルを取る日も昨年に引き続き継続でき、これは会社やチームメイトの理解の上に成り立っていることに感謝しつつ、引き続き継続していきたい

犬にもいろんな場面で助けてもらったり、一方でガマンしてもらっていることも多い反面、それを全然返せていないと感じている。 いつもながら本当に家族にはいつも支えてもらっていて感謝ばかりである。

仕事について・開発者として

"仕事"については、今年は「忙しなかった一年」というのが自分の中でもあったし、チームの中でもわりと同じ認識のようだった

ただ、自分個人で見るとあまり大きなことを成し遂げていないように感じることの多い一年だった

生成AIの進化もすさまじく自分も業務で活用しているが、生成AIによってやはり「レビュー」が大変になってきていることが個人としてもチームとしても大きな課題であり、ここが開発生産性を上げていく上で今後、重要なトピックの1つだと痛感している

今年の後半は、 - 自分としてはこれが「自分の大きな成果である」と言えるものが特に無かった - こぼれた球拾いのようなことは続けてやっていたが、それがチームとして低く(≒価値のないもの)見られているように感じてしまっていた - 「チームを全体からみる」ような動きをしているつもりだが、その立ち回りについて「マイクロマネジメントすぎる」というようなことをチームメイトから言われてしまった - これは自分でも気づいていはしたものの、目を背けていた現実ではあったのでかなり響いた

こんなことがあり、年末はちょっとメンタルを崩し気味だったりと、かなり辛かった

いま何とかもし直しつつあるものの、具体的な改善や対策は見えておらず、まだ"穴から脱出できていない"ので、ここを何とかするのが喫緊の課題となりそう

年明けに唯一の上司との面談があるので、そこで自分のこれまでの答え合わせや今後についての壁打ちに付き合ってもらいたいと考えている。

youtu.be

たまたま及川さんのLinkedInのポストから上記の動画にたどり着いたのだが、やはり自分はこの手の「プロダクトをつくる」ということに対して非常に興味や関心が高いことにあらためて気付かされた

自分に求められている動きは、もしかしたら自分の考えているものとは違うが「システムアーキテクト」や「ビジネスアーキテクト」。この2つ自体は大きく違うものだが、この辺の「アーキテクト」というのがいまの自分が目指していて、かつ自分に求められている動きなのではないかと感じている

またチームメンバーは残念なことに1人減ってしまったものの、今年の4Qに2人加わり、それなりの人数になってきてできることが増えてきそうなのは嬉しく、期待できる面である

一人は今いるメンバーに比べて若手のメンバーで、彼には現行のメンバーを突き上げて底上げしてくれるような動きを勝手ながら期待している

もう一人は、実は私が入社した時に色々お世話になったメンバーで、ソフトスキル、ハードスキルともに非常にバランスにも優れていて優秀な方なので、素直にまた一緒に仕事できるのが嬉しい

新しい体制で来年は本格的に始動していくので、自分の課題にも向き合いつつ、チームともしっかり向き合いながら新たな1年やっていきたいと考えている

その他

幸い周りの環境や人には恵まれていて、大変なときに相談にのってもらったり、話を聞いてもらったり今年も本当にいろんな人に助けてもらった

また出社する頻度は昨年に比べると大きく減ったが、同僚と一緒にランチをする機会が良い息抜き、気分転換にもなって非常に良かった

健康面では昨年からさらに体重が増えてしまって周りにも心配されるくらいになってきてしまった・・

ストレス解消も兼ねて隔週でキックボクシングでカラダを動かしているがそれだけでは全然運動不足。食事というか間食を抑えないといけない。

相変わらず休み方や特に休日の過ごし方が下手くそなので、これに関する書籍や動画を最近は見ていた。

先述のキックボクシングのように自分にはいわゆる「アクティブレスト」が足りてなさそうなので、そのへんを意識してみながら過ごしていこうと思う。

2026年の抱負

夫として・父として

"夫として"は、まずは自分の目指す夫、求められている夫の解像度を上げて目標を設定するところから始めようと思う

なかなか自分の苦手な部分ではあるが、しっかり向き合うべき時でもあると思う

昨年に引き続きだが、妻が困っている時、家族が困っているときに「頼れる存在」として価値を出せるようにしたい

"父として"は、子どもと関わる時間(+家族と関わる時間)は引き続き大事にしていきたい

そのうえで、もっと子どもと出かけたり、犬も連れて一緒に出かけたりする機会もさらに増やしていきたい(手札を増やしたい)

仕事について・開発者として

自分の会社での立ち位置としていまは肩書が「シニアエンジニア」となっている

ただ個人としてはもっと広い範囲に影響を与えられる、いわゆる「スタッフエンジニア(スタッフプラス)」を目指したい (昨年は達成できなかった・・)

そのうえでおそらく「アーキテクト」もしくはそれに近しいなにかでもっとチームにも貢献できるような動きをしつつ、個も出せるような動き回りをしていきたい

その他

休日や余暇はアクティブレストや、さらに今年は少しワガママを言って人と会う機会を増やしたい

今年も同僚のサポートもあって対外的なアウトプットを出せたことはKeepで今年もつつけていきたいが、昨年はちょっとムリもあったのでその辺はうまい塩梅でやっていきたい

昨年の主なアウトプットは以下の通り - 技術書典のスポンサーブース - GoConferenceのスポンサーブース - 技術同人誌 - U-NEXT TECH STREAM 03の「第2章 サービス統合の話 」

techbookfest.org

  • 技術同人誌 - U-NEXT TECH STREAM 04の「第1章 スーパーフラットな組織でどのようにして開発しているのか 」

techbookfest.org - 会社のアドベントカレンダーの記事

アーキテクチャConference(1日目)に行ってきた|sora083

最後に

こんなことを年末年始の休みで考えていました。

2026年もいろいろな変化があり、いろいろな悩みや葛藤も多くあると思います。 40というおそらく人生の折り返し地点を過ぎて、少し違う向き合い方をしながら困難を乗りこなしつつ、自分や自分たち家族なりの幸せを見つけ、それを実践して楽しく暮らしていけたらなと思います!

今年もよろしくお願いします!!

ありがとう2024年とやってきました2025年

もう2025年も明けて1週間近く経ちますが、明日から仕事始めというタイミングで昨年の振り返りと今年やりたいことなどについてつらつらと書きます

2024年について

色々大きなイベントや変化があり、とにかく大変だったことや時には辛かった思い出が多かった一年だった

一方で会社の同僚とあったり、久しぶりに友人、知人に会える機会もちょこちょこあったり、年の後半には家族で旅行にいったりお出かけしたりと楽しい思い出もいっぱいあった

夫として父として

"夫として"は正直、「何ができたのかな」という思いが多く、妻に任せてしまったりと負担を掛けてしまったことが多かったように思う

ただ妻は自分よりも大変であったであろうこの1年を一緒に乗り切るためのサポートなどは多少できたのかなと考えている

(一緒に乗り切れなかったときもあったけど・・)

ただ妻の話を聞いて、相談にのったり話をしたり、振り返ってみると本当に自分が夫として妻に何かできたのはこれくらいな気がしている

一方"父として"は、昨年の4月から子どもが保育園に入園して、生活スタイルが変わったことにより、自分の関わり方にも色々と変化があったように思う

最初のことはほとんど関われなかったのだが、

  • 休日に二人きり、もしくは家族で一緒に外で遊ぶようになった
  • 保育園への主に送りをすることで、先生やクラスメインとのママ、パパとの関わりを持てるようになった
  • (ほとんどなかったけど)妻が予定がある際に自分だけでもそれなりに面倒が見れるようになった

などなど、他のママさん、パパさんから比べると大したことはないかもしれないが自分としては大きな進歩だった

また家族と過ごす時間を積極的に取れるように、仕事をいったん早めにあがって一緒にごはんやお風呂をしてから、また仕事という生活スタイルを取る日も多かった

※これは会社がフレックスを導入していることと、チームメイトなどの理解があって成り立っていることだが・・

本当に家族にはいつも支えてもらっていて感謝ばかりである

仕事について、開発者として

"仕事"については1Qで大きな仕事があり、昨年のプロジェクトの中で自分が一番コミットしたもの、かつ一番大きかったものがこれだった。

詳細は語れないが、プロジェクトとしては自分のエンジニア人生でもそう多くは経験できないような規模のもので、自分がメインで担当した部分は今回のプロジェクトには必須である、自社のサービスのこれからの発展にも不可欠な要素だったのでハードだったがやりがいもあったし、それに見合う評価ももらえたように思う。

ここでの動き方では「一部の開発リード」兼「片足プロジェクトマネージャー」みたいな立ち位置で動いていた(と思う)

特に後者のような動き方のほうが"開発"よりも自分に向いてて、かつバリューが出せるところと感じていて、ここでの立ち回りをなんとかでもこなせたのは大きな自信につながった

また、ここが自分でも興味がある分野であるので、さらに経験を積みつつレベルアップしていきたい

ただ、いま居る組織は「マネージャー」や明確な「プロジェクトマネージャー」というロールがいない、「スーパーフラット」という非常に特殊な組織構造を採用している

そのため「◯◯マネージャー」の存在意義や価値については、きっと組織内でも賛否両論だと思う

ただ、自分は明確なロールや肩書はなくとも、ここに該当するような動きを担っていくのがバリューが出せるし、自分にも向いているし、ひいては組織としても確実にアウトプットを出せることにつながっていけているのかなと考えている

一方で"開発者"としては、技術やエンジニアリングで解決した"大きな何か"というのは特筆すべき(というかできる)ものが無かったように思う

小さな改善やトライは多少はしたが、何か新たな仕組みを導入したり、技術的に新たな取組みや自分としてのトライもなければ、資格取得や体系的な勉強など前向きに取り組んだ"これ"というものが無かったように思う

ここについてはやはりいま所属している組織では自分も含めて全員が、いわゆる「IC(Individual Contributor)」の立場であることを踏まえると、常に磨き続けなくてはいけないポイントである

最近は「リファクタリング」や「メンテナビリティの高いコードの書き方」にやや興味があり、積読してしまっている本もあるので、このあたりから取り組んでいきたい

その他

幸い周りの環境や人には恵まれていて、大変なときに相談にのってもらったり、話を聞いてもらったり本当にいろんな人に助けてもらった

また出社することが多く、同僚と一緒にランチをする機会が良い息抜き、気分転換にもなって非常に良かった

健康面では昨年から体重が15kgも増えてしまって、いろいろとマズい、というかマズすぎる・・

40手前にしてこの体重はマズすぎるので、ストレス解消も兼ねて隔週でキックボクシングでカラダを動かしているがそれだけでは全然運動不足・・

また今年は出社ではなく自宅からのリモート勤務も増える見込みなのでより運動不足に拍車がかかるので、これはかなり喫緊の課題である

相変わらず休み方や特に休日の過ごし方が下手くそなので、ここも今年、改善したいなと感じている

2025年の抱負

夫として父として

"夫として"は、今年からまた家族で大きな変化を迎えていることもあり、「頼れる存在」でありたいとぼんやりだが考えている

妻が困っている時、家族が困っているときに「頼れる存在」として価値を出せるようにしたい

※と想ってはいるが具体策が思い浮かばない・・

"父として"は、子どもと関わる時間(+家族と関わる時間)は引き続き大事にしていきたい

そのうえで、もっと子どもと出かけたり、犬も連れて一緒に出かけたりする機会も増やしていきたい

仕事について、開発者として

自分の会社での立ち位置としていまは肩書が「シニアエンジニア」となっている

ただ個人としてはもっと広い範囲に影響を与えられる、いわゆる「スタッフエンジニア(スタッフプラス)」を目指したい

組織のロールとしては用意されていて、実際に「スタッフエンジニア」に位置する肩書で従事している同僚もいる

もちろん肩書が変わったから何か動き方が変わったり、職位が変わったりということではないが、一つの目安として考えているし、そのくらい組織にインパクトを与えられる存在ではありたいと考えている

(ここはすごく欲が強い部分なのだろうなと感じている)

また振り返りでも述べたが、今年は"開発者"としてのスキルのアップにも少しフォーカスしたい

知識を得つつ、実践を繰り返して、今年は「これをやった」といえるアウトプットを出したい

その他

「休日をうまく過ごせるようになりたい」ので、まずは手始めにこの本を読んでみようと思う

また人と会う機会が減ってしまっているので、今年はもう少し、実際に人と会う時間を作りたい

あと今年は同僚のサポートもあって対外的なアウトプットを出せた

大変なこともあったけどとても良い経験だったし、これは継続していきたい

最後に

こんなことを年末年始の休みで考えていました

明日から仕事も始まり、2025年の"日常"が本格的に開始していきます

今年も色々と変化がありますが、無理せず、楽しみも作りながら笑顔で過ごしていきたいと思います!

2022年の振り返りと開発プロジェクトの進め方について

気づけば2022年も年末。

犬の散歩をしたり大掃除をしながらふと今年を振り返りながら、プロジェクトの進め方や管理、特に"アジャイル"について少しだけ考えたり感じたりしたので、それのメモも兼ねて書きます。

前提

自社サービスのバックエンドサービスの開発・運用に携さわっている。

年齢は30代後半で、エンジニアとしては十数年働いており、現在の会社は2社目で4年超の在籍になる。

  • 周りの元同期や年次が同じくらいのエンジニア界隈の方も、組織を率いていたりグループやチームなどをリードしていく立場にある人が多い
  • 一方で自分の所属している会社では「スーパーフラット」という組織構成になっており、開発部隊ではCTOが居てその下は全員、上下関係といったヒエラルキーの無いフラットな組織である

チームは領域やサービスによって分かれておりチームごとに文化の違いはあるものの、基本的には開発方式はアジャイルで「スクラム」を基本としたものが採用されている。

  • スクラムマスターの有無もチームごとに異なっている
  • 現在所属しているチームはメンバーが6人いるが「専任のスクラムマスター」が存在しておらず、スプリントごとにローテーションしていくスタイルを採っている

最近感じていることや取り組んでいること

(これは以前からの課題であるが)"フラット"であるがゆえの自由さや物事の進めやすさがある。

  • 一方でそこのいわゆる勘所が"経験"や"個々人の指向"などに依存している部分が多く、特に経験の浅い、いわゆるジュニアメンバーはここがつかめず苦労している印象がある
  • さらにコロナでリモートワークがメインになり今後も続いていくことが決まっているので、この流れはさらに加速していくと考えられる

今までは「スプリント内の定期進捗MTG(週1程度)」や「振り返り」などでここをカバーしていたつもりだったが、なかなか報告・相談のタイミングがうまくつかめなかったりという状況が発生していた。

  • 対策として最近は「デイリーハドル」を開催するようにしてみていて、一定の効果が出ているように感じている
  • ただ、一方でデメリットとして全体の進捗が見えづらくなっているという面もあり、これは進め方の工夫が必要だと考えている

ジュニアメンバーで、自分でも課題を抱えている自覚はあるがどうして良いのか分からない状態に陥っているように見えるメンバーが居り、1on1で本人の課題感やアドバイス的なことなどをお話させてもらった。

  • それを皮切りにせっかくなのでと考えて、メンバー全員と1on1をしてみた
  • リモート中心になってから一緒に仕事をするようになったメンバーも多くいることなどから、メンバーの意外な面や抱えている課題、考えなどが聴けて個人的にはとても良い機会だったと感じている

その中で出てきたコメントの1つとして、担当プロダクトのカバー範囲が広くなってきており、途中からの参画などにより"すべて"の把握が難しいメンバーが居るということも分かった。

  • これは自分も"そうなのかな"と感じていた部分でもあったので、あらためてここを確認できて認識の答え合わせが出来た

今までは「なるべくすべてカバーしよう」という雰囲気になっていたが、一方で「プロジェクト単位でメインで担当する範囲を区切る」という試みも行っている。

  • 特に経験の浅いメンバーにはこの試みで"自信"と大まかでも"プロジェクトの進め方"について学んでもらえると良いなと感じている

また、あるメンバーとの会話の中で「アジャイルもっとちゃんとやっていきたい」という話が出ていた。

ここはチームとして「課題」を抱えていると同時に、「改善の余地がある」部分でもあるので、ここについて掘り下げてみたい

チームとアジャイルについて

チームでのアジャイルと課題について

  • 先述の通り"スクラム"をベースとした開発手法を採用しており、"専任のスクラムマスター"が居らずローテーションで回している
  • プロダクトオーナー(以下PO)が存在しており、POと開発チームで「リファインメント」によって"次スプリントでやること"が決められていく
  • JIRAを利用しているがバックログの管理があまりちゃんとできておらず、自分や気づいた開発メンバーがメンテしていることが多い
  • リファインメント前のタスク整理は、当番のスクラムマスターが担当している
    • ただし事前の大まかな整理は自分が暗黙的にやっている
    • 上記のバックログの整理も含めて自分の"シャドウワーク"となってしまっていてあまり良い状況とはいえない
  • スプリント内にタスクが消化しきれず"持ち越し"が多い(=タスクの進捗が安定していない)
    • さらに持ち越しが常態化しているメンバーも居る

なぜ問題が発生しているのか

  • チーム全体(POも含めて)の「アジャイル」に対しての共通認識が持てていない可能性がある
  • POの責務が広すぎて"バックログの管理やメンテ"といったことに対応できていない
  • 特にジュニアメンバーに見られがちだが「自分のタスク」にフォーカスしすぎて、その結果何が起こるのか、そもそもなぜこの仕事をしているのかが見えていないのかなと感じることがある
    • 結果としてタスクを持ち越してもいいや、となってしまっているように感じている
  • これは個人的に感じたことだが、TeamGeekなど触れられているHRT(謙虚・尊敬・信頼)がチーム内で欠けてしまっているように見られた
    • 自分としては"信頼"が薄らいでしまっているメンバーが居るように感じている
    • もしかしたらメンバー間の"尊敬"も人によってまちまちだったりするのかもしれない

信頼について

"信頼"についてはこれもあくまで個人的な考えだが、いわゆる"社会人としての基本的なこと"がもっと大事にされてもよいのではと感じる場面がある。

結果そこが"信頼"の欠如につながってしまっている一因となってしまっているのではないかと考えている。

  • 例えば、時間や約束を守る、敬語を正しく使う、他人に関心を持つ、貢献してくれた人にお礼を言う etc.
  • この辺りを学ぶ機会に恵まれなかったという面もあるような気がしている
    • 少なくとも"自分が感じている違和感"が、少なからずそのメンバーに対するマイナスイメージに繋がってしまっているという影響も多少あるような気がしており、この状況は良くない

我々は課題にどう立ち向かっていくのか

  • スクラムに関するワークに関しては、あらためて「専任のスクラムマスター」を置くことも検討しつつ、少なくとも"シャドウワーク"はなくしていきたい
  • 1on1のときにも話題に出たが、チーム感で「アジャイル」や「スクラム」の対する共通認識を持つ機会を作る
    • 以前に実施したことがあったがその頃と今とではメンバーもだいぶ変わっており、時間も経過しているのでいまの状況やメンバーに合わせたカスタマイズが必要と思われる
  • "社会人としての基本的なこと"について相互理解や、どこがお互いの着地点かを探る機会を持つ
    • 自分の価値観が古い部分や正しくない部分なども大いにあるはずなので、お互いの相互理解を深めつつ、お互いにとって働きやすい関係性を構築したい

最後に

そんなことをふと考えた2022年末でした。

来年も色々と忙しく充実した一年になりそう予感なので、引き続き頑張っていきたいと思っています。

来年もよろしくお願いします!

p.s

こっそり会社主催のLTがありプレゼンをする機会がありました。もしよければご一読いただけますと嬉しいです。

https://www.docswell.com/s/sora083/5RPG1Z-2022-08-26-093111

API呼び出しをRestTemplateからWebClientに切り替えた話

どんな話?

spring-bootで作成されているマイクロサービス間のAPI通信のクライアントをRestTemplateからWebClientに切り替えてみましたという話。

なぜ切り替えたのか、どのように対応しているのかといった内容を書きます。

なぜ切り替えたのか?

ビジネスロジックの中でいくつか別サービスへの通信を行っているが、いくつか非同期で通信を行える箇所があった。

メッセージキューを利用したりと徐々に非同期化を図っていたが、今回のケースでは解決法としてWebClientを利用するのが適してそうなこともあり試してみた。

そもそもRestTemplateは2022年4月現在でメンテナンスモードとなっており公式でもWebClientの利用が推奨されていたため、近い将来切り替えたいという話も上がっていた。

切り替え前の状況

ビジネスロジック内の1処理としてhttp通信での別サービスの呼び出しを行っている。

この通信自体は即時性が求められるものではなく、非同期での連携で問題ないものではあったが同期的に通信処理を行っていた。

ただし連携開始してから、たびたび通信が不安定になるケースが発生しており、これに起因しての不具合が発生する事がわかった。

そのため非同期連携に切り替えようと思いどんな方法が良いかなと考えたところ、WebClientでノンブロッキングでの連携が適していると考え切り替えを実施した。

切り替えについて

実現したいこと

  • 非同期、ノンブロッキングでのAPI呼び出しを行いたい
  • タイムアウト発生時にはリトライを実施したい(通信状況が不安定なケースでもリトライで復旧するケースも多いため)

実装例

APIクライアントの定義例

@Component
public class ServiceApi {

  private final WebClient webClient;

  public ServiceApi() {
    this.webClient =
        WebClient.builder()
            .baseUrl("URL")
            .build();
  }

  public Mono<Void> create() {
    log.info("cacheUserPlan request={}", request);
    return this.webClient
        .post()
        .uri("URL")
        .retrieve()
        .bodyToMono(Void.class)
        .retryWhen(
            Retry.fixedDelay(2, Duration.ofSeconds(5))
                // タイムアウトエラーが発生した場合には5秒間隔でリトライを行う(2回までAPI呼び出しを試みる)
                .filter(
                    throwable ->
                        throwable instanceof WebClientRequestException
                            && (throwable.getCause() instanceof ConnectException
                                || throwable.getCause() instanceof TimeoutException)));
  }
}

API呼び出し側の実装例

今回はビジネスロジックからの該当のAPI呼び出し部分のみノンブロッキングにしたかったため呼び出し側でsubscriberを利用 (Monoのままプレゼンテーションでレスポンスはしない)

ServiceApi
    .create()
    .subscribe(
        response -> {
            // API呼び出しが成功した場合の処理
        },
        exception -> {
            // API呼び出しでエラーが発生した場合の処理
        });

参考にさせていただいた情報

リトライのテストについて

リトライ周りのテストをどう書くのが良いか分からず少しハマった。

調べてみた限りMockWebServerを利用してモックサーバにAPI接続して試す方法が良く紹介されていたのでそちらを利用してみることにした。

参考にさせていただいた情報

今後について

切り替え後はしばらく様子を見てエラーハンドリングやリトライ設定などを今後必要に応じて見直していきたい。

リトライについてはjitterを利用したexponential backoffの利用なども考えていきたい。

RestTemplateを使ったAPI接続で並列処理数が上がらずにハマった話

どんな話?

RestTemplateを使ってのAPI呼び出しで複数スレッドでの並列呼び出しを行っているのに、なぜか呼び出された側で5並列まででしか処理をされていないという事象が発生して調査してみましたという話。

色々試してみたりで新たに学んだことがあったので備忘録兼ねてまとめた内容。

状況

※以下、API接続の呼び出し元のとなるサービスを「サービスA」、APIを提供しているサービスを「サービスB」と表記します

  • サービスA、BともにJava&spring-bootで作成されているアプリケーション
  • サービスAでは少なくとも10スレッドでリクエストしようとしているアプリケーションのログを確認
  • サービスBでは5を超えるスレッド数で処理できているAPIも存在している様子
  • サービスAではRestTemplateはデフォルトの設定で利用
  • サービスAではサービスBと別のサービスへのAPI接続も行っており、そちらではapacheの httpcomponentsのhttpclientを利用していた

調査してみて分かったことと原因

  • サービスAのRestTemplateでは「javaのHttpURLConnection」ではなく、「apacheのhttpcomponents」が使われるようになっていた
    • debugでRestTemplateの設定内容などを確認してみて判明した
    • ここは推測だがdependencyとして「apacheのhttpcomponents」が定義されている場合にRestTemplateをデフォルトで利用すると、「apacheのHttpComponents」のhttpclientが利用されるようになるらしい
    • 試しにapacheのhttpcomponentsをdependencyから外してAPI接続してみたところ、サービスBの処理が10スレッドで走った
  • RestTemplateでapacheのhttpcomponentsをデフォルト設定で利用する際に、connection poolの設定の中でmaxPerRoute)という値があり、これが5で設定されるようになっていた
    • そのため、同一接続先への接続上限数が5になっており、サービスBで最大5並列まででしか処理されていなかった
    • 上記のmaxPerRouteの設定を試しに10に変更してみたら、サービスBの処理が10スレッドで走った

まとめ

  • 複数スレッド走らせる場合のテストはちゃんとやらないとダメ(特に今回はローカルでも再現可能な事象だったこともありこれに尽きる)
  • IDEデバッグ機能の活用大事
  • RestTemplate理解したつもりになっていたけどよく分かっていなかった・・
    • ドキュメント見たり、挙動見たり今回のことを通して学びました

その他参考になったページ

terasolunaorg.github.io

最近の仕事や環境で思っていること

昨年の2月中頃からリモートワーク中心になり1年強。

この1年で所属しているチームのメンバーが変わったり、様々なタスクやプロジェクトを進めたりと日々過ごしていく中で、当然ながら色々感じたことや思うところがあった。

近々チーム内での振り返りをしましょうという話があるが、まずは自分が感じていることなどを一度整理してみたいと思っていたこともあり、 思いついたことなどをつらつらメモがてら書いてみます。

ずっとアタマにはあったけどここで急にやってみようと思ったのは、アジャイルな開発とチームづくりの内容に触発されたのがきっかけの1つ。

チームとプロジェクトの進め方について

チームはバックエンドのAPI開発・運用を担当しているチーム。

メンバーは7人いて、ここ1年くらいで新しくチームに加入してくれたメンバーとそれ以前から在籍しているメンバーが半々くらい。

2週間スプリントでアジャイルで開発を進めているが、担当プロダクトはSoRでわりとウォーターフォールよりな開発が必要とされている部分が多いように感じている。

主要な登場人物としては、PO(Product Owner)と開発チームメンバーがおり、POは1人で複数プロダクトを兼任しているような体制。

開発は複数プロジェクトをチーム内で分担しながら進めているような状況。

チーム内でリーダーという役割・肩書の人はおらず、ファシリテート役をローテーションで回すなどしている。実質、リーダー的な役回りをしてくれている人がいたりもするが、その人にだけ負荷がかからないような仕組みづくりができるようチーム内で心がけている。

最近の取り組みや役割について

以前はチーム全体で複数プロジェクトで必要な対応をばーっと並べて、進めたいタスクを取っていきやっていくスタイルだったが、複数プロジェクトを並行して効率的に回していくための取り組みとして、プロジェクトごとに主担当とサブ担当みたいな割り振りをして、各自で担当プロジェクトの対応を中心にタスクを取っていき進めていく手法を採るようにしていきましょうという話になっている。

また所属チームは開発・運用はもちろん、プロジェクトの優先順位の調整や要件定義、プロジェクトリードのような立ち回りも担っていることが多い。

最近感じていることや課題

プロジェクトの進め方と役割分担

前述のようにプロジェクトに対しての関わり方を変えたことで、以前に比べてそれぞれのプロジェクトに専念できるような仕組みづくりとなってきた一方で、テックリードやマネージャーなど役割の人がいないため、プロダクト全体や他プロジェクトとの関係などに気を配る人、というのを役割として明示的に担っている人がいない状態となっている。

そのため中心的に動いてくれている人や、やれる人が全体の把握などを"暗黙的にしている"という状態になっている。

この暗黙的というのが難しく、出てきた課題をどうするか、ここからどうプロジェクトを進めていくかなどといった、プロジェクトを進める舵取りをしていく中での"関係者"を誰にするか、というところなどで頭を悩ませる場面もたびたびあり、結果としてチームがうまくスケール出来ていないのではと個人的に感じる場面がある。

かと言って、そこを完全に分業してしまうと、全体を把握できるメンバーが新たに出づらくなる、担当プロダクトの全体感が見えづらくなるという弊害もあるように感じているので、この辺りのバランスをどこに持っていくのか、というのが非常に悩ましい課題だと感じている。

プロジェクト内での役割と要求ハードルが高くなっているのではという危機感

次にプロジェクト内での役割についてだが、暗黙的かつ必要に応じて担当している"役割"みたいなものが大きく、あるプロジェクト内でのあるプロダクトの担当メンバーという立ち位置だけでなく、プロジェクトリード的な立ち位置も一緒にこなす必要が出てくる場面がたびたびある(というより増えてきている)。

これにより"主担当を持つこと"に対して心理的なハードルも高くなってしまっているように感じている。

今後について

プロジェクトの進め方と枠割分担については、今後も手探りで進めていきながら「ちょうど良いバランス」を模索して、調整しての繰り返しでやっていくのかなという感じ。

ここに書いていること、想っていることは個人的な主観たっぷりの考え方なので、他の人達がどう感じているのかなどはちゃんと聞いてみたい。

プロジェクト内での立ち位置などについても、個人的な考えなので、これが自分だけの意見か、他にも同様の課題感を持っている人がいるのかは一度ちゃんと確認しておく必要がありそう。

その上で"やっぱりこの課題があるしなんとかしなくては"となった場合は、「では、何がいま一番解決したい課題なのか」を探っていくところから地道に活動していくのかなと想像している。

年齢的にもそういった立ち回りをしていくことも求められていると思うので、よい"チームづくり"を実践していけるように取り組んでいきたい。

springアプリケーションのORマッパーの比較メモ

Kotlin + spring-bootのアプリケーションでのDBアクセスをどのライブラリを使って行うが良いかという課題があり、

簡単なコードを書いていくつか試してみたのでそれについてのメモ

Java ORマッパーの選定ポイントのスライドを参考にさせていただき、

の3つについて比較を、1:Nの2テーブルのみの簡単なCRUD APIを使って実施してみた

spring-data-jpa

spring-bootのORマッパー=JPAというイメージもあり、ちょっとしたwebアプリを書く際などに今まで利用していたのがこちら。

以前はspring-jdbcでゴリゴリSQLを書いていたことも合ったので「それに比べてDBアクセスが楽になった」という印象がある反面、アノテーションマッピングの仕方、JPQLの使い方など使うにあたって学習が必要なものが多いことや、複雑なクエリを書こうとしてN+1問題などにぶち当たったりと使っていく上での課題も多く、自分が使いこなせるようになるにはハードルが高いなという感じがあった。

感想

  • (利用経験での慣れが大きい気もするが)1:NやN:Nなどのマッピングアノテーションで対応できる(ただし方法がいくつかあり、どういった場面でどれを使うのが良いのかの選択が難しい)
  • ページングの実現も簡単
  • (DDDを使っている場合)集約ルートから、関連エンティティをgetter経由で取得できるのでコード量が少なくできる
  • N+1問題や3つ以上のテーブルのJOIN FETCHができない。意図していないクエリが生成されることもマチマチという課題がつきまとう

エンティティのコード例

1側

@Entity
data class Team(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val teamId: Long? = null,

    val name: String,

    val type: String,

    @Version @NotNull val version: Int = 0

) : Serializable {

    @OneToMany(mappedBy = "teamId", cascade = [CascadeType.ALL])
    var members: MutableList<Member> = mutableListOf()
}

N側

@Entity
data class Member(

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val memberId: Long? = null,

    val firstName: String,

    val lastName: String,

    val teamId: Long,

    @Version @NotNull val version: Int = 0

) : Serializable {
}

spring-data-jdbc

spring-data-jpaと似たような書き方で かつシンプルに使えそうという印象を持ったので試してみたのがこちら。

アノテーションマッピングの仕方がほとんど同じことや、CrudRepositoryが使えるためfindByIdやfindAll,saveなどはそのまま使えるので新しく覚えることも少なくコード量もjpa同様に少なくて済みそうな感じだった。

感想

  • spring-data-jpaと同じような感じで使えるため心理的ハードルが低い(個人的に)
  • マッピングの仕方が違うことやLAZYフェッチが出来ないため、JPAに慣れている場合はそこの注意が必要になりそう
  • LAZYフェッチがないなどJPAに比べてシンプルなためN+1問題などに悩まされることはなくせるor減らせそう
  • (手元では試せていないが)ページングについては対応できていないような記述、記事を見かけたのでページングを手軽に使うことは出来無さそう
  • 情報もまだ少なく、上記のページングの話も含めてまだ、これから機能や安定性が整ってくるという印象を受けた(シンプルなアプリであれば充分だとは思うが)

エンティティのコード例

1側

@Data
data class Team(

    @Id
    val teamId: Long? = null,

    val name: String,

    val type: String,

    @Version @NotNull val version: Int = 0

) : Serializable {
    
    @MappedCollection(idColumn="team_id", keyColumn="team_id")
    var members: MutableList<Member> = mutableListOf()
}

N側

@Data
data class Member(

    @Id
    val memberId: Long? = null,

    val firstName: String,

    val lastName: String,

    val teamId: Long,

    @Version @NotNull val version: Int = 0

) : Serializable {
}

jooq

参考のスライド内では「クエリビルダー型」と分類されていたライブラリの1つ。

spring-data-jpaとかに比べると記述は増えるが、よりSQLに近い書き方ができる一方で、JDBCのように生のSQLを書く必要はないという感じなので、バランスがよくJPAで抱えていた課題を解決しつつ、エンティティの自動生成などを活用することでDBへの変更にも追随しやすい、というメリットがありそうと考えて試してみた。

DDD X CQRS - 更新系と三焦経で異なるORMを併用して上手く行った話などを見る限り、DDDにも活用できそうなことも試してみたいと思った理由の1つ。

感想

  • spring-data-jpaに比べると記述量は多くなるが、クエリで条件や取得したい情報を明確に定義できるのは良いと思った
  • エンティティの自動生成などプラグインを活用することで、開発や運用もだいぶラクにできそうという印象を持てた
  • (自分の学習不足が大きいが)2つ以上のテーブルを結合する場合などの書き方がよく分からなかったし、それ専用のDTOクラスのようなものを用意する必要がありそうに感じた
  • 1:NのテーブルでNの関連をどう定義するばよいのかが分からなかった

エンティティのコード例

1側(関連エンティティの表現はたぶん間違っている)

@Data
data class Team(
    
    val teamId: Long? = null,

    val name: String,

    val type: String,
    
    @NotNull val version: Int = 0

) : Serializable {
    
    var members: MutableList<Member> = mutableListOf()
}

N側

@Data
data class Member(
    
    val memberId: Long? = null,

    val firstName: String,

    val lastName: String,

    val teamId: Long,
    
    @NotNull val version: Int = 0

) : Serializable {
}