Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Red_Hat_Application_Foundationsから学ぶアーキテクチャー入門

 Red_Hat_Application_Foundationsから学ぶアーキテクチャー入門

なんでもかんでも1台のサーバーに入れて巨大なシステムを構築していないでしょうか?
システムが巨大化するとレスポンスタイムの低下や、開発速度の低下等のいくつかの問題が発生するようになります。
Red Hatではアプリケーションを小さく作り複数のサーバーに分割してシステムを構築することを推奨しています。
そうすることで、不必要なレスポンスタイムの低下や開発速度の低下を防ぐことができるようになります。
しかしながら、サーバーを複数台に分割する場合は1台ですべてを作る場合に比べていくつかの注意点が必要になる場合があります。

Red Hat Application FoundationsはJava EEを実装するJBoss EAPやMicroProfileを実装するQuarkusやそのほかのミドルウェア、インテグレーション製品のどれを使っても良いというサブスクリプションになります。
このセッションではRed Hat Application Foundationsに含まれる製品やそのほかのOSSを使用して、どうやってアプリケーションを分割していくのかと、分割する上での注意点について説明します。
Red Hatの製品はすべてがOSSでベースとなるアップストリーム製品(≒github上等でOSSライセンスで公開されているリポジトリ)があります。
Red Hatのサポートが不要な場合はサブスクリプションを購入しなくても使用することができます。
ですので、Red Hatのサブスクリプションを購入したことがない方、購入する予定のない方でも聞くことができます。

すでに巨大なJava EEサーバーで構築されているシステムを抱えている方や、これからシステムを分割していきたい方、1台のサーバーでしか作ったことがない方の知識の助けになると思いますのでぜひご参加ください。

Satoshi Seto

November 27, 2022
Tweet

More Decks by Satoshi Seto

Other Decks in Technology

Transcript

  1. Red Hat Application Foundationsから学ぶ アーキテクチャー入門 レッドハット株式会社 2022.11.27 スペシャリストソリューションアーキテクト 瀬戸 智

    1 JJUG CCC 2022 Fall 16:00~ Track:D #jjug_ccc_D
  2. 2 2022年2月からRed Hat所属 スペシャリストソリューションアーキテクト JBoss EAP、Quarkusなどを担当 日本Javaユーザーグループ幹事 自己紹介:瀬戸智

  3. 本題に入る前にお知らせ 3

  4. 4 ▸ 2023年前半にリリース ▸ 2022年中にベータ版リリース ▸ ベースになるのはWildFly 27 ※すべては予定であり予告なく変更になる可能性があります。 The

    road to JBoss EAP 8 https://developers.redhat.com/articles/2022/06/24/road-jboss-eap-8 https://rheb.hatenablog.com/entry/road-jboss-eap-8 (日本語翻訳) JBoss EAP 8 Coming Soon! (Jakarta EE 10対応)
  5. 5 https://www.wildfly.org/news/2022/09/29/WildFly26-Beta-Released/ https://www.wildfly.org/downloads/ Java SE 11、Java SE 17で実行可能 WildFly 27

    Now Available! (Jakarta EE 10対応)
  6. 6 ▸ MicroProfile 5.0(Jakarta EE 9API使用)から依存ライブラリのパッケージ名がjavaxから jakartaへ変更されていたため対応が保留されていた。 ▸ Jakarta EE

    10のリリースに伴い対応が行われている。 ▸ 次はMicroProfile 6(Jakarta EE 10ベース)対応のもの ▸ 詳しくは以下の記事を。 https://quarkus.io/blog/road-to-quarkus-3/ Quarkus Coming Soon! (MicroProfile 6対応)
  7. 7 参考情報(OpenShift) OpenShiftのサブスクリプション&サポート契約にはQuarkusのサポートが含まれます。

  8. ここから本題 8

  9. 9 E-Wordsより https://e-words.jp/w/%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3.html アーキテクチャーとは

  10. 10 ▸ 銀の弾丸はありません。 ▸ 特定の場合に特に有効というのはあります。 ▸ 今回のセッションでは良い場所、悪い場所両方とも記載するように心がけています。 ・ 悪い場所があるから使わないほうが良いとかではないよ! ▸

    すべてはトータルでのメリット・デメリットで判断してください。 アーキテクチャーの選択について
  11. 11 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  12. モノリスから マイクロサービスへ 12

  13. 13 全部を一台に乗せるモノリスから小さなマイクロサービスへ 拡張や需要スパイクに 備えて過剰気味に確保 されたサーバーリソー ス 最初からあるアプリ群 後乗せしたアプリ群 サーバーと同サイズのMW 業務・機能ごとに

    アプリを分割 ワークロードに応じて 個別スケール アプリは追加される
  14. 14 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  15. Red Hat Application Foundationsとは 15

  16. 16 https://www.redhat.com/en/resources/application-foundations-datasheet EAPとRed Hat Application Foundationsの関係 含まれないもの: • Fuse 6

    / AMQ 6 / Vert.X / PAM / DM • All Managed Application Services API管理 データ変換 サービスオーケストレーション イベントバス データストリーミング シングルサインオン Javaアプリケーションフレーム ワーク インメモリ分散データストア Migration Toolkit for Applications • AMQ Streams • AMQ Broker • Debezium Change Data Capture • Service Registry • Camel 3 (CEQ, CK, CSB) • Fuse 7 • 3scale API Management • Node.js • Red Hat JBoss EAP • Red Hat build of Quarkus • Spring Boot • Red Hat build of OpenJDK • Red Hat JBoss Web Server • Red Hat Data Grid • Red Hat Single Sign On(keyCloak) • Migration Toolkit for Applications
  17. 17 ▸ Application FoundationsにはJBoss EAPが含まれておりJakarta EEのユースケース に完全対応 ▸ Application Foundationsには多数の製品が含まれ、Jakarta

    EEでカバーできない領域を MicroProfileに準拠したQuarkusや他の特化したミドルウェアでカバー可能 ▸ JBoss EAPはJakarta EE仕様に準拠しておりポータビリティがあるのは当然だが、 それ以外のミドルウェアについても100%OSSなので、ロックインの心配はない Application Foundationsを選択する理由
  18. 18 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  19. アプリケーションの分割と トランザクション 19

  20. 20 ▸ コンピューターにおける一処理の単位。 ▸ ここからここまでの処理に成功したか、失敗したか。 ▸ 成功だったらコミット(処理の確定)、失敗だったらロールバック(処理の切り戻し)。 ▸ いわゆるACID特性が保たれている。 ▸

    複数サーバーにまたがってトランザクションを担保したい場合は特別な考慮が必要。 トランザクションとは
  21. アプリケーションの分割 クライアント フロントエンド サーバー バックエンド サーバー(+ DB) この中でトランザクション を担保したい。

  22. AMQ Broker(JMS、ActiveMQ Artemis) イベント駆動型アーキテクチャ 22 ▸ フル機能のメッセージ指向ミドルウェアのブローカー ・ ピュアJavaで高性能のメッセージブローカー ・

    柔軟な永続化方式: 高性能なジャーナル or JDBC ・ 高可用性: シェアードSAN or シェアードナッシング レプリケー ション ・ 柔軟なクラスタリング ▸ 様々なキューイングのオプション、メッセージの永続化、管理 方式 ▸ 複数のプロトコルとクライアント言語をサポート ・ AMQP 1.0, MQTT, STOMP, OpenWire, HornetQ ・ Java JMS, C++, .NET, Python, Javascript, NodeJS Clients Source Artemis
  23. 23 ▸ 複数のサーバー間でトランザクションを担保するための仕組み。 2フェーズコミット(2相コミット)

  24. 24 2フェーズコミット(コミット時) フロント バック1 バック2 複数のサーバーへのデータの書 き込みと、書き込みが正しくでき たのかの確認を行う (フェーズ1) フェーズ1のすべてのサーバーの

    応答を待ってからコミットを行う。 (フェーズ2)
  25. 25 2フェーズコミット(ロールバック時) フロント バック1 バック2 一つでもエラーになった場合は他 のサーバーも含めてすべてロー ルバックを行う。 (フェーズ1)

  26. 26 2フェーズコミット(うまくいかない例) フロント バック1 バック2 コミット時に一つのサーバーでエ ラーになった場合はどうすればい いのか?(フェーズ2) 一つのサーバーからだけ応答が 返ってこない場合にどうすればい

    いのか?(フェーズ1,2)
  27. 27 2フェーズコミット(数が増えた場合) フロント バック1 バック2 今は2台だけど台数が増えてきた 場合、どこまでこの仕組みは耐え れるのか?

  28. 28 ▸ 多数のサーバー間でトランザクションを担保する仕組みがあるが、よく知られたいく つかのケースでうまく動かない。 ▸ それを認識したうえで、どうしてもトランザクションを担保したい場合はAMQ Broker(JMS、ActiveMQ Artemis)を使用することで、実現することができる。 ここまでのまとめ

  29. 29 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  30. 多くのサーバーで 整合性を担保していく 30

  31. 31 ▸ AMQ Broker(JMS、ActiveMQ Artemis)を使用することで複数サーバー間でトランザク ションの担保ができるが、サーバーが多くなると無理が出てくる。 ▸ トランザクションを使わずに、処理が正しく行われていたら結果が正しくなる状態(結 果整合性)を目指すことで、多くのサーバーがある場合でも無理なくデータの整合性を 担保することができる。

    整合性の担保
  32. AMQ Streams(Apache Kafka) イベント駆動型アーキテクチャ 32 Source Apache Kafkaをベースとしたエンタープラ イズデータストリーミングプラットフォー ム

  33. 33 Apache Kafka • 2010年にLinkedInで開発され、2011年に オープンソース化されたストリーミング データのための分散システム • 長期間キューをためておくことを前提と したアーキテクチャ

    • 非常に高いスループットと低レイテンシ ーで大量データを処理 • 容易に水平スケール • クラスタリングにより高い耐障害性 • 大量のコンシューマも処理可能 • データはjsonでやり取りをする
  34. 34 LinkedIn の開発者がApache Kafka を設計したのはなぜか? ▸ リアルタイムログのような高いボリュームのイベントストリームをサポートするための ハイスループットを実現したい ▸ オフラインシステムからの定期的なデータロードを可能とする大容量バックログを取り

    扱いたい ▸ 伝統的なメッセージングのユースケースを取り扱うために低遅延である必要がある Apache Kafka
  35. Kafkaを使用したデータ連携 クライアント フロントエンド サーバー バックエンド サーバー(+ DB) フロントエンドサーバーは kafkaにキューとして貯める バックエンドサーバーはkafka

    を参照して処理をする。
  36. 36 ▸ トランザクション処理を使った整合性は強整合性とも呼ばれ、すべての状態で必ず整 合性が取れている状態が保証される。 ▸ Kafkaを利用した結果整合性は短時間だがデータの整合性が取れていない時間が発生す る。が、多くの場合はこれで十分に期待通りの動作をする。 ▸ 多くのウェブアプリでは一覧画面の表示はリアルタイムではデータベースと同期 がとれていないはずだが、少し昔の情報を参照しても特に何も感じていない。

    トランザクション処理から結果整合性へ
  37. 37 ▸ データを失わないように作ると最低一回の処理は行えるようになるが、二回以上の処 理が行われてしまうことがある。 ▸ 同じデータが何回処理されても同じ結果になるように作る必要がある。(冪等性) ▸ バックエンドサーバーでキューを取り出した後にバリデーションエラーが発生しても ロールバックが行えないため、フロントエンドサーバー側で十分にバリデーションを 行う必要がある。

    ▸ バックエンドサーバーでロールバック用のデータを作ることもできるが、ロール バック処理の自前での実装は大変。 AMQ Streams(Apache Kafka)を使う上での注意
  38. 38 ▸ 多数のサーバー間でトランザクション制御を行うのは難しいので、その場合は結果整 合性を取るようにする。 ▸ その場合に使用できるのがAMQ Streams(Kafka)。 ▸ 使う場合はトランザクションがないことによるいくつかの実装上の注意が出てくる。 ここまでのまとめ

  39. 39 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  40. アプリケーションをこれ以上 大きくしないようにする 40

  41. 41 アプリケーションを分割するのにも時間がかかる 移行に数か月~数年 その間は2重メンテ 最初からあるアプリ群 後乗せしたアプリ群 サーバーと同サイズのMW 業務・機能ごとに アプリを分割 ワークロードに応じて

    個別スケール アプリは追加される 新機能の追加を両方に
  42. 42 https://microprofile.io/ ▸ データベースを監視し、データの変更点をキャプチャする ▸ トランザクションログをベース ▸ スナップショットの取得, フィルタリング機能 など

    ▸ オープンソース, 非常に活発なコミュニティ Debezium
  43. 43 Debeziumによる チェンジデータキャプチャ アーキテクチャ データソースをモニタリングして 行単位でその変更をキャプチャ AMQ Streams Kafkaに取り込まれたデータを参照

  44. Debeziumコネクタ 44 Source • General Availability ◦ MySQL ◦ Postgres

    ◦ MongoDB ◦ SQL Server ◦ DB2 (Linux only) ◦ Oracle (LogMinerを使用) Application Foundationsでサポートしているデータベース ※Upstream版では他のデータベースへのコネクタも提供されています。 https://debezium.io/releases/1.9/
  45. Using Change Data Capture for Stack Modernization: Demo Debeziumで全文検索を追加 既存システムを

    小売店の在庫や売上を 管理するための レガシーアプリケーション データの保持のために使用 データベース更新イベントを キャプチャして公開します • kafka トピックの管理 • メッセージの受信と保存 • コンシューマーがイベントの 読出しをできるようにする 製品データの更新分を、elasticsearch の インデックスに追加します データをインデックス化し、 全文検索の機能を強化します REST APIを通して 製品の検索を実施します 既存システムの検索機能を強化 リアルタイムで情報を集計し、常に最新の情報を検索することが可能に 新規で作った場所は旧アプリとは 別管理とすることができる。
  46. 46 ▸ テーブルを直接インターフェースとして外部に公開することになるので公開後のテー ブルの変更時に影響が出る。 ▸ なんでもかんでも公開すればよいというものではない。 ▸ ただし、データ連携のフォーマットはjson形式で一般的なものなので、 Debeziumから剥がすことは簡単に行える。 ▸

    有効化するときにDBの設定が必要になる場合がある。 Debeziumを使う上での注意
  47. 47 ▸ Debeziumを使うことで既存のアプリケーションに手を加えずに新しいアプリケーショ ンへデータ連携を行える。 ▸ 新旧システムの並行開発をしているときに特に有用。 ▸ ただし、データベースのテーブルレイアウトを外部に参照させてしまうことになるの で注意が必要。 ここまでのまとめ

  48. 48 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  49. 急なアクセス量の変化(オート スケーリング)に対応する 49

  50. 従量課金では最小限のサーバーにしたほうが都合が良い クライアント ロードバランサー サーバー

  51. 51 ▸ 即座にサーバーが起動すると急激なリクエスト数の増加にも対応ができる。 ▸ サーバーの起動に時間がかかる場合、事前にリクエスト数の増加を予測してサーバー を起動させておく必要がある。 サーバーが増える=サーバーが起動する

  52. 52 ▸ 旧来のJava EEサーバーは起動が遅いと言われがちだが、JBoss EAPの起動は早い。 ▸ デフォルトだと数秒~十秒程度で起動する。 ▸ Webサーバーに必要な機能のみに限定すればもっと早い。 JBoss

    EAPの起動は早い
  53. 53 ▸ アプリケーションを小さく作る。 ▸ 読み込むものが少なければそれだけ早くなる。 ▸ アノテーションを使わない、読み込まない設定にする。 ・ 起動時にすべてのクラスを舐める必要が出てくるのでその分遅くなる。 ・

    もともとJavaは遅延クラスロードの機能を備えている。 ▸ 過剰なリソースの確保を起動時に行わない。 ・ DB接続コネクションプールとか。 Java EE(Jakarta EE)サーバーの起動を早くする
  54. 54 ▸ デフォルトで1秒~2秒程度。 ▸ 十秒程度が待てない場合はこちらを使用する。 ▸ QuarkusはJavaでは主流な動的DIではなく、静的DI(コンパイル時DI)を行っているため 起動時にすべてのクラスを舐める必要がない。 Quarkusの起動はもっと早い

  55. 55 https://quarkus.io/ ▸ GraalVMはJavaをネイティブコンパイルする。 ▸ デフォルトで数十ミリ秒。 ▸ メモリ使用量も低減。 Quarkus+GraalVMの起動はもっと早い

  56. 56 ▸ QuarkusはGraalVMでのコンパイルを前提に設計されているため、特別な設定はほぼ不 要。(Windowsでも、Macでも、Linuxでも) ▸ GraalVMをインストールして、pom.xmlにプロパティを追加するだけ。 https://ja.quarkus.io/guides/building-native-image GraalVMでのコンパイルの仕方

  57. 57 ▸ Quarkusはコンパイル時にDIを行うため、コンパイルの時間が多少延びる。 ▸ ただし、アプリケーションが巨大でなければ問題にはならない程度。 ▸ GraalVMはコンパイル時に多大な時間がかかる。 ・ 数分以上。 ▸

    GraalVMにはよく知られたいくつかの制限がある。 https://www.graalvm.org/22.0/reference-manual/native-image/Limitations/ Quarkus、GraalVMを使う上での注意
  58. 58 ▸ 他のサーバーにセッション情報を共有、コピー(セッションレプリケーション)できる ようにアプリケーションを作っておくと負荷分散がやりやすい。 ▸ JBoss EAPはInfinispan(インメモリデータグリッド)を内蔵しており、セッション レプリケーションを単独で行える。 ▸ セッション共有用のサーバーを別で作る場合も(Red

    Hat DataGrid) ▸ そもそもセッションを使わないようにする場合もある。 ・ Quarkusはデフォルトではセッションを使えないようになっている。 (参考)セッションレプリケーション
  59. 59 ▸ オートスケーリングのためにはサーバーの起動は早い方が良い。 ▸ JBoss EAPは一般的なJava EEサーバーよりも起動が早い。 ▸ Quarkusはもっと起動が早いが、コンパイルが多少遅くなる。 ▸

    GraalVMはもっと起動が早いが、コンパイルがかなり遅くなる。 ここまでのまとめ
  60. 60 ▸ モノリスからマイクロサービスへ ▸ Red Hat Application Foundationsとは ▸ アプリケーションの分割とトランザクション

    ▸ 多くのサーバーで整合性を担保していく ▸ アプリケーションをこれ以上大きくしないようにする ▸ 急なアクセス量の変化(オートスケーリング)に対応する ▸ アプリケーションの開発速度を加速する 目次
  61. アプリケーションの開発速度を 加速する 61

  62. 62 ソフトウェア開発データ白書 2018-2019 https://www.ipa.go.jp/ikc/publish/whitepaper_dl.html システム開発の工程にかかる時間 テストの比率が増えている

  63. 63 改良開発時のテスト工数の増加 ▸ 新規開発時はすべての新規開発した機能だけをテストしていればよい。 ▸ 改良開発時は修正したところに加えて既存機能のテストも必要になる。 ・ =回帰テスト(リグレッションテスト)

  64. 64 テストの時間を減らす ▸ 手動で行っているとどうしても時間がかかる ・ テスト作業で手作業が必要な量を減らしていく。

  65. 65 テストの時間を減らす-テスト項目の標準化 ▸ テストケースの作成の省力化をするために、どの画面でも行うテストを共通項目としてくくりだ し、一元管理をする。 ▸ どの工程でどういった確認をするべき項目の整備=テスト観点の整備。

  66. 66 テストの時間を減らす-静的解析 ▸ findbug、pmd等の静的解析ツールを使う。 ▸ 動かすまでもなくソースコードを見ればバグってるのがわかるよねというのを見つけてくれるツ ール。 ・ Stringを==で比較しているとか。 ・

    テスト工数を半分に削減できたプロジェクトもあり。 ▸ フレームワークの特性に合わせてプロジェクト内でよくある不具合を自分たちでルールとして追 加することも可能。 ▸ アプリケーションの移行時に静的解析をして非互換をチェックするツールがRed Hat Application Foundations に含まれるMigration Toolkit for Applications。
  67. 67 テストの時間を減らす-テストの自動化 ▸ JUnit等を使ってテストを自動化する。 ・ JBoss EAP(Java EE/Jakarta EEサーバー)に使えるJUnit用のサポートツールがArquillian (Red

    Hat製のOSS) 。 ・ QuarkusにはJUnit用のサポートツールが内蔵されている。 ▸ Red HatのOpenShiftはKubernetesにCI/CDツール(Tekton、Jenkins)のサポートが追加されてい る。 ▸ テストの自動化にかける工数はそこそこかかるので数回しか使わないものであれば作らないほう が良い。
  68. 68 (補足)テストの自動化はやっておいた方が良い。 ▸ 業務側の修正だけではなく、使用しているライブラリ、ミドルウェア、さらにOSのいたるとこ ろに不具合、特にセキュリティバグが含まれている可能性があり、また、見つかった時に即座に 適用をする必要がある場合がある。 ・ 特にインターネットに公開されているサーバーの場合、外部からのアタックが当然のように される。 ・

    例としてはLog4shell、Spring4shell、Heartbleed等たくさん・・・・ ▸ WAF(Web Application Firewall)等を使うことで危険性を大幅に削減することはできる。 ・ WAFの防護は完全ではないということは認識する必要がある。
  69. 69 テストの時間を減らす-テスト環境構築の自動化 ▸ クラウドのAPIを使用して自動でテスト環境を構築する。 ・ オンプレの場合でもOpenShift(Kubernetes)等の仮想化ツールを入れることでAPIを使って のテスト環境の構築が可能に。 ▸ Ansible(Red Hat製オートメーション製品)でネットワーク、サーバー等の操作のテンプレートを

    作成し、何回でも作り直せるようにする。 ▸ Podman(Red Hat製のDocker互換ソフトウェア)でサーバー構成のテンプレートを作成して Ansibleと組み合わせてより迅速に構築を行う。
  70. 70 ▸ 改良開発時は回帰テストのぶんだけテスト工数がかかるようになる。 ▸ テスト工数を減らすためには手作業を減らす必要がある。 ここまでのまとめ

  71. 71 ▸ 今回紹介しなかったよくある課題(ex. シングルサインオン)のためのソリューション (ex. Red Hat SSO)が他にいくつもあります。 ▸ ぜひメリット・デメリットを比較してよいシステムを作ってください。

    まとめのまとめ
  72. linkedin.com/company/red-hat youtube.com/user/RedHatVideos facebook.com/redhatinc twitter.com/RedHat Red Hat is the world’s leading

    provider of enterprise open source software solutions. Award- winning support, training, and consulting services make Red Hat a trusted adviser to the Fortune 500. Thank you 72