社内SEになりました

社内SEは本当に楽なのか?ユーザー系IT企業とSierとの違いは?これからIT企業への就職や転職を考えている人むけに、ユーザー系IT企業から社内SEに40代で転職した筆者がITエンジニアの仕事内容やプロジェクト管理のノウハウ等をご紹介。

非機能要件(性能:基盤設計(前編))

非機能要件の中の性能の説明の続きです。

要求定義や要件定義が終わると、次は基盤設計です。

基盤設計は主に可用性と性能の要件をベースに設計をしていきます。特に性能要件の基盤設計は難しく、性能要件が厳しいシステムの場合には、かなり高いスキルが必要とされます。

1.基盤設計(同時接続数:初級編)

要件定義で決めた同時接続数をもとに、サーバーの同時接続数の設計をします。

f:id:SystemEngineers:20200704122649p:plain

システムで上限を設定した箇所は、基本的には全て監視の対象となります。

ですが上記のようにあちこちに同時接続数の上限があると監視も大変なので、通常は1箇所だけ厳しい設定にして、他の箇所は緩く設定をします。

f:id:SystemEngineers:20200704131607p:plain

上記は、最大掃除接続数が100人の場合の例です。一人のユーザーがアクセスをすると、最大6つのHTTPリクエストが発生します(①)。

同時に100人が利用するので、ロードバランサーには最大600のHTTPリクエストが発生しますが、ロードバランサーの処理能力には余裕があるので、倍の1,200のHTTPリクエストを受けられるように設定します(②)。

次にWEBサーバーは2台あるので、通常はロードバランサーの半分のHTTPリクエストを処理することになりますが、1台がダウンした場合を想定し、ロードバランサーと同数を設定します(③)。

次はAPサーバーです。一人のユーザーで同時に発生するHTTPリクエストは最大6つですが、APサーバーまで到達するのは通常は1つだけです。ユーザーが画面のボタンを押すと、まずはメインHTMLを取得するためのHTTPリクエストがAPサーバーまで到達して、その後、メインHTMLに記載されている大量のコンテンツ(JPEGPNGなど)を最大6多重でWEBサーバーに取得しにいくためです(静的コンテンツはWEBサーバー折り返し)。

そのため最大利用者が100人の場合、1つのAPサーバーには最大50のHTTPリクエストが到達します。APサーバーが1台ダウンした場合の可用性の要件が80%の縮退運転だった場合、最大80のHTTPリクエストを処理することを想定した設定にします(④)。

APサーバーからDBサーバーへの接続は、全てのHTTPリクエストがDBアクセスを伴うものではありませんので ④>=⑤ となりますが、そこまで厳密に設定する必要はないので、④と同じ値を設定します(⑤)。

DBサーバーには最大でも100の同時アクセスしか発生しませんが、APサーバーから最大80アクセス×2台の設定なので、そちらと整合を取るため160の設定にします。ただDBサーバーへの大量アクセスは、APサーバーでブロックする設計なのでDBサーバー自体の設定は緩くても問題ありません。そのためAPサーバーが1台増えた時を考慮して、設定値を240にします(⑥)。

このように最大同時接続数100人に対して、APサーバーでボトルネックが発生する設計にすることで、監視対象をAPサーバーに絞ることができます。

2.基盤設計(同時接続数:上級編)

ECサイトのように不特定多数のユーザーがアクセスするシステムや大規模システムの場合、さらに考慮が必要な設定があります。

それは「ファイルディスクリプタ」と「ポート番号」です。

「ファイルディスクリプタ」とは、OSがファイルを操作する際に使用するファイルに割り振られる番号です。主にLinuxUnixで用いられる仕組みで、Windowsではファイルハンドルが相当します。

Windowsのファイルハンドルは、相当大きな値なので、この値をチューニングすることは無いと思って良いですが、ファイルディスクリプタの場合には、大規模システムではチューニングが必須です。

ファイルディスクリプタの上限値は、OS上で動くアプリケーションによって変わります。

例えばApacheのpreforkモデルのように、HTTPリクエストごとに子プロセスを作成する場合、OS全体の上限数に影響します(初期値は12,998)。

Apacheのworkerモデルのようにスレッドを使用するアプリケーションの場合には、1プロセスの上限数に影響します(初期値は1,024)。特にこのケースの場合は初期値が小さいので注意が必要です。

もう一つの「ポート番号」も、大規模システムの場合には、ローカルポート番号が枯渇することがあります。

f:id:SystemEngineers:20200704195619p:plain

Linuxのローカルポート番号のデフォルトは、32768〜61000(28,232ポート)、Windowsのローカルポート番号のデフォルトは、49152〜65535(16,383ポート)なので、それ以上の利用が想定される場合には、ローカルポート番号の範囲を拡張する必要があります。

ローカルポート番号拡張の際には、ミドルウェアに割当てるポート番号との重複も考慮する必要があります。 

3.基盤設計(ヒープサイズ)

JAVAの場合ですが、同時接続数と同じくらい重要なのが、ヒープサイズです。利用者が多いシステムの場合、ヒープサイズも拡張しておかないと、同時接続が重なった場合にOutOfMemoryが発生します。

ヒープサイズは初期と最大の2つの設定がありますが、通常は初期=最大で設定します。初期を小さくすると、ヒープを拡張する際にオーバーヘッドが発生するためです。実際のところは初期=最大で設定をしても、OSレベルでは最大サイズまでメモリーを割当てないことが多いのですが。

APサーバー上で他のソフトウェアが動いていない場合、ヒープサイズは、要件定義で決めたメモリー使用率の最大近くまで割当てます。例えばサーバーのメモリーが2GBで、メモリー使用量の上限が60%だった場合、ヒープサイズは初期=最大=1GBで設定します。そうするとヒープで50%、残りのOS等で10%弱使用するので、使用率を60%ギリギリで有効利用することができます。それほどヒープを使わなくても、無駄にメモリーを余らせる必要もないので、目標上限のギリギリになるように設定をするのがコツです。

4.基盤設計(タイムアウト:初級編)

タイムアウトの設定も重要です。

ただタイムアウトの設定はいたるところにあり、初級レベルから超上級レベルまで様々です。

その中でも必ず設定を意識しなければいけないのが、APサーバーとロードバランサーのセッションタイムアウトです。

HTTPやHTTPSは、ステートレス(サーバーがクライアントの状態を保持しない)なプロトコルのため、何もしないとAPサーバーは1回目のHTTPリクエストと2回目のHTTPリクエストが同一ユーザーのものであることを認識できません。

f:id:SystemEngineers:20200716151602p:plain

そのため、APサーバーが初回のHTTPリクエストに対してセッションIDというものを振り、クライアント(ブラウザー)に返送します。クライアントはそのセッションIDをCookie等に保持し、2回目以降のHTTPリクエストでは、そのセッションIDを利用してAPサーバーにアクセスします。それによってAPサーバーは、ユーザーのログイン状態を維持することができます。これをセッション管理と呼びます。

f:id:SystemEngineers:20200717101305p:plain

このセッションを維持する時間をAPサーバーに設定します。社内システムであれば、通常、30分または60分で設定します。最後にAPサーバーがHTTPリクエストを受けてから、この設定したタイムアウトの時間が過ぎるまで次のHTTPリクエストが発生しないと、セッションが破棄され、「session timeout」となります。

ユーザー部門に説明する際には、「ボタンを押してから次にボタンを押すまでの時間」といった説明をしないと誤解が生じます。例えば稟議のシステムで、稟議の文書を入力しますが、テキストフィールドに入力するだけではHTTPリクエストが発生しないため、セッションタイムアウトも更新されません。せっかく頑張って2時間かけて文書を入力しても、申請ボタンを押すと「session timeout」となり入力内容が破棄される、という悲劇になるので注意が必要です。

f:id:SystemEngineers:20200716152614p:plain

このセッション管理のタイムアウト値は、長ければ長いほど良いというわけではありません。セキュリティー上のリスクにもなりますし、アクセス数が多いとメモリーJAVAヒープ)を圧迫することにもなります。またセッションに格納する情報はアプリケーションで作り込むため、大量の情報をセッションに格納すると、やはりメモリー枯渇の原因になります。

そのためメモリーを効率的に利用するために、適切な情報をセッションに格納し、適切な時間でセッションを破棄する設定が必要となります。

またロードバランサーを利用している場合には、このAPサーバーのセッションタイムアウトに合わせて、セッション維持のタイムアウトの設定も必要となります。

ロードバランサーは、複数のAPサーバーのうち負荷の少ないサーバーにHTTPリクエストを振り分けます。その際、2回目のHTTPリクエストを1回目と異なるAPサーバーに振り分けてしまうと、APサーバーのセッション管理が有効に機能しなくなってしまいます。(APサーバーの中には、APサーバー間でセッション情報を共有する製品もあります)

f:id:SystemEngineers:20200717101613p:plain

そのためロードバランサーにはセッション維持(persistence)という機能があり、一定時間内であれば同一サーバーに振り分けをしてくれます。

f:id:SystemEngineers:20200717103513p:plain

このロードバランサーのセッション維持にもタイムアウトの設定があり、APサーバーのセッションタイムアウトよりも短いと、システム全体として不整合な状態になります。

またこのセッション維持のタイムアウトも、長ければ長いほど良いというわけではありません。セッション維持方式には、上図の⑥でかめ吉さんを特定する方法に種類があり、「送信元IP」で特定する方式や「クッキー」で特定する方式などがあります。

このセッション維持方式が「送信元IP」で、セッション維持タイムアウトを例えば24時間で設定した場合、問題が発生します。

本番運用中に複数あるAPサーバーが1台ダウンした場合、ロードバランサーは他のAPサーバーにHTTPリクエストを振り分けます。

その後、ダウンしたAPサーバーが復旧することになりますが、いつまでも他のAPサーバーに振り分けたセッション維持が残ってしまうため、せっかく復旧したAPサーバーにほとんどHTTPリクエストが振り分けられない状態となってしまいます。

復旧したAPサーバーに振り分けられるのは、障害発生中に一度も他のAPサーバーにアクセスしなかったPCや、最後にアクセスしてから24時間アクセスが無くセッション維持が破棄されたPCだけとなります。

【振り返り】

今回は性能の基盤設計の説明でした。次回は性能の基盤設計の続き(後編)と性能負荷テストの説明をしていきたいと思います。

①可用性
②性能
③拡張性
④運用保守
⑤移行
⑥セキュリティ
⑦ユーザービリティ/アクセシビリティ
⑧システム環境