プロファイルは逆モードです

5618 ワード

逆モードとは、一般的に固定されたパターンが形成されている誤った方法を指すが、プロファイルについては、ある微信群の中でredisの公式dockerミラーがredis.confを暴露していないと文句を言っている人がいるのを見て、私は当時議論しにくいが、自分の観点を言っただけだ.「プロファイルを配置するのは逆モードだ」.
実際、この問題については2年ほど前に書いたことがあります.
...(後に)環境変数を用いずにソフトウェアを制約し、カスタマイズする行為(環境変数はもともとこれをしているが)という共通認識が形成された.このような結果、c/c+、java、python、rubyの様々なコミュニティは自分のプロファイルの習慣的な使い方を形成しています.さらに、javaコミュニティには、プロファイル自体をコードと区別する傾向がありました.
どれだけの人がこの話に注意しているのか分からないが、同僚から感銘を受けたというフィードバックがあったので、細かい議論を省略した.しかし、2年後、私は論争が少なくないことに気づいたが、その道理ははっきりしていないので、本文は補習に来て、プロファイルの問題を専門に討論した.
構成は何ですか?
構成の「構成」ではありません
web.xml、springXX.xml、ibatisXX.xml......これらはかつてJavaエンジニアがよく知っていた「配置」であり、「約束が配置より大きい」がまだ流行していない時代には、これらのものは非常に煩雑で、開発者に非難されることが多い.それらのしたことは実際にはコードと差が少なく、コードを書かないのはプログラミング言語で簡潔に表現しにくいからだ.
Ruby on Railsにも似たようなファイルがあります.configディレクトリの下にあるファイル(routes.rb、アプリケーション.rb、initializersディレクトリの下にあるファイルなど)は、「構成」ファイルと呼ばれていますが、それ自体はrubyコードにすぎません.ある観点から、これらのファイルはいくつかの機能ライブラリを的確に構成するためであるが、このような「構成」は使い捨てであり、不変であるため、ビジネス機能のプログラミング実装と見なすこともできる.
これらの状況には共通点があります.これらのいわゆる「構成」ファイルは、開発段階で作成され、ソフトウェアの納品後、テストでもオンラインでも変更されません.ソフトウェア開発のライフサイクルから見ると、コードと一致しているので、この「構成」ファイルは構成ではありません.
本格的な構成
本当の構成はdevtestperealを接頭辞とする内容です.例えば、データベースの設定です.開発段階と生産環境で同じデータベースを使用することはできません.
# config/database.yml
development:
  ......
  database: shelter_development

test:
  ......
  database: shelter_test

production:
  <<: host:="" db="" database:="" shelter_production=""/>

これらの構成は、アプリケーション・システムと外部環境の関係を示し、各構成項目の値は、特定の環境に関連し、ライフサイクルとコードが異なり、ソフトウェアの導入と実行に密接に関連しています.
構成管理
コンフィギュレーション・アイテムは実行時と関連しているため、ソフトウェア・システムが実行されると、これらのコンフィギュレーション・アイテムに実際のパラメータ値を提供する必要があります.たとえば、次のようにします.
production:
  <<: host:=""/>

このような内容はソースコード制御に組み入れるべきではないことを知っています.理由は3つあります.
  • 線上の実際の状況は保護する必要があり、ソースコードに直接組み込まれると安全リスク
  • を招く.
  • オンライン次元から見ると、データベースの交換などの調整が必要になると、比較的簡単な方法で迅速に切り替えるべきであり、「commit-push-deploy」プロセスはこのような調整に煩雑すぎる
  • である.
  • ソースコードのバージョン管理は、線上に複数のアプリケーションインスタンスがある、構成項目の値が異なるなど、
  • のような内容と調和しにくい.
    ここでの根本的な原因は、コンフィギュレーション・アイテムとコードのライフサイクルが異なることです.
    通常のメンテナンス作業では、構成項目とソースコードを管理するバージョン制御システムは独立しており、gitをオンラインで維持し、すべてのオンライン構成ファイルを入れ、自動化スクリプトで配布を実行する方法を見たことがあります.
    dockerテクノロジーを使用すると、このような方法が見られます.
    docker run ... -v /home/admin/conf/db.yml:/usr/src/app/config/database.yml ...
    

    標準化と自動化の必要性から、この行のコードは、あるcapistranoスクリプトまたはjenkinsタスクで硬化する可能性があります.実際には、本明細書の最初の問題で得られた提案の答えでもあります.
    この方法は実行可能ですが、残念ながらこれはきれいではありません.構成項目には環境の特殊性(ここではデータベース・サーバのhostを指します)を反映する必要があります.このような構成項目ごとに、メンテナンスを実行するツールが管理する必要がある情報は少なくとも4つあります.
  • 構成項目名:host
  • 構成項目の値:192.168.16.103
  • プロファイルの場所:/home/admin/conf/db.yml
  • プロファイルのターゲットマウントポイント:/usr/src/app/config/database.yml
  • 明らかに、前の2つこそ私たちが関心を持っている情報であり、後の2つは重要ではありません.
    ここで「間接性」が現れたため,コンフィギュレーション項目の名前−値バインドをファイルに配置したため,メンテナンスツールはこのバインド関係を直接管理するのではなく,そのファイルを迂回的に管理し,それによってマウントポイントの概念を導入した.
    これは小さな問題のようですが、実際にはそうではありません.このような間接管理には反直感のほかに、少なくとも2つの結果があります.
  • コンフィギュレーション・アイテムの統一管理の困難は、どのようなメンテナンス・ツールを使用しても、ツールがどのコンフィギュレーション・アイテムを管理しているか分からないため、グローバル・ビューが不足しており、将来コンフィギュレーション・アイテムの最適化が面倒になります.この結果、多くのチームが「コンフィギュレーション・管理システム」を追加開発する必要があります.次に、この管理システムにマウントポイントとファイルの実際の場所のバインド関係の維持を担当させます.
  • コンフィギュレーション・アイテム管理は標準化できません.明らかに、javaアプリケーションのdb.propertiesとRailsアプリケーションのdatabase.ymlのファイルは本質的に同じデータ構造を持っているが、使用すると大きく異なるため、上記の「構成管理システム」では、さまざまなプロファイルフォーマットを理解する必要があり、読み取ることができるだけでなく、情報を失わずに書き込むことができる.(そして、コンフィギュレーションファイルのコメント内容など多くの問題も処理する)
  • プロファイルを使用するのは良いアイデアではありません.より良い方法は環境変数を使用することです.
    production:
      <<: host:="" env="">
    

    dockerでコンテナを有効にすると、次のようになります.
    docker run ... -e db_host='192.168.16.103' ...
    

    一見、このようにするのは少し遅れているように見えますが、特に構成項目が多い場合は面倒に見えますが、実際には私たちは直接そうすることはありません.メンテナンスツールを借りて、これらの構成項目はシステム的に管理することができます.ファイルという中間段階を取り除くと、構成管理は簡単になり、標準的なオープンソースソフトウェアで負担することができます.
    もちろん、ここでは本当の構成項目を管理する必要があります.構成ではない「構成」は必要ありません.
    構成の本質
    次に、この構成の本質について詳しく説明します.ソフトウェアとは、本質的にはプログラムです.簡単なプログラムコードは、このように実行できます.
    def area
      5 ** 2 * Math::PI
    end
    

    半径5の円面積を計算して実行します
    irb(main):001:0> area
    => 78.53981633974483
    

    しかし、このコードは固定半径しか計算できません.一般的には、次のように変更されます.
    def area r
      r ** 2 * Math::PI
    end
    

    実行してください
    irb(main):001:0> area 5
    => 78.53981633974483
    irb(main):002:0> area 7
    => 153.93804002589985
    

    修正前後の違いは関数を追加したパラメータで、プログラム設計課の先生は私たちに、関数の中のrは形式パラメータで、呼び出す時私たちはこのrの代わりに数字の5あるいは7を使って、呼び出す時のパラメータの値も実際のパラメータと言います.
    この例は簡単ですが、パラメータ化という重要な考え方が含まれています.コアは、私たちが確定できるものをある製品ユニット(関数、クラス、プログラムなど)に固化し、パラメータによって適応能力を備えさせ、さまざまな実行コンテキストに柔軟に適応することができます.
    したがって、パラメータ付与プロセスは実際には製品ユニットが実行コンテキストを得るプロセスであり、環境へのバインドと見なすこともできる.この考え方によれば、関数パラメータ化はパラメータ付き関数であり、クラスのパラメータ化はインスタンス変数を携帯する対象インスタンスであり、プログラムのパラメータ化は私たちが上述した構成項目であり、この意味で、私たちはUNIXの先駆者たちがなぜ環境変数のメカニズムを作ったのかをよりよく理解することができる.
    コンフィギュレーション項目とはアプリケーションソフトウェアをパラメータ化することであり,環境変数設定は実パラメータ対パラメータのバインドである.
    プログラムとプロセスの関係はクラスとインスタンスの関係によく似ています.プログラムがインスタンス化されるたびに、つまりプロセスを実行するときにオペレーティングシステムが環境変数をバインドします.これにより、このプロセスは起動時の設定に従って自分の実行ロジックを調整し、外部環境に適応します.
    環境変数のバインドはプロセスの開始時に行われ、実行中に値を変更できないことに気づく人もいるかもしれませんが、これは設計上の不足ではないでしょうか.
    いいえ、逆の設計を想定することができます.環境変数のバインドがいつでも行われている場合、私たちは行動方式が不確定なソフトウェアシステムに直面します.プロセスの実行に問題が発生すると、私たちが分析する現場には、実際の値を確定していないパラメータがたくさん含まれています.これは問題の分析によく災難です.
    配置は小さな問題のように見えますが、私たちが真剣に考察した後、システムのアーキテクチャ、コンポーネント間、コンポーネントと外部環境の関係をもっと深く理解することができます.私はずっと『三体』の章北海の父の臨終前の提案「もっと考えなさい」が好きです.はい、問題に遭遇したらもっと考えて、よく考えてから手を出して、仕事が半分になります.
    思考問題:「開閉原則(Open/Closed Principle)」との関係は?