先史時代
過去3年間、Novotelecom内部自動化部門で働いていました。 IT関連部門の内部プロセスを自動化するシステムの主な開発は、キャンペーン自体の活発な成長とともに2008年に始まりました。 当時、リーダーシップは質の高い意思決定を行うための目標を設定していませんでした。主な目標は市場を征服することでした。 IA部門が取り組んでいる主なシステムは、人事計画要素とヘルプシステムも含む内部CRMシステムです。 長い間、システムは自作のフレームワークで記述されていましたが、Yiiに会って会社のWebサイトを実装した後、システムをこのフレームワークに移行することが決定されました。 この特定のフレームワークが選ばれた理由についての議論は、私の記事の範囲を超えています。
Yiiへの最初の転送中、私たちのチームはアーキテクチャを変更せずに残すことにしました。 開発のペースは成長しており、作業を組織化する内部プロセスは、アーキテクチャ面を優先するレベルにまだありませんでした。 したがって、1年後、現在のシステムの機能の約3分の1がYiiに移行されました。 開発のペースを確実に高めました。 このフレームワークは多くの典型的な問題を解決するのに役立ちましたが、以前はその解決に多くの時間がかかっていました。 しかし、ますます煩わしくなり始めた瞬間がありました。 それでも、すべてがリターンゾーンに入るまで、アーキテクチャの問題を解決する必要がありました。 1つのモノリシックアプリケーションではなくサービスに切り替える決定を下した決定的な要因は、キャンペーンでのシステム間アーキテクトの役割の割り当てであり、すべての内部プロセスとアーキテクチャの側面を整理し始めました。 この役割は、Javaでソフトウェアを作成する関連グループのいずれかのアーキテクトに割り当てられました。 soaパラダイムは最初に彼らのグループで選択され、過去3-5年にわたってこのプラクティスはこのアプローチのすべての長所と短所を示してきました。
環境について少し
- OS Debian 6
- nginx Webサーバー
- PHP 5.3
- フレームワークyii
- phingビルドおよび展開システム
- サービスはdebパッケージとしてインストールされます
- ヘシアン関連サービス統合プロトコル
制限事項
最初は、ビジネスロジックのレイヤー(顧客アプリケーション、顧客カードなど)を組み合わせたモジュールを使用して開発アプローチが選択されました。 サービスに切り替えると、アプリケーションの構造を整理する方法、デプロイする方法、SVNに保存する方法の問題が生じました。
このような問題を解決するには、いくつかのアプローチがあります。 彼らのうちの1人は2Gisからの彼らの記事で提案されました。 同様のソリューションを使用して、アプリケーションの構造Yiinitializrを整理することもできます。 2amigosからの解決策は非常に優れていますが、すべてを取り込んで転送するだけではすでにかなり問題がありました。 したがって、既存の例とYiiで得た経験に基づいて自転車を作成する必要がありました
SOAについて少し
最初の段階では、次のサービスが割り当てられました

図で2つの内部層が選択されています:コアとポータル
コア -すべてのサービス、およびyii、behat、ratcherなどのライブラリ、および関連サービスと統合するためのコンポーネントのセットの正しい操作に必要な共通コンポーネントのレイヤー。
ポータル -ユーザーインターフェイス。
さらに、この図は、内部および外部サービスと対話プロトコルの層を示しています
実装の詳細
各アプリケーションは、それがサービスであろうとユーザーインターフェースであろうと、 webとconsoleの 2つのエントリポイントのいずれかを持っています。 たとえば、Webサービスの場合、エントリポイントはrest apiです。
configストレージは、機能を考慮して、yiinitializrとの類推によって行われました。 したがって、各アプリケーションには次の構成構造があります。
- service.web.php-Webパーツの構成
- service.console.php-コンソール部分の構成
- service.test.php-自動テストを実行するための構成
- service.base.php-以前のものすべての一般的な設定。 それぞれの内部で接続されています。
- env / local.php-環境(dev、test、またはproduction)に応じたパラメーターがレンダリングされる構成
- セクション/ routes.php-ルーティングルール
共通パッケージのApplicationDispatcherコンポーネントは、次の機能を実装するアプリケーションの初期化を担当します:構成の準備、内部エイリアスの書き込み、ルートの書き込み、環境に応じたディレクトリへのパスを取得するためのメソッド、たとえば一時ファイルまたはログを含むフォルダーへの提供
コンポーネントはindex.phpで接続され、次のように呼び出されます
ソースパッケージindex.phpをダウンロード
// if(!file_exists('/usr/share/ntk-rm-common/protected/components/ApplicationDispatcher.php')) { throw new Exception(' ntk-rm-common'); } require_once('/usr/share/ntk-rm-common/protected/components/ApplicationDispatcher.php'); // $dispatcher = ApplicationDispatcher::getInstance(); // : $dispatcher->setEnvironment(ApplicationDispatcher::ENV_PRODUCTION); // $dispatcher->setApplicationType(ApplicationDispatcher::APP_TYPE_WEB); // $dispatcher->create('crm')->run();
メソッドのソースコードを作成する
/** * * @param $service - * @return mixed * @throws Exception */ public function create($service) { $this->service = $service; if(empty($this->app_type)) { throw new Exception(' : web console'); } // require_once $this->getBasePath('common') . '/helpers/global.php'; $config = $this->prepareConfig(); // $config['runtimePath'] = $this->getRuntimePath($service); // - protected $config['basePath'] = $this->getBasePath($service); $this->setAliases(); if ($this->app_type == self::APP_TYPE_WEB) { $this->app = Yii::createWebApplication($config); // $this->setRoutes(); // assets $basePath = $this->getHtdocsPath($this->service) . '/assets/'; $this->app->getAssetManager()->setBasePath($basePath); } else { defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); $this->app = Yii::createConsoleApplication($config); } return $this->app; }
構成ファイルを準備するためのロジックは、Yii-BoilerplateまたはYiinitializrで使用されるロジックと大差ありません
/** * . * @return array|mixed * @throws Exception - */ private function prepareConfig() { if (!$this->isExistsServiceConfig()) { throw new Exception(' «' . $this->getServiceConfigName() . '» . .'); } // $service_configs = array( '/' . $this->service . '.' . $this->app_type . '.php', '/env/local.php' ); $config = $this->mergeConfigs(array(), $service_configs , $this->getConfigPath(($this->service))); // $common_configs = array( '/env/local.php', '/common.base.php', $this->app_type == self::APP_TYPE_WEB ? '/common.web.php' : '/common.console.php', ); $config = $this->mergeConfigs($config, $common_configs, $this->getConfigPath('common')); // backend $backend_configs = array( '/php-backend.base.php', '/env/local.php', ); $config = $this->mergeConfigs($config, $backend_configs, $this->getConfigPath('php-backend')); return $config; }
パッケージ構造
前述のように、実稼働環境でのサービスのインストールはdebパッケージを通じて行われます。 deb-wayを完全にサポートするために、debパッケージをインストールするとき、アプリケーションは次のディレクトリに散在しています。
- / usr / share / <service_name> / protected /-サービスソース
- / usr / share / doc / <service_name> /-config local.default.phpの例
- / usr / bin / <service_name>-ロボットを起動するための実行可能ファイル
- / var / www / <service_name> / htdocs /-北のウェブのディレクトリ
- / var / tmp / <service_name> /-一時ファイルを保存するディレクトリ
- / var / log / <service_name> /サービスログを保存するディレクトリ
Phingユーティリティを使用してパッケージをビルドする
phingユーティリティは、パッケージの構築を担当します。
- トランクブランチからsvnから現在のバージョンをダウンロードします
- 上記の手順に従って、必要なディレクトリ内のすべてを配布します
- コマンドを呼び出してパッケージをビルドします
- svnにラベルを作成します
- パッケージをdebianパッケージリポジトリサーバーにアップロードします
パッケージ構造を形成するタスクのサンプルコード
<!-- ============================================ --> <!-- Target: prepare --> <!-- ============================================ --> <target name="prepare" depends="clean"> <echo msg=" " /> <mkdir dir="${project.packageDir}" /> <copy todir="${project.packageDir}"> <fileset dir="${project.basedir}/debian"> <include name="**/*" /> <exclude name=".svn" /> <exclude name="cron.d/" /> <exclude name="cron.d/*" /> </fileset> </copy> <exec command="svn info | grep 'URL: '" outputProperty="project.tmp.svnInfo" /> <php expression="end(explode(': ', '${project.tmp.svnInfo}'));" returnProperty="project.tmp.svnUrl" /> <echo msg=" SVN" /> <exec command="rm -Rf ${project.packageDir}/var/www/ntk-rm-crm/*" /> <exec command="svn export --force ${project.tmp.svnUrl} ${project.packageDir}/export/"/> <echo msg=" - /var/www/ntk-rm-crm/htdocs/" /> <mkdir dir="${project.packageDir}/var/www/ntk-rm-crm/" /> <copy todir="${project.packageDir}/var/www/ntk-rm-crm/htdocs/" > <fileset defaultexcludes="false" expandsymboliclinks="true" dir="${project.packageDir}/export/htdocs/"> <include name="**/*" /> </fileset> </copy> <mkdir dir="${project.packageDir}/var/www/ntk-rm-crm/htdocs/assets/" /> <copy file="${project.packageDir}/var/www/ntk-rm-crm/htdocs/index-prod.php" tofile="${project.packageDir}/var/www/ntk-rm-crm/htdocs/index.php" overwrite="true" /> <delete file="${project.packageDir}/var/www/ntk-rm-crm/htdocs/index-prod.php" /> <echo msg=" /usr/share/ntk-rm-crm/protected/" /> <mkdir dir="${project.packageDir}/usr/share/ntk-rm-crm/protected/" /> <copy todir="${project.packageDir}/usr/share/ntk-rm-crm/protected/" > <fileset defaultexcludes="false" expandsymboliclinks="true" dir="${project.packageDir}/export/protected/"> <include name="**/*" /> <exclude name="configs/*" /> <exclude name="**/yiic*" /> </fileset> </copy> <delete dir="${project.packageDir}/usr/share/ntk-rm-crm/protected/configs/" includeemptydirs="true" /> <echo msg=" yiic.php " /> <copy file="${project.packageDir}/export/protected/yiic-prod.php" tofile="${project.packageDir}/usr/share/ntk-rm-crm/protected/yiic.php" overwrite="true" /> <copy file="${project.packageDir}/export/protected/yiic-prod" tofile="${project.packageDir}/usr/bin/ntk-rm-crm" overwrite="true" /> <echo msg=" /etc/ntk-rm-crm/" /> <mkdir dir="${project.packageDir}/etc/ntk-rm-crm/" /> <copy todir="${project.packageDir}/etc/ntk-rm-crm/" > <fileset defaultexcludes="false" expandsymboliclinks="true" dir="${project.packageDir}/export/protected/configs/"> <include name="**/*" /> <exclude name="**/crm.test.php" /> <exclude name="**/local.default.php" /> </fileset> </copy> <echo msg=" /usr/share/doc/ntk-rm-crm/" /> <mkdir dir="${project.packageDir}/usr/share/doc/ntk-rm-crm/" /> <copy file="${project.packageDir}/export/protected/configs/env/local.default.php" tofile="${project.packageDir}/usr/share/doc/ntk-rm-crm/local.default.php" overwrite="true" /> <echo msg=" cron- /etc/cron.d/ntk-rm-crm" /> <copy file="${project.basedir}/debian/cron.d/ntk-rm-crm" tofile="${project.packageDir}/etc/cron.d/ntk-rm-crm" overwrite="true" /> <echo msg=" /var/log/ntk-rm-crm/" /> <mkdir dir="${project.packageDir}/var/log/ntk-rm-crm/" /> <echo msg=" /var/tmp/ntk-rm-crm/" /> <mkdir dir="${project.packageDir}/var/tmp/ntk-rm-crm/" /> <echo msg=" export" /> <delete dir="${project.packageDir}/export/" includeemptydirs="true" /> </target>
おわりに
結論として、このソリューションには長所と短所の両方があることに注意したいと思います。 このスキームの実装後に得られる主な利点のうち、パッケージのdebian-wayサポートを区別できます。これにより、サポートを受けている人たちの生活が楽になります。 また、新しい機能を同時に開発および実装することが容易になりました。
この記事はガイダンスのみを目的としています。 ある記事では、すべての側面を開示していません。 質問があれば、すぐに答えます。
さらに、SOAパラダイムに関する資料へのリンクもいくつかあります。