2019年3月 4日

黒帯

ヤフーにおけるJava事情を軽くご紹介します

  • このエントリーをはてなブックマークに追加
黒帯WEEKの2日目の記事です。カテゴリの一覧はこちら

はじめに

こんにちは。第8代黒帯〜プログラミング言語(Java)〜 の森下と申します。

ヤフーでは、最近はJavaで書かれたさまざまなOSSの利用や貢献がされていたり、サービス開発でもJavaが使われることが増えてきているなど、社内でのJava利用が拡大してきています。

その背景には、ヤフーにおける標準言語の一つとしてJavaが位置付けられていることや、システムが大規模になるにつれて静的型付けやコンパイルなどできっちり作れるという利点が活きてくる点、また社内で利用できるPaaS環境(Pivotal Cloud Foundry)でもSpring Bootベースのアプリケーションがサポートされていて親和性があるといったことからだと思います。

本記事では、ヤフーでのサービス開発においてサーバーサイドの開発にJavaを利用する場合の作業環境や、どんなフレームワークが使われているかなどの概要をご紹介したいと思います。Javaのスキルを持つエンジニアの皆様にヤフーに対する興味を持っていただければ幸いです。

開発環境

以下、ヤフー社内でJava言語による開発作業を行う際の利用ツールなどについてご紹介します。

統合開発環境(IDE)

ヤフーにはコマンドラインやエディターをがっつりと使いこなす猛者も多いですが、さすがにJavaを使った開発では各種入力支援やコンパイルエラーなどの指摘がほしいということもあって、IDEを基本的に利用しています。

利用するIDEの指定が特にあるわけではありませんが、IntelliJ IDEAのUltimate版のライセンスを会社で購入しているため、ヤフー社内で利用できます。機能が豊富で動作も軽く、各種フレームワークのサポートもしっかりしているため、IntelliJ IDEAを利用する人は社内で増えてきていると思います。

ビルドツール

Apache MavenおよびGradleを基本的に利用しています。どちらかに限定したり推奨したりする動きは特になく、どちらを利用するかは各サービスやリポジトリ単位などで開発者が選択しています。

CI/CD

ヤフーではScrewdriver.cdConcourseというCI/CDプラットフォームが社内で運用されており、各サービスの開発者はこれらを使って開発や各環境へのデプロイを行っています。

Javaで書かれたソフトウエアをこれらのCI/CDプラットフォーム上で扱う際は、OpenJDKおよびmavenやgradleなどのツールを組み込んだビルド用コンテナ上で実行することで、コンパイル・テスト・パッケージングなどを行い、デプロイ先に応じたツールで成果物をデプロイしています。

フレームワーク

以下、ヤフー社内でのJavaによるサーバーサイドアプリケーション開発時に利用されている各種フレームワークについてご紹介します。

Spring Boot

新しくサーバーサイドアプリケーションを作成する場合には、基本的にSpring Bootアプリケーションの形態(単独起動できるjarファイル)とすることが多いです。JavaEEアプリケーションの形態(warファイルなど)となっているものもありますが、それらは過去の経緯によるものが多く、またそういったものであっても可能な限りSpring Bootに移行しているケースもあります。

これは、Tomcatなどのアプリケーションサーバーを別途準備しコンフィグレーションやデプロイをする必要があるJavaEE形式のアプリケーションよりも、アプリケーションのjarファイルとJavaランタイムがあれば動かせるSpring Boot形式アプリケーションのほうがシンプルでどこでも動かせるという利点があるからだと思います。

以下、よく使われるSpring系の機能やフレームワークの一部をさらに紹介します。できるだけOSSをそのまま活用していますが、ヤフー社内で利用されているプラットフォームに適合させるための実装を有志で一部開発しています。

Spring Web MVC

Spring Web MVCSpring Frameworkに含まれる機能で、アノテーションベースでURLとJavaクラスおよびメソッドを対応付けてHTTPリクエストを処理できるフレームワークです。

同期コールされるバックエンドWebAPIなどはSpring Webを使ってRestfulAPIとして実装されているケースが多いと思います。なお、ウェブのフロントエンドアプリケーションでJavaを利用している例は少ないと思います。しっかりとしたウェブのUIを作成する場合はJavaScriptをがっつりと使うことになり、そうなるとサーバー側もJavaScriptで書けるNode.jsを使いたくなることも多いと思います。

ちなみにSpring WebFluxもSpring Framework5系/Spring Boot2系以降で利用できますが、利用されている実例は自分の周りでは見ていません。これはWebAPIを作成するためというよりも、Reactive Streamを使って無限ストリームをバックプレッシャー制御つきで返したいようなケースで活用するものなので、適用例自体が少なそうなのと、アプリケーションコードでも気をつけるべきこと(ブロックする処理を混ぜない)があって利用のハードルが若干高いためと思われます。

Spring Security x Athenz

Spring Securityは、さまざまな方式の認証認可の仕組みやセキュリティ関連のHTTPヘッダを取り扱うなどウェブアプリケーションのセキュリティに関する機能を提供してくれるフレームワークです。

ヤフーでは、社内のWebAPIなどのRBACの仕組みとしてAthenzを利用しており、これをSpring Bootベースのアプリケーションに組み込むために、Spring Securityと組み合わせて利用するライブラリを有志で開発・サポートしており、利用できるようにしています。

Spring Cloud Stream x Apache Pulsar

Spring Cloud Streamは、メッセージブローカーの種類を問わず同じアプリケーションコードで非同期メッセージの送受信を行うためのフレームワークです。標準ではRabbitMQやKafkaと接続するためのBinderというライブラリが提供されています。

ヤフー社内では、Apache Pulsarが全社向けのメッセージブローカーとして提供・運営されており、サービス開発者はこれを自分の担当システムに組み込むことができますが、Apache Pulsar向けのBinder実装は標準では提供されていないため、Apache Pulsar向けのBinder実装を有志で開発・サポートしており、利用できるようにしています。

Spring Cloud系、Micrometerなど

最近では、システムをMicroservicesアーキテクチャ的に作ることが多くなってきています。そうしているのは、サービス改善を頻度高く行ったり、負荷の高い機能を必要なだけスケールできるようにしたり、PaaS環境などで稼働させやすかったりといろいろな理由がありますが、その結果として複数のアプリケーションプロセスが連携しあってサービス全体を構成する複雑な形となるため、連携しやすくしたり状況を可視化して問題発生時に対応できるようにするなどの非機能要件が増えてきています。

この非機能要件をサポートする仕組みとして、Spring Cloud系の仕組み(サービスディスカバリやサーキットブレーカーなど)が提供されていますが、このあたりの仕組みはヤフーではまだ利用はそれほど進んでいません。特にこういった非機能要件は最近ではアプリケーションに組み込まずサイドカーとして組み込むと言った流れもあり、これだと言えるようなデザインが社内でも確立していません。逆に言えば取り組める余地が大いに残っている領域であるともいえます。

なお、アプリケーションが分割されてシステム全体が複雑化する傾向は確実にあるため、その状況での問題発生の事前検知や原因究明等のためにモニタリングやトレーシングの取り組みは進み始めていて、各種メトリクスの取得にはSpring Bootの2系から標準で組み込まれるようになったMicrometer という仕組みをつかったり、分散トレーシングの仕組みとしてSpring Cloud Sleuthを使うなどの事例がだんだんと出てきています。

テストフレームワーク

ヤフーでは、継続的にサービスを改善し続けながら品質を保つために、自動テストをCI/CDプラットフォーム上で常に動かすようにしており、Javaで開発されたアプリケーションも以下のようなテストフレームワークを利用しています。どちらもmavenやgradleからそのままテスト実行できますし、両者が同じリポジトリにあっても問題ないため併用している場合もあります。

JUnit

Javaにおける標準的なテストフレームワークとして、JUnitはやはり多く利用されています。モック化の仕組みが必要な場合にはJMockやMockitなどを併用します。特別な準備などの必要もなくすぐに使えるのは利点ですが、Javaの文法そのままでテストケースを記述するのは若干しんどいところもあり、後述のSpockを好む開発者もいます。

ちなみに、JUnit5が最新バージョンではありますが、JUnit4の頃に書かれた多くのテストケースの蓄積があることから、まだまだJUnit4の利用が多いと思います。

Spock

JVM言語の一つであるGroovyをベースとしたテスト向けDSL/フレームワークがSpockです。モックのふるまいの定義やAssertの仕方、繰り返しやそのためのテストデータの記述などがJUnitよりも柔軟で書きやすくなっているため、テストをしっかり書こうとするとこちらを好んで選択する開発者もいます。テスト時にGroovyを動かすためのdependencyやpluginの設定などを入れる必要があったり、GroovyおよびSpock独自の記法を学ぶと言ったイニシャルコストはかかりますが、恩恵は十分に受けられると思います。

社内サポート事情

ヤフーでは、Java言語サポートチームというものがあり、サービスの垣根をこえて有志が集まって、社内の各方面に対するJava利用に関するサポート活動を行っています。以下のような対応を行っています。

  • サービスの開発現場からの相談に対応
  • ヤフー社内のさまざまなプラットフォームとJavaを組み合わせた際の課題解決に協力
  • AthenzやPulsarなどとSpringを組み合わせるためのライブラリ開発
  • 教育研修のカリキュラム作成サポート、レビュー

ヤフーでは過去PHPの利用が多かったという背景もありJava経験者が比較的少なく、Javaの利用が拡大していく中でサポートチームへの要望はだんだんと増えてきています。

サポートメンバー全員が各担当サービスでの主業務を持った上での活動なので、部活動的な雰囲気も若干ありますが、広い範囲に関わることができるためさまざまな事例を知ることができ、自身のプレゼンス向上などにもつながることから協力者も徐々に増えてきています。

最後に

ヤフーのサービス開発でJavaを使う場合に、現在使われている各種ツールやフレームワークなどを大まかにご紹介させていただきました。Javaに関するもろもろの雰囲気が少しでも伝われば幸いです。

個々のサーバーサイドアプリケーションのコードを書いて動かすまでの、言語からフレームワークと言った各要素については形が決まってきている一方で、もう一歩引いた視点で見た全体アーキテクチャ、特にMicroservices的な構成にシフトするにあたってシステムをうまく動かしていくための非機能要件に関わる部分はまだまだ考えるべきところや進化の余地があるというのが現状です。

サービス開発の現場からそういった領域の良い事例をつくったり、またヤフー社内で有志で開発されているような実装に関わったり、またそれらをOSS化したりコミュニティーのイベントで登壇して発表するなど、Javaエンジニアにとってチャレンジできる場がヤフーにはこれからもいろいろとあると思います。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加