将来のOpenSIPS設計

まえがき

OpenSIPSは、シグナリングSIPスイッチです。 本当に多くのSIPコールを処理したい場合、おそらくOpenSIPSを通過することはないでしょう。
このシステムは実際に「成熟」しており、戦闘でテストされ、時間の経過とともに多くの有用な(そしてそうではない)モジュールで大きくなりすぎています。

同時に、2001年に設計されたアーキテクチャが現代の要件を満たしていないことは明らかです。
そのため、OpenSIPS開発者は、バージョン2.0は「ゼロから」維持されると述べました。

以下は、 OpenSIPS 2.0設計ドキュメントの翻訳です。 habrasocietyはこれについてどう思うかと思います。

開発者に伝えようとする重要なコメント。

新しいアーキテクチャが必要な理由

現在のOpenSIPSアーキテクチャ(バージョン2.0より前)は、7年以上前の概念に基づいています。 当時、要件は単純で(単純なステートレスSIPプロキシ、UDPのみ)、これらの要件に従って決定が行われました。 しかし、SIPと機能(TCP / TLS、スクリプト操作、ダイアログのサポート、外部システムとの統合など)の両方でのすべての追加により、既存のアーキテクチャは要件と実際のユースケースを満たせなくなりました。

注意! 内部には、写真付きの大きく構造化されたテキストがあります。


新しいアーキテクチャによって解決される問題:

新しいアーキテクチャの概要

新しいアーキテクチャは、現在のアーキテクチャの問題と成功したソリューションを考慮して開発され、SIPとOpenSIPSの開発の方向性も考慮します。
トップレベルでは、OpenSIPSは2つの完全に独立した部分で構成されます。

複数のルーティングサーバーが同じコアに接続して異なる機能を実装したり、単にシステム全体の容量を増やしたりできると想定されています。

SIPコア

カーネルは、SIPに関連する機能を提供する低レベルのコンポーネントです。 これらは自動的に実行でき、複雑な構成を必要としません。 コアは、トランスポートレイヤー、パケット分析、トランザクション、およびダイアログ、NATアクセス、SIP登録、オンラインステータス(プレゼンテーション)の自動サポート、RFCで明確に定義され、高レベルのサブシステムからの介入を必要としない機能を担当しますルーティング。

コアはいくつかの水平レベルに分割され、それぞれが特定の機能を実行します。

画像

コア構造

SIPメッセージは下位レベルL 0に到着します。 各レベルはメッセージを処理し、次のレベルに転送するか、それより低いレベルに戻します。 戻りが発生した場合、これは、メッセージ処理がこのレベルで終了したことを示します(たとえば、これはKeepAliveメッセージまたは再送パケットへの自動応答の仕組みです)。 メッセージがルーティングサーバーとの対話を提供するレイヤーに到達すると、メッセージは(各レベルで行われたすべての変更と共に)ルーティングサーバーに送信され、ルーティングサーバーはメッセージをさらに処理し続けます。 次に、メッセージは、トランスポートレベル(L 0 )に到達し、ネットワークに送信されるまで、レベルからレベルへと上から下に進むパスに沿って戻ります。

カーネルには2つのメッセージフローがあります。

両方のストリームで、各レベルは異なるアクションを実行できます(たとえば、SIPアナライザーレベルは、着信ストリームからのメッセージを解析し、それらを収集して、発信ストリームに配置します)。

SIPメッセージは、ネットワークからL 0 (トランスポート層)を使用して読み取られ、上位層に送信されます。 各レイヤーは適切なアクションを実行します。たとえば、SIPアナライザーレベルは解析された形式のデータをメッセージに追加し、トランザクションレベルはトランザクション識別子を追加し、ダイアログレベルはダイアログ識別子を追加します。 タスクの完了後、レベルは次のことができます:(a)処理のためにメッセージを上位レベルに転送する(現在のレベルが処理を完了できない場合)、または(b)メッセージの処理を決定し、送信のために送信ストリームにメッセージを転送する(この場合) 、それより上のレベルはすべてスキップされます)。

このようなアルゴリズムは、各レベルで最も効率的なメッセージ処理を提供します。 下位レベルを使用してメッセージを自動的に処理できる場合、すべてのレベルを介してすべてのメッセージをルーティングサブシステムに送信する必要はありません。 たとえば、キープアライブメッセージへの応答は、カーネルによってL4レベルで自動的に処理できます(パススルーNAT)。 もう1つの例は、ルーティングサブシステムが初期要求の受信と処理のみに関心がある場合です。 この場合、後続のリクエストはダイアログレベルを使用して自動的に処理およびルーティングされ、チェーンのさらに下に転送する必要はありません。

階層に加えて、Coreはいくつかのデータベースバックエンドも実装しています。 これらは、カーネルの各レベルがメモリに保存する内部データ(ダイアログ、オンラインステータス、登録、NATを通過するための情報)の再起動間で保存するために使用されます。

コア内部では、レベルを重要度で分類できます。

カーネルには、データベースのメインレベルとバックエンドのパラメーターを含む独自の構成ファイルがあります:どのネットワークインターフェイスでリッスンするか、トランザクションパラメーター、ダイアログパラメーターなど。

カーネルは、ノンブロッキングI / Oをサポートする非同期リアクターとして実装されます。 マルチコアプロセッサを搭載したマシンでリソースを効果的に使用するために、カーネルは(CPUコアの数に応じて)いくつかのスレッドを使用します。

ルーティングエンジン


ルーティングサブシステムはルーティングを提供します。これに対して、構成スクリプトはOpenSIPSの現在のバージョンを担当し、現在存在するほとんどのモジュールの機能を提供します。

ルーティングサブシステムは、個別のコンポーネントとしてカーネル上で実行されます。 前述のように、複数のルーティングサブシステムを1つのコアに接続して、さまざまなサービスを実装したり、複数の物理マシンの負荷分散によるシステムのスループットを向上させたりできます。

新しい設計では、カーネルをルーティングサブシステムに接続するために2つのアプローチを使用できます。

なぜ2つのアプローチを使用するのですか? これら2つのオプションは排他的ではありませんが、相互に補完します-内部ルーティングサーバーはパフォーマンスと管理性の点でより効率的です(直接Cレベルでカーネルと緊密に統合されるため)、外部ルーティングサブシステムははるかに普遍的でシンプルなソリューションです(制御がはるかに簡単な高レベル言語アプリケーション)。

内部ルーティングモジュール

ルーティングモジュールは追加のレベルのセットであり、ライブラリの形式で提示され、カーネルに関連付けられて単一のアプリケーションを形成します。 ルーティングモジュールには以下が含まれます。

画像

内部ルーティングサブシステム

スクリプトインタープリターは、高レベル言語(埋め込みPerlなど)にブロックを直接挿入する機能を備えた既存の特殊言語に基づいています。 パフォーマンスへの影響の程度に応じて、特殊なスクリプトを完全に高級言語に置き換えることができます(たとえば、カーネル関数またはCモジュールが呼び出されるPerlでルーティングモジュールのロジック全体を記述します)。

新しいアーキテクチャでは、インタープリターが非常に高速であり、単純なロジックを備えた構成に最適であり、高負荷にうまく対応できるため、既存のネイティブスクリプトを使用することが可能です。

このソリューションは、高レベル言語の機能を使用して実装できる複雑なルーティングロジックが必要なシナリオの実装を大幅に簡素化するため、高レベル言語でのスクリプトの埋め込みも有用に見えます。 この機能により、複雑なスクリプトを記述する複雑さが軽減されるだけでなく、特殊な組み込みスクリプト言語を習得する必要がなくなります。 ただし、この場合、高レベルの言語インタープリターはより重くて遅いため、パフォーマンスの低下が発生します。 一方、高水準言語を使用すると、水平スケーリングが実現します。 すべてのルーティングサブシステム(高レベル言語およびストレージテクノロジの機能を使用)がネットワークに接続され、いくつかのOpenSIPSコアを使用するグローバルルーティングサーバーのように全体として動作する(複数のサーバー上の)OpenSIPSクラスターを想像してください。

定義済みの機能(ダイヤルプラン、LCR、QoS、B2BUAなど)を提供するルーティングサブシステムのモジュールは、その形式に関係なく、スクリプトから使用できます。

操作中にスクリプトをリロードすることが可能です。

外部ルーティングサブシステム

組み込みの外部ルーティングサブシステム(またはアプリケーション)と同様に、メッセージが2方向(下から上、上から下)に通過する一連のレベルとして実装されます。 これらの層は、特定のSIPサービスのルーティングロジックを実装する層で終わります。 最後の層は、古いアーキテクチャで使用されていたスクリプトに相当します。

一部のレベルはアクティブです-これは、送信中にメッセージを変更し、場合によっては、メッセージの中継を停止し、処理を終了してメッセージを戻すことを決定することを意味します。 これは、メッセージの内容を分析するか、前のルーティングレベルからの指示に基づいて行われます。 他のいくつかのレベルは受動的です。 これは、特定の機能(LCRやコール制御など)を実装するクラスと機能のみを提供しますが、レベルアップ間のエンドツーエンドのメッセージングには使用されないことを意味します。 これらはルーティングロジックから明示的に呼び出され、メッセージを変更します。

画像

アプリケーションとしてのルーティングサブシステム

アプリケーションは特定のコア(または必要に応じて複数のコア)に登録し、その機能をコアに報告します。 機能には、このルーティングサブシステムと制限が関係するメッセージが含まれます。 これにより、カーネルはこのアプリケーションに送信するメッセージと量をフィルタリングできます。 さらに、アプリケーションは、カーネルがメッセージをこのアプリケーションにルーティングする必要があると判断した場合、カーネルのオプションレベルの一部を動的に有効/無効にするようにカーネルに要求できます。 これにより、特定のアプリケーションがカーネルに、特定のアプリケーションに送信されるすべてのメッセージについて、NATの通過レベルを無効にするように指示できる、柔軟な構成を作成できます。 その結果、カーネルはこのアプリケーションにメッセージを送信するときに、NATを介したパスレベルをスキップします。 これは、アプリケーションがNATを単独で通過することに対処することを意味します。 また、アプリケーションがキープアライブメッセージを受信することを意味します。 このレベルを無効にしていない他のアプリケーションは、キープアライブメッセージを表示せず、NATを通過するレベルが使用されるため、NATを通過する問題を解決しません。 これにより、非常に柔軟な構成が可能になります。これにより、Core構成を変更したりCoreを再起動したりすることなく、オプションのCoreレベルを実行時にオンまたはオフにできます。

画像

複数のシングルコアアプリケーション

アプリケーション全体を、Pythonなどの高級言語で作成できます。 OpenSIPSの実装は、ユーザーが高レベルのルーティングロジックを作成できるようにするために必要なすべての機能を提供します。 これは、アプリケーション図の最後のレベルに対応します。 既存のスクリプトのようになりますが、アプリケーションの他の部分と同じ言語(この場合はPython)でのみ記述されます。 もちろん、アプリケーションは、Java、Ruby、Perlなどの他の言語で実装できます。

私たちそれぞれOpenSIPSプロジェクトを支援できます

ご清聴ありがとうございました。

Source: https://habr.com/ru/post/J106719/


All Articles