[Spring Clound] Nacos 高可用性クラスターの構築と使用

1. ナコスの紹介

Nacos は、マイクロサービスの検出、構成、管理を支援することに専念しています。Nacos は、動的なサービス検出、サービス構成、サービス メタデータ、およびトラフィック管理を迅速に実現するのに役立つ一連の使いやすい機能セットを提供します。Nacos は、マイクロサービス プラットフォームをより機敏かつ簡単に構築、配信、管理するのに役立ちます。Nacos は、「サービス」中心の最新のアプリケーション アーキテクチャ (マイクロサービス パラダイム、クラウド ネイティブ パラダイムなど) を構築するためのサービス インフラストラクチャです。

nacos公式サイト:https://nacos.io/zh-cn/docs/what-is-nacos.html

2.Nacosのインストール

2.1. Nacos 環境の依存関係

Nacos は Java に基づいて開発されており、その動作は 64 ビット JDK 1.8+ 環境に依存します。

公式 Web サイトに移動して JDK をダウンロードします: Java ダウンロード | Oracle

2.2. Nacos サーバーのインストール

Nacos はオープン ソースであるため、github からソース コードをダウンロードしてコンパイルしてインストールすることも、github から直接コンパイル済みの公式インストール パッケージをダウンロードしてインストールすることもできます。この記事では、最新の情報に基づいて、公式にコンパイルされたインストール パッケージを直接使用してインストールします。正式リリース2.0.3バージョン。以前に抜け穴があったため、2.x より前のバージョンは使用しないでください。1.x バージョンと比較して、2.x バージョンのパフォーマンスも 10 倍向上しています。

ダウンロードアドレス: https://github.com/alibaba/nacos/releases

3. Nacosの展開

3.1. 単一インスタンスのデプロイメント

単一インスタンスの展開は運用環境には適しておらず、単一障害点は致命的です。

Linux シングル インスタンスの非クラスター モード起動コマンド:

スタートアップ.sh -m スタンドアロン

Linux 単一インスタンスの非クラスター モードのシャットダウン コマンド:

シャットダウン.sh

nacos管理ページにアクセスし、ユーザー名とパスワードをnacosとして初期化します。

アクセスアドレス:http://127.0.0.1:8848/nacos/index.html

デフォルトではポートは 8848 であり、IP はデプロイメントサーバーインスタンスの IP に置き換える必要があります。

3.2. クラスターの展開

3.2.1. クラスターアーキテクチャ

ここに画像の説明を挿入

  • 高可用性 Nginx クラスター
  • Nacos クラスター (少なくとも 3 つのインスタンス)
  • 高可用性データベース クラスター (Nacos 組み込みデータベースを置き換える)

3.2.2. シミュレートされた展開

環境情報:

システムバージョン マシンIP アプリケーションをデプロイする アプリのバージョン
CentOS8.5 192.168.230.1 Nginx nginx-1.18.0
CentOS8.5 192.168.230.129 ナコス 2.0.3
CentOS8.5 192.168.230.130 ナコス 2.0.3
CentOS8.5 192.168.230.131 ナコス 2.0.3
CentOS8.5 192.168.230.1 MySQL 5.7.32

vmware 仮想マシンを使用して、上記のさまざまなマシン環境をシミュレートします。

ビルド手順:

  1. nacosデータベースを初期化する

ダウンロードしたインストール パッケージ nacos-server-2.0.3.tar.gz を /usr/local ディレクトリに解凍し、/nacos/conf で nacos-mysql.sql スクリプトを見つけます。

ここに画像の説明を挿入

MySQLインスタンスにnacosライブラリを作成し、SQLスクリプトを実行する
ここに画像の説明を挿入

MySQL インスタンスを指すように Nacos 構成ファイルを変更し、その埋め込みデータベースを置き換えます。

ここに画像の説明を挿入

application.properties で次の設定を見つけます。この設定はデフォルトでコメントアウトされています。コメントをキャンセルし、データベース情報を実際のデータベース情報に変更して保存します。他の nacos サービス インスタンスも同じ変更を行う必要があります

ここに画像の説明を挿入

高可用性を実現するには、通常、複数の MySQL データベース インスタンスがあり、nacos の構成ファイルでも各 MySQL インスタンスの情報を指定する必要があります。次に例を示します。

ここに画像の説明を挿入

  1. クラスタ構成

/nacos/conf の下でcluster.conf.example ファイルを見つけて、名前をcluster.conf に変更します。

ここに画像の説明を挿入

cluster.conf ファイルを変更し、ファイル内のデフォルトの IP 情報を削除し、nacos クラスター内の各 nacos インスタンスの IP を追加します。クラスター内のすべての nacos インスタンスは、上記のクラスター構成を行う必要があります。これまで nacos の構成が完了したので、クラスター モードで 3 つの nacos インスタンスを起動してみることができます。
ここに画像の説明を挿入

/nacos/bin ディレクトリに切り替えて、 ./startup.sh & tail -f /usr/local/nacos/logs/start.out を実行します。

nacos を起動し、起動ログを確認すると、起動が成功したことを示す次のプロンプトが表示されます。

ここに画像の説明を挿入
ここに画像の説明を挿入

この時点で、ブラウザを通じて各 nacos インスタンスのコンソールにアクセスできます (例: http://192.168.230.131:8848/nacos)。

注: 3 つのインスタンスがクラスター モードで正常に起動した場合、3 つのインスタンスのそれぞれの管理ページにアクセスすると、上記のログイン ページが表示されます。アクセスできない場合は、ファイアウォールが nacos サービスのポートを開いていない可能性があります。次のコマンドを実行できます。

[root@localhost bin]# firewall-cmd --add-port=8848/tcp --permanent
 
success
 
[root@localhost bin]# firewall-cmd --reload
 
success

nacos 起動レポートが異常な場合は、次の 3 つの理由が考えられます。

ここに画像の説明を挿入

理由 1: MySQL データベースに接続できません。通常、MySQL データベースが存在するホストがポート 3306 を開いていないためです。MySQL ホストで次のコマンドを実行します。

[root@localhost bin]# firewall-cmd --add-port=3306/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
Success

理由 2: nacos 設定ファイル application.properties のデフォルトのデータベース接続タイムアウト設定は、次の図に示すように比較的短いため、ネットワーク遅延やその他の理由により、MySQL が接続タイムアウトになり、nacos がエラーを開始する可能性があります。したがって、タイムアウトを長い時間に設定するだけで済みます。

ここに画像の説明を挿入

ここに画像の説明を挿入

理由 3: 仮想マシンのメモリが不足しています。vmvare で仮想マシンを作成すると、各仮想マシンに 1G のメモリしか割り当てられません。nacos の起動スクリプト start.sh から、nacos がクラスタで起動されると、デフォルトで割り当てられる Java ヒープモード メモリ空間は 2G なので、nacos 起動エラーは仮想マシンのメモリ不足が原因と判断でき、仮想マシンのメモリを 2G に変更すると正常に起動できるようになります。

  1. Nginxの設定

Nginx 構成ファイル nginx.conf を次のように変更します。

http {
    
    
 
    include       mime.types;
 
    default_type  application/octet-stream;
 
    sendfile        on;
 
    keepalive_timeout  65;
 
    #nacos集群负载均衡
    upstream nacos-cluster {
    
    
        server 192.168.230.129:8848;
        server 192.168.230.130:8848;
        server 192.168.230.131:8848;
    }
 
    server {
    
    
        listen       80;
        server_name  192.168.230.1;
        location / {
    
    
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://nacos-cluster;
        }
 
        error_page   500 502 503 504  /50x.html;
 
        location = /50x.html {
    
    
            root   html;
        }
    }
}
  1. アクセスコンソール

Nginx サービスが存在するホストの IP をブラウザーに入力してアクセスします。

http://192.168.230.1/nacos/#/login

デフォルトのユーザー名/パスワード: nacos/nacos

ここに画像の説明を挿入

[クラスター管理] - [ノード リスト] に切り替えて、nacos クラスター ノード情報を表示します。

4. マイクロサービス統合 Nacos

4.1. 依存コンポーネントのバージョンの選択

Spring Cloud Alibaba と Spring Boot および Spring Cloud のバージョン間の互換性要件は非常に厳しいため、間違ったバージョンに依存すると、サービスの開始時にエラーが発生し、起動に失敗する可能性があります。ただし、Alibaba 担当者は、推奨されるバージョンの依存関係を整理してくれました。

ここに画像の説明を挿入

使用している nacos は最新バージョン 2.0.3 であるため、上記の表から、依存する Spring Cloud Alibaba のバージョンは 2.2.7.RELEASE であることがわかります。Spring Cloud Alibaba のバージョンに従って卒業バージョン依存関係テーブルのクエリを続けます。以下の図に示すように、依存する Spring Cloud バージョンは Hoxton.SR12、依存する Spring Boot バージョンは 2.3.12.RELEASE であることがわかります。

ここに画像の説明を挿入

したがって、上記のクエリを通じて、マイクロサービスの依存関係バージョンの選択は次のように最終的に決定されます。

Springクラウドバージョン Spring Cloud Alibaba バージョン スプリングブートバージョン ナコスバージョン
ホクストン.SR12 2.2.7.リリース 2.3.12.リリース 2.0.3

公式バージョンの説明: https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

4.2. 登録センター

まず、demo-project-parent 親プロジェクトを作成し、次のように、「4.1 依存コンポーネントのバージョンの選択」で決定されたバージョンに従って、親 pom ファイルに依存コンポーネントとバージョンを定義します。

<properties>
  <java.version>1.8</java.version>
  <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
  <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
  <spring-cloud-alibaba.version>2.2.7.RELEASE</spring-cloud-alibaba.version>
</properties>
 
<dependencyManagement>
  <dependencies>
    <!-- spring boot 依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>${spring-boot.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    
    <!-- spring cloud 依赖 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
 
    <!-- spring cloud alibaba 依赖 -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>${spring-cloud-alibaba.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

4.2.1. サービスプロバイダー

親プロジェクトの下に新しいサービス プロバイダーのサブモジュール micro-service-provider を作成し、pom ファイルに依存関係を導入します。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

プロバイダー構成ファイル application.yml を変更します。

server:
  port: 8081
 
spring:
  application:
    name: service-provider
  cloud:
    nacos:
      discovery:
	#nacos集群配置(Nginx)
        server-addr: 192.168.230.1:80

プロバイダー起動クラス:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
    
    
 
    public static void main(String[] args) {
    
    
        SpringApplication.run(ProviderApplication.class, args);
    }
 
}
Provider测试Controller类:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class ProviderController {
    
    
 
    @Value("${server.port}")
    String port;
 
    @GetMapping("/hi")
    public String hi(@RequestParam(value = "name", defaultValue = "zmx",required = false) String name) {
    
    
        return "hello " + name + ", i'm provider, my port:" + port;
    }
 
}

4.2.2. サービス利用者

親プロジェクトの下に新しいサービス コンシューマ サブモジュール micro-service-consumer を作成し、pom ファイルに次の依存関係を導入します。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
 
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
 
<!-- 需要注意的是引入openfeign,必须要引入loadbalancer,否则无法启动。-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

コンシューマ構成ファイルを変更します。

server:
  port: 8082
 
spring:
  application:
    name: service-consumer
  cloud:
    nacos:
      discovery:
        #nacos集群配置(Nginx)
        server-addr: 192.168.230.1:80

@EnableFeignClient アノテーションをプロジェクトのスタートアップ クラスに追加して、FeignClient 機能を有効にします。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
 
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
    
    
 
    public static void main(String[] args) {
    
    
        SpringApplication.run(ConsumerApplication.class, args);
    }
 
}

プロバイダー サービスのインターフェイスを呼び出す偽クライアント FeignClient を作成します。

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
//此处的value值对应于provider服务application配置文件中的spring.application.name
@FeignClient(value = "service-provider" )
public interface ProviderClient {
    
    
 
    @GetMapping("/hi")
    String hi(@RequestParam(value = "name", defaultValue = "zmx", required = false) String name);
 
}

テスト インターフェイスを作成し、コンシューマーがプロバイダー サービスのインターフェイスを呼び出せるようにします。

import net.myibc.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class ConsumerController {
    
    
 
    @Autowired
    ProviderClient providerClient;
 
    @GetMapping("/hi-feign")
    public String hiFeign(){
    
    
        return providerClient.hi("feign");
    }
}

プロバイダープロジェクトとコンシューマープロジェクトを起動し、nacosの[サービス管理]-[サービス一覧]ページで確認すると、両方のサービスが正常に登録されていることがわかります。

ここに画像の説明を挿入

注: ここですべてのサービスを開始した後、コンソールで特定のサービスのみを表示できるか、登録されたサービスが見つからない場合があります。nacos.log ログを確認して、次の例外を見つけてください。
ここに画像の説明を挿入

この例外の理由: nacos クライアントがバージョン 2.x にアップグレードされると、gRPC の通信方法が追加され、2 つのポートが追加されます。これら 2 つのポートは、nacos の元のポート (デフォルトでは 8848) に特定のオフセットを付けて自動的に生成されます。

ポートとメインポート間のオフセットの説明:

9848: クライアント gRPC リクエスト サーバー ポート。クライアントがサーバーへの接続とリクエストを開始するために使用します。

9849: サーバー gRPC は、サービス間の同期などに使用されるサーバー ポートを要求します。

7848: Nacos クラスター通信ポート。Nacos クラスター間の選出、検出などに使用されます。

したがって、この問題の原因は、nacos2 で新たに追加された 2 つのポートがすべてのサービス登録インスタンス情報を表示できないことにあると推測するのは難しくありません。nacos ホストで次のコマンドを実行するだけです。

[root@localhost bin]# firewall-cmd --add-port=9848/tcp --permanent
success
[root@localhost bin]# firewall-cmd --add-port=9849/tcp --permanent
success
[root@localhost bin]# firewall-cmd --add-port=7848/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
Success

注: VIP/nginx プロキシ クラスターを使用する場合、2 つのポート 9848 および 9849 の TCP リクエスト転送を nginx で構成する必要があります。そうしないと、クライアント サービスは起動時にサーバーの 2 つのポートに接続できなくなります。起動が失敗する原因となります。プロキシを使用しない場合、ホストが上記のコマンドを実行してポート ホワイトリストを有効にした後、クライアント サービス アプリケーション構成ファイルで naocs クラスターのノードの IP とポートを構成するだけで済みます。 :

ここに画像の説明を挿入

Nginx は nacos TCP 転送構成を構成します。

#配置nacos TCP转发
stream {
    
    
    upstream nacos1 {
    
    
        server 192.168.230.129:9848;
        server 192.168.230.130:9848;
        server 192.168.230.131:9848;
    }
 
    server {
    
    
        listen 9848;
        proxy_pass nacos1;
    }
 
    upstream nacos2 {
    
    
        server 192.168.230.129:9849;
        server 192.168.230.130:9849;
        server 192.168.230.131:9849;
    }
 
    server {
    
    
        listen 9849;
        proxy_pass nacos2;
    }
}

4.2.3. サービスコール

ブラウザに http://127.0.0.1:8082/hi-feign と入力すると、ブラウザは応答を返します。

hello feign, i'm provider ,my port:8081

ブラウザのリクエストがコンシューマ サービスのインターフェイスを正常に呼び出し、コンシューマ サービスも偽装によってプロバイダ サービスのインターフェイスを正常に呼び出すことがわかります。

4.2.4、負荷分散

Feign は Spring Cloud Loadbanlancer をロードバランサーとして使用します。プロバイダーのポートを変更して、ローカルで新しいプロバイダー サービスを開始すると、ローカルに 2 つのプロバイダー サービスが存在し、ポートはそれぞれ 8081 と 8083 になります。ブラウザで http://127.0.0.1:8082/hi-feign を複数回呼び出すと、ブラウザに次の情報が交互に表示されます。

hello feign, i'm Provider ,my port:8081
hello feign, i'm Provider ,my port:8083
この時点で、コンソール プロバイダー インスタンスの数は 2 になります。

4.3. 設定センター

4.3.1、構成センタークライアント

新しい nacos 構成クライアント サブモジュール nacos-config-client を親プロジェクトの下に作成し、pom ファイルに次の依存関係を導入します。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

bootstrap.yml ファイルで次の内容を構成します (application.yml ファイルではなく、bootstrap.yml ファイルである必要があります)。

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      config:
        server-addr: 192.168.230.1:80
        file-extension: yaml
        prefix: nacos-config-client
  profiles:
    active: dev

上記の構成では、nacos config サーバーのアドレスが構成され、構成の拡張子は ymal です (現在サポートされているのは ymal とプロパティのみです)。server.port は設定されておらず、server.port の属性は nacos で設定されていることに注意してください。上記の設定は、Nacos の dataId の形式に対応しています。nacos の完全な形式は次のとおりです。

${
    
    prefix}-${
    
    spring.profile.active}.${
    
    file-extension}
  • prefix のデフォルトは spring.application.name の値ですが、構成項目 spring.cloud.nacos.config.prefix を通じて構成することもできます。
  • spring.profile.active は現在の環境に対応したプロファイルであり、詳細は Spring Boot のドキュメントを参照してください。注: spring.profile.active が空の場合、対応するコネクタも存在せず、dataId のスプライシング形式はprefix . {prefix} になります。プレフィックス_ _ _ _ {ファイル拡張子}
  • file-exetension は構成コンテンツのデータ形式であり、構成アイテム spring.cloud.nacos.config.file-extension を通じて構成できます。現在、プロパティと yaml タイプのみがサポートされています。

nacos を起動し、コンソール http://192.168.230.1/nacos にログインし、データ ID を作成します。完全な構成は次の図に示されています。

ここに画像の説明を挿入

RestController を作成し、コントローラーに @RefreshScope アノテーションを追加して、構成のホット ロードを実装します。このアノテーションは、構成を動的に更新する必要があるクラスがロードされた場合にのみ有効になります。このアノテーションがスタートアップ クラスに追加された場合、他のクラスの動的更新は有効になりません。コードは次のとおりです。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@RefreshScope
public class ConfigController {
    
    
 
    @Value("${username:lily}")
    private String username;
 
    @RequestMapping("/username")
    public String get() {
    
    
        return username;
    }
}

プロジェクト nacos-provider を開始し、ブラウザーで http://127.0.0.1:8084/username にアクセスし、nacos コンソールで構成されたユーザー名の値 zhangsan3 を返します。nacos コンソールでユーザー名の設定を lisi に変更し、nacos-provider プロジェクトを再起動せずに http://127.0.0.1:8084/username に再度アクセスし、変更された値 lisi を返します。これは nacos の設定として表示されます。センターはホットローディング機能を実装しています。

nacos でユーザー名設定を変更する前に戻ります。
ここに画像の説明を挿入

nacos のユーザー名の値を lisi に変更し、再度戻るように要求します。
ここに画像の説明を挿入

注: 一部の高バージョン SpringCloud コンポーネントを使用する場合、nacos 構成クライアント サービスの開始時に bootstrap.yml 構成ファイルが見つからない場合があり、次のエラーが報告されます。システム環境変数で環境変数を構成するだけで済みます。利用可能: spring.cloud.bootstrap.enabled=true

ここに画像の説明を挿入

ここに画像の説明を挿入

4.3.2. 権限認証を有効にする

通常、セキュリティ上の理由から、クライアント サービスは nacos にアクセスするときにユーザー名とパスワードの認証を渡す必要があります。Nacos はデフォルトでは認証を有効にしません。認証を有効にする必要がある場合は、最初に /nacos/conf/application.properties 構成ファイルを編集する必要があります, 以下の図に示すように、nacos.core.auth.enabled=false 設定項目を見つけます。デフォルトは false で、認可認証がオフになっていることを意味します。これを true に変更することで認証を有効にできます。変更が完了したら、すべての nacos インスタンスを再起動する必要があります。

ここに画像の説明を挿入

次の図に示すように、アプリケーション構成ファイルで nacos ユーザー名とパスワードを構成します。まずサービスのユーザー名とパスワードを存在しないユーザーとして構成し、サービスを開始して権限の構成が有効かどうかを確認します。

ここに画像の説明を挿入

サービスを開始した後、コード = 403 および不明なユーザーという例外が報告され、権限の検証が失敗したことが示されました。

ここに画像の説明を挿入

ユーザー名とパスワードを正しいものに変更した後、サービスを再度開始すると、サービスが正常に開始されることがわかります。
ここに画像の説明を挿入

ここに画像の説明を挿入

ここまでで、nacos の権限認証設定が有効になっていることがわかります。

おすすめ

転載: blog.csdn.net/u011397981/article/details/131400168