序文
出版は最後キロ連続配信です。
伝統的に、ソフトウェアの最終リリースは、手動設定、操作とチームワークの多くを必要とストレスの多いプロセスです。信頼性のリリースでは、開発者がテスト担当者はまた、詳細を行う必要があります後に展開、運用、保守担当者が発表しパーソナライズされたスクリプトのシリーズを実行するために、展開運用・保守要員の実装に関連する情報を同期させる、その後、詳細な展開ドキュメントを準備する必要があり、かつマニュアルの検証。
各ステップは、人間の判断と情報通信のことでニーズをたくさん持っている、わずかなミスが非常にヒューマンエラーはシステム障害、リリースタイムを引き起こし、その結果は予測できない、解放後の早い時間に忙しい生成されます、方法を考え頭脳アプリケーションだけで正しく動作するために展開させ、そして最後に、多くの場合、このようなシーンが共通しているロールバックする必要がありました。
配信の複雑さの介護者、使いやすい高速で、安定した、フォールトトレラントと強いのセットを減らし、反復的なソフトウェア開発に小さなステップを使用する方法に加えて、この痛みのポイントを解決するために、すばやく配信システムをロールバックする能力を有することが必要なの際に不可欠です本論文では、パブリッシングプラットフォームマイクロ医療の過程でのベストプラクティスのいくつかの構築に焦点を当てます。
コア特性
- その上でJava、NodeJS、パイソン、PHP、Luaの、アンドロイド、IOSおよび:主流のアプリケーションをカバーしています。
- サポートバッチリリースとグレーのリリース
- 一時停止を解除し、支援を再開
- 歴史の迅速なロールバックのバージョンをサポートしています
- アプリケーションのサポートと停止と再起動
- これは、マルチインスタンスアプリケーションログの集約ビューをサポートしています
- サポート分散パブリッシングノード
- リリースポイントの前に品質レッドカード
- リリースリアルタイム監視および分析
- リリースの品質と効率のメトリックの後
全体的なアーキテクチャ
- 典型的なアプリケーションの公開プロセス:
- システムプロジェクトの後、言語入力の開発、JDKのバージョン、ツールを構築、展開、製品のパス、コードアドレスを含むWCP-アプリケーション管理アプリケーションで作成したアプリケーションは、そのような基本的な情報などのアプリケーションを担当するアプリケーション(アプリの情報は、すべての研究開発協力の基礎となっています)。
- アプリケーションが作成された後、アプリケーションは自動的に、WCP-資源管理のリソースを適用するアプリケーションとCMDB内(テスト環境、開発前の環境、本番環境などを含む)、IP /ドメインとの間の関係を確立します。
- 確立パブリッシングプラットフォームのアプリケーションは自動的に仕事を公開発生した後、基本的な情報のアプリケーションやリソースを取得、リリースで発行された灰色またはバッチリリースの実行をトリガすることができます。
- レリーズ操作が(パイプラインの実行結果の確認と発行のチェックリストを含む)赤い線の品質をチェックし、自動的に実行される前に、解放するために品質赤いごみを満たしていませんでした。
- 発行操作、モニタは自動的に最初のリリース後に懸濁またはグレー、自動トリガ・モニタを公開します。モニターが公開停止に失敗した場合は、監視している場合、公開し続けることができます。
- レリーズ操作後、データ収集を格納して提供し、品質と効率が出力されかんばん発行データには、メトリック(公開成功率、発行頻度、および長いリリースタイム)を行います。
- 公開された問題は、高速のロールバックや他の機能を実行し、問題を迅速に見つけるためにログとパブリッシングアプリケーションログ集計クエリを提供しています。
- プラットフォームインターフェースを公開:
リリースポイントの前に品質カード
品質は、組み込み機能連続配信です。この最後キロを公開では、プラットフォームの自動化を公開することにより、品質レッドカードのポイントをどのように行う、プラットフォームリリースの重要な特徴です。
パイプラインのパイプラインで、自動的にユニットテストをトリガー,,静的コードスキャニング、セキュリティテスト、提出されたコードの現像後の統合テストは、参加するパイプラインの開発とテストを構成しています。
相互作用の品質を保証するための重要な手段は、持続的送達の目標を達成するために、我々は品質赤い線の実施の結果として、R&Dパイプラインを持っている公開カードポイント(あなたはまた、手動で表の検査結果の放出を増加させることができます)配達の全期間を保護する方法として、スムーズ。
一般的な品質のカードのポイント戦略の自動化:
- R&Dパイプライン状態
- ユニットテストの結果
- ユニットテストカバレッジ
- コードの静的チェック
- 統合テスト結果
- セキュリティスキャン結果
- 状態(リリース計画管理システム)をリリースする予定です
- 公開されたウィンドウ
- 評価結果などを公開
品質管理に掲載されました
システムの安定性を保護するために、我々は、各アプリケーション監視プラットフォームは、対応するダイヤルテスト監視点で構成されています。
リリースされたときにどのように誤報を減らすために、または主要な公開プロセスを回避することは、ここで発生したパブリッシングプラットフォームの監視プラットフォームを必要とし、高度な制御戦略のシリーズで行います。
- 公開されたシナリオ1:
- 説明:新しいバージョンがリリースされるサービスのインスタンスを再起動する場合、アプリケーションは、例えば、アプリケーション開発者は不要な干渉をもたらすこと、アラームをトリガすることを一定の確率があります。
- 戦略:アプリケーション荷造り、公式リリースを実行し、アプリケーションに監視タスクを有効にするために、リリース監視プラットフォームのAPIの後に同じ呼び出しで、アプリケーション内のタスクの監視を停止するために監視プラットフォームのAPIを呼び出すをコンパイルする前にプラットフォームを公開。
-
公開されたシナリオ2:
- 説明:様々な理由のために公開応用例(例えばコードエラーの展開としては、明らかにBUGの新バージョンなどがある)場合、システム障害がありました。
- 策略:采用分批发布策略,各个实例发布完后立即触发该实例的监控,如果监控发现异常,标识该批次发布操作失败,并强制中止后续批次的发布操作,以避免更多的实例出现问题。
-
逻辑流程
这里需要强调的是,拨测监控覆盖率在微医会作为团队的重要指标。因为应用只有在配置监控点后,发布平台才能在发布过程中进行有效的监测和干预。
发布后质效度量
质效度量是研发协作平台的一个重要组成部分,主要质效指标将按照研发质量、研发效率、研发成本三方面进行细分。
其中在发布过程中产生的数据,将会输送给质效度量系统进行质效分析,重点包括
- 发布频率
- 发布时长
- 发布成功率等。
所有团队和研发成员可以结合这些发布数据指标,发现自己存在的问题和短板,并进行有效改进。
分批发布
分批发布是批次进行应用部署,每次仅对应用的一部分实例进行升级。分批发布过程中如果出现故障,则终止回退,待问题修复后重新发布。
这里我们采用了比较简洁的批次分配算法,因为公司目前使用的是双机房IDC,当应用进行分批发布时,首批发布会在两个机房中随机各选择一个实例执行,其他的实例则放到了第二批发布。
选择发布暂停,则可在首批发布完后暂停发布,等人工确认首批发布的实例没有问题后,再执行后续其他实例的发布,如此可有效保障发布的稳定性。
发布过程中,可在发布平台中实时查看运行日志,若发现问题,可随时执行暂停、取消或者回滚等操作。
- 最佳实践
每个实例进行部署时,需要保证没有请求会派发到该实例,否则用户就会看到502的错误。所以需要有一个“下线”的操作,把当前机器从负载均衡中摘除,然后在部署完成之后,再把自己挂回到负载均衡中,这个过程称为“上线”。
为了实现该目的,可基于OpenResty自研Nginx网关对实例上下线进行实时调度,基于 OpenResty 的 Nginx 网关的实现过程比较复杂,这里不再详尽展开。
问题响应
在发布过程中,如果出现了一些意料之外的情况,发布平台也提供了一些常用的功能,满足开发人员定位和处理问题的需要,同时也尽量避免开发人员直接登录服务器操作。
- 查看日志
主要对接了公司统一的日志平台系统,可实时查看应用日志,并且聚合了多实例的日志信息,减少几个实例不停切换寻找问题的痛苦。
- 重启或停止实例
某个实例故障时,可快速重启或停用实例。
- 快速回滚
每个发布的版本发布平台都会有备份,当发布新版本发现问题时,可快速回滚到历史版本
Jenkins Pipeline
在整套发布平台中,Jenkins Pipeline提供了核心的构建、打包、部署以及分布式调度的底层基础能力,只不过为了更灵活的调度发布操作、管理应用与发布任务之间关系等,我们摒弃了Jenkins自身的UI界面,而通过发布平台调用Jenkins API的方式将其定位为基础引擎。
其中Jenkins Pipeline的共享库特性,让我们通过groovy编程的方式,很好的实现了发布脚本的版本管理,再也不用发愁怎么管理那堆凌乱的shell脚本了。
这里只截取一部分结构代码,Jenkins共享库的具体使用可参见之前的系列文章。
import groovy.json.JsonSlurper
def call(Map map) {
pipeline {
agent any
parameters {
//java应用参数
string(name: 'BUILD_TOOL', defaultValue: 'maven', description: '构建工具')
string(name: 'MAVEN_VERSION', defaultValue: 'maven3', description: 'maven构建工具版本')
string(name: 'GRADLE_VERSION', defaultValue: 'Gradle3.3', description: 'gradle构建工具版本')
string(name: 'WAR_RELATIVE_PATH', defaultValue: '', description: 'war包地址')
string(name: 'WAR_STD_NAME', defaultValue: '', description: 'war包地址')
string(name: 'POM_RELATIVE_PATH', defaultValue: '/pom.xml', description: 'pom文件地址')
string(name: 'HAS_TEMPLATES', defaultValue: 'false', description: '是否有模板文件')
string(name: 'TEMPLATES_RELATIVE_PATH', defaultValue: '', description: '模板文件路径')
string(name: 'JETTY_VERSION', defaultValue: '', description: 'jetty版本')
string(name: 'GRADLE_TASK', defaultValue: 'war', description: 'gradleTask打包方式')
......
}
tools {
gradle "${params.GRADLE_VERSION}"
jdk "${params.LANGUAGE_VERSION}"
maven "${params.MAVEN_VERSION}"
}
stages {
stage('部署正式环境') {
steps {
script {
def pmap = [:]
try {
//应用参数传递
pmap.put('BUILD_TOOL', BUILD_TOOL.trim())
pmap.put('WAR_RELATIVE_PATH', WAR_RELATIVE_PATH.trim())
pmap.put('WAR_STD_NAME', WAR_STD_NAME.trim())
pmap.put('