1. 背景
現在、弊社ではチームごとに異なるコンフィグレーションセンターを使用しており、eコマース会社はSpring Cloud Config、決済はApollo、APPチームはApollo+Nacosを使用しています。企業のビジネスの発展に適切に対応するには、統合されたインフラストラクチャ テクノロジー スタックが不可欠です。
画像出典:ライブブロードキャスト「マイクロサービスインフラストラクチャの選択で良い仕事をする方法」 – Li Yunhua
さらに、e コマース チームが使用する Spring Cloud Config は、次のような技術的な問題点に直面しています。
- 構成を変更するにはサービスの再起動が必要です
- 構成管理はフレンドリーではありません (gitlab を通じて変更)
- 権限制御、フォーマット検査、セキュリティ構成などの機能が欠如している
2. 構成センターの選択
オープンソース製品の分析
- 春のクラウド構成
2014 年 9 月にオープンソースになった Spring Cloud エコロジカル コンポーネントは、Spring Cloud システムとシームレスに統合できます。
- アポロ
2016 年 5 月、Ctrip は信頼性の高い分散構成管理センターをオープンソース化しました。異なる環境や異なるアプリケーションクラスタの構成を一元管理でき、構成変更後はリアルタイムでアプリケーション側にプッシュでき、標準化された権限やプロセスガバナンスなどの特徴を持ち、マイクロサービスに適しています。構成管理シナリオ。
- ナコス
2018 年 6 月、Ali は、クラウド ネイティブ アプリケーションの構築を容易にする動的なサービス ディスカバリ、構成管理、およびサービス管理プラットフォームをオープンソース化しました。アリババで育成され、10年間のダブルイレブンのピークテストで成長し、使いやすさ、安定性と信頼性、優れたパフォーマンスという核となる競争力を蓄積してきました。
比較項目 | ナコス | アポロ | 春のクラウド構成 | |
---|---|---|---|---|
コミュニティ活動 | オープンソースの時間 | 2018.6 | 2016.5 | 2014.9 |
ギットハブフォロー | 20.5k | 26K | 1.7K | |
書類 | 完了 | 完了 | 完了 | |
パフォーマンス | スタンドアロン読み取り (QPS) | 15000 | 9000 | 7 (電流制限のため) |
スタンドアロン書き込み (QPS) | 1800 | 1100 | 5 (電流制限のため) | |
可用性 | サービス停止の影響(構成サービス) | 開始されたクライアントは影響しません | 開始されたクライアントは影響しません | 開始されたクライアントは影響しません |
デプロイメントモード | 集まる | 集まる | 集まる | |
使いやすさ | 設定有効時間 | リアルタイム | リアルタイム | 再起動して有効にするか、手動更新して有効にしてください |
データの一貫性 | HTTP非同期通知 | データベースはメッセージ キューをシミュレートし、Apollo はメッセージを定期的に 1 分間読み取り、リアルタイムで有効にします。 | Git はデータの一貫性を保証し、Config-server は Git からデータを読み取ります | |
設定インターフェース | サポート | サポート | サポートしません | |
構成フォーマットのチェック | サポート | サポート | サポートしません | |
設定のロールバック | サポート | サポート | サポートされています (git ベースのロールバック) | |
バージョン管理 | サポート | サポート | サポート (git ベースのバージョン管理) | |
クライアントがサポートする言語 | 公式 Java 非公式 Go、Python、NodeJS、C++ | 公式 Java .net 非公式 Go、Python、NodeJS、PHP、C++ | ||
クライアントの使用 | ナコスクライアント | アポロクライアント | クラウド構成クライアント | |
安全性 | 権限管理 | サポート | 完全なデータ権限は比較的完全です | サポート (git) |
認可・監査・レビュー | サポート | インターフェース上での直接操作と変更許可と公開許可の分離をサポート | git 権限管理に依存する | |
データ暗号化 | サポートしません | サポートしません | プロパティ値の暗号化と復号化 | |
アーキテクチャの複雑さ | 運用保守コスト | Nacos+MySQL (シンプルなデプロイメント) | Config+Admin+Portal+MySQL (複雑な展開) | Config-server+Git+MQ (複雑なデプロイメント) |
サービスの依存関係 | Alibaba Cloud の登録および検出センターであり、2 つの機能が分離されています。 | 分散にはeurekaが組み込まれた登録センターが必要です | レジストリが必要です | |
グレーリリース | クライアント構成とルーティング ルールをサポートするクライアント コンピューティングの結合が高く、煩雑です | サーバー側の構成とルーティング ルールをサポート サーバー側の計算クライアントは透過的でシンプル | サポート | |
メールサービス | サポートしません | サポート | サポートしません | |
クエリ構成の監視 | サポート | サポート | サポート |
- パフォーマンスの観点から: 読み取りおよび書き込みパフォーマンス Nacos > Apollo > Spring Cloud Config。
- 機能の観点から: 機能の完全性 Apollo > Nacos > Spring Cloud Config。
- コミュニティ活動の観点から: Spring Cloud のエコロジカルな Netflix は、お金が儲からないため、基本的にあまりメンテナンスされていないことがわかりました。しかし、Spring Alibaba のマイクロサービス エコシステムは、これを変換した後、Ali がお金を稼ぐため、常にオープンソースで維持されます。 SaaS の一部。
- ナコスの利点: シンプル。登録センターと構成センターの機能が統合されており、導入と運用が Apollo よりも直観的かつシンプルであるため、アーキテクチャの複雑さが簡素化され、運用保守と導入の作業が軽減されます。
性能比較
- プレス情報
プロセッサー: Intel® Core™ i5-9500 CPU @ 3.00GHz 3.00 GHz
システム: Windows 10
内部テスト: 16G
- 圧力測定ツール:JMeter
- 圧力テスト戦略: 100 人のユーザーがスレッド 10 を段階的にオープン、期間 100 秒をリクエスト
シナリオ 1: サーバーを呼び出す
テスト結果は次のとおりです。
圧力テストにより、Nacos 読み取り構成の TPS は約 11000、書き込み構成の TPS は約 1800 であるのに対し、Apollo 読み取り構成の TPS は約 1100、書き込み構成の TPS は約 310 であることがわかります。 Nacos読み取りおよび書き込みパフォーマンスにおいて明らかな利点があります。
シナリオ 2: クライアントに電話する
テスト結果は次のとおりです。
読み取りパフォーマンスに大きな違いがないことがわかります。
結論は
選定理由 | 選ばない理由 | |
---|---|---|
ナコス | 統合されたテクノロジースタックにより、既存テクノロジーの問題点を解決できる 運用コストとメンテナンスコストが低い | |
アポロ | エウレカに頼る | |
春のクラウド構成 |
参照文書:
3. すぐに使える
参考ドキュメント:https://nacos.io/en-us/docs/quick-start-spring-boot.html
依存関係をアップグレードする
spring-cloud-config の依存関係を削除します。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
Nacos 依存関係を追加します。
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.1.8</version>
</dependency>
Nacos 構成を置き換える
元の bootstrap.yml ファイルの構成構成を nacos 構成に置き換えます。
spring:
application:
name: {
应用名}
cloud: # 移除
config: # 移除
uri: http://config-center.alpha-intra.dbses.com/conf # 移除
label: alpha # 移除
置換結果は以下の通りです。
spring:
application:
name: {
应用名}
nacos:
config:
server-addr: http://ec-nacos.dbses.com
namespace: alpha
group: {
组名}
スタートアップクラスにアノテーションを追加する
// dataId 对应服务的配置
@NacosPropertySource(groupId = "${nacos.config.group}", dataId = "${spring.application.name}.yml", first = true)
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
4. 練習する
動的リフレッシュの構成
方法 1: @NacosValue を使用する
このメソッドを使用するには、@NacosPropertySource に autoRefreshed=true を追加する必要があります。サンプルコードは次のとおりです。
@NacosPropertySource(groupId = "infra", dataId = "zebra-service.yml", first = true, autoRefreshed = true)
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
Nacos は次のように構成されています。
test1:
config: 2
インターフェースのコードは次のとおりです。
@RestController
public class TestController {
@NacosValue(value = "${test1.config}", autoRefreshed = true)
private String config;
@GetMapping("/config")
public String getConfig() {
return config;
}
}
方法 2: @NacosConfigurationProperties を使用する
サンプルコードは次のとおりです。
@Configuration
@Data
@NacosConfigurationProperties(prefix = "test2", dataId = "zebra-service.yml", groupId = "infra", autoRefreshed = true)
public class TestConfig {
private List<String> config;
private Map<String, String> map;
@Override
public String toString() {
return "TestConfig{" + "config=" + config + ", map=" + map + '}';
}
}
Nacos は次のように構成されています。
test2:
config:
- yang
- wang
map:
courier: yang
zebra: wang
インターフェースのコードは次のとおりです。
@RestController
public class TestController {
@Autowired
private TestConfig testConfig;
@GetMapping("/config2")
public String getConfig2() {
return testConfig.toString();
}
}
知らせ
マップを動的に更新すると、変更されたキーが蓄積され、元のキーは削除されません。たとえば、zebra-service.yml 設定の test2.map.zebra を test2.map.zebr に変更すると、得られる結果は次のようになります。
TestConfig{config=[yang,money]、map={courier=yang、zebra=money、zebr=money}}
方法 3: @NacosConfigListener を使用する
Nacos は次のように構成されています。
test1:
config: 2
サンプルコードは次のとおりです。
@RestController
public class TestController {
@Value(value = "${test1.config}")
private String config;
@GetMapping("/config")
public String getConfig() {
return config;
}
@NacosConfigListener(dataId = "zebra-service.yml", groupId = "infra")
public void testConfigChange(String newContent) {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(new ByteArrayResource(newContent.getBytes()));
Properties commonsProperties = yamlFactory.getObject();
this.config = commonsProperties.getProperty("test1.config"));
}
}
複数の構成のインポート
問題の説明
私たちのプロジェクトはこれまでに多くのパブリック構成を読み取ってきましたが、今度はパブリック構成を読みたいと考えています。どうすればよいでしょうか?
問題が解決しました
@NacosPropertySources アノテーションを使用して複数の構成ファイルを追加できます。
サンプルコード:
@NacosPropertySources({
@NacosPropertySource(groupId = "infra", dataId = "captcha-service.yml", first = true),
@NacosPropertySource(groupId = "commons", dataId = "__common_eureka_.yml")
})
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
ここで、first = true は、このファイルの構成優先度が最も高いことを意味します。
ローカル構成の上書き
問題の説明
開発者として、デバッグのためにプログラムをローカルで起動する必要がある場合がありますが、現時点では、ローカルで起動されたプログラムはアルファ環境の構成に接続されています。アルファ環境の構成を変更すると、アルファおよび他のプログラムの動作に影響を与える可能性があります。
このような状況に直面した場合、構成の優先順位をどのように管理すればよいでしょうか?
test1.config 構成を例に挙げてみましょう。nacos 設定ファイルは次のとおりです。
起動時の設定は以下の通りです。
テストコードは次のとおりです。
@RestController
public class TestController {
@NacosValue(value = "${test1.config}", autoRefreshed = true)
private String config1;
@GetMapping("/config1")
public String getConfig1() {
return config1;
}
}
実行結果は次のとおりです。
ローカル構成ではカバレッジの効果は得られません。
問題分析
最初にプログラムのスタートアップ クラスを変換することもできます。
ブレークポイントから、アプリケーション設定 (ここでは nacos の zebra-service.yml を指します、以下同様) の優先順位が、必要なパブリック設定よりも前にあることがわかります。
アプリ構成はパブリック構成よりも前に置く必要があります。
ただし、アプリケーション構成は、システム変数 (systemProperties) およびシステム環境 (systemEnvironment) の前にもあります。そのため、設定した test1.config はローカルとして有効になりませんでした。
少し変更を加えると、次のようになります。
問題が解決しました
次に、ローカル構成が上書きされるかどうかをテストします。
ローカル構成はカバレッジの効果に達しました。最終的な起動クラス コードは次のとおりです。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@PrepareConfigurations({
"__common_database_", "__common_eureka_"})
@NacosPropertySource(groupId = "infra", dataId = "zebra-service.yml", autoRefreshed = true
,after = StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME
)
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
この記事は、ブログ用のマルチポスト プラットフォームであるOpenWriteによって公開されています。