Dubbo、API メソッド、SpringBoot メソッドの詳細な紹介

こんにちは、シェンディです


Dubbo、API メソッド、SpringBoot メソッドの詳細な紹介



これまでは自分で書いた RPC フレームワークを使ってきましたが、それは自分で書いたものであり、その後の Spring Cloud シリーズも含め、市販されているオープンソース フレームワークに比べて機能が劣るからです。統合などを行う必要があり、作業量が膨大です。

ホイールを作らずにホイールは作らないという考えのもと、ダボについて学び始めました



ダボ

Apache Dubbo は、使いやすく高性能な WEB および RPC フレームワークであり、サービス ディスカバリ、トラフィック ガバナンス、可観測性、認証などのエンタープライズ レベルのマイクロサービスを構築するための機能、ツール、ベスト プラクティスも提供します。

Dubbo を使用して開発されたマイクロサービスは、ネイティブのリモート アドレス検出機能と相互通信機能を備えており、Dubbo が提供する豊富なサービス ガバナンス機能を使用して、サービス ディスカバリ、ロード バランシング、トラフィック スケジューリングなどのサービス ガバナンス要求を実現できます。Dubbo は拡張性が高いように設計されており、ユーザーはトラフィックの傍受や場所の選択のためのさまざまなカスタム ロジックを簡単に実装できます。



公式ドキュメント: https://cn.dubbo.apache.org/zh-cn/index.html



RPC、分散、マイクロサービス

ここで簡単に紹介しますと、RPC はリモート プロシージャ コール (Remote Procedure Call) であり、RPC を通じて、プログラムから他のデバイス プログラムの関数を (ネットワーク経由で) 呼び出すことができます。

分散とは、複数のプログラムがネットワークを介して通信してシステムを形成することを意味し、通常は RPC を使用して分散を実現します。

マイクロサービスはプログラムを複数のプログラムに分割し、それらのプログラムは分散方式で通信します。



クイックスタート


飼育員を始める

現在、公式文書ではZookeeperが使用されているため、事前にZookeeperをインストールする必要があります。Zookeeperのインストールと使い方については、こちらの記事を参照してください

Zookeeper のインストールの詳細な紹介、使いやすい



Dubbo API に基づいたマイクロサービス アプリケーションの開発

任意の Maven プロジェクト、pom.xml次のコンテンツを編集して追加します

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>3.2.0-beta.4</version>
</dependency>

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-x-discovery</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.8.0</version>
    <exclusions>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-handler</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-epoll</artifactId>
        </exclusion>
    </exclusions>
</dependency>


注: 依存パッケージのほとんどは org.apache.dubbo を使用します。


サービスプロバイダー

2 つの新しいパッケージ (サービス インターフェイス定義を含む 1 つの API と、サービス インターフェイスの特定の実装を含む 1 つのプロバイダー) を作成します。

API パッケージの下に新しいインターフェイスを作成します。内容は次のとおりです

public interface ITest {
    
    

	String sayHi(String name);
	
}

このインターフェイスを実装するためにプロバイダー パッケージに新しいクラスを作成し、サーバーを公開します。内容は次のとおりです。

import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import demo.api.ITest;

public class Test implements ITest {
    
    

	public static void main(String[] args) {
    
    
		// 定义具体的服务
        ServiceConfig<ITest> service = new ServiceConfig<>();
        service.setInterface(ITest.class);
        service.setRef(new Test());

        // 启动 Dubbo
        DubboBootstrap.getInstance()
                .application("first-dubbo-provider")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .protocol(new ProtocolConfig("dubbo", -1))
                .service(service)
                .start()
                .await();
	}

	public String sayHi(String name) {
    
    
		return "hi, " + name;
	}
	
}

上記のzookeeperはzookeeperのアドレスです。ポートの上の文字列が変更されている場合は、それに応じて変更する必要があります。

これでサービスプロバイダーを起動できるようになり、起動後にコンソールに多くの情報が出力されます。

しばらくお待ちください。以下のような情報が表示されれば起動成功です。

セッション ID に対する ping 応答を受け取りました:…

ここに画像の説明を挿入


これは常時出力される、ZKのハートビート機構ログです

上記で実装された関数を簡単に説明します。これは、sayHi インターフェイスを提供するのと同じです。インターフェイスは、name パラメーターを受け取り、文字列を返します。文字列の内容は、hi、+ 渡された name パラメーターです。



サービス消費者

clientクライアント (コンシューマ) を格納するための新しいパッケージを作成する

パッケージの下に新しいクラス Test2 を作成して、提供されたサービスをサブスクライブし、呼び出します

内容は以下の通りです

import java.io.IOException;

import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;

import com.alibaba.dubbo.config.ReferenceConfig;

import demo.api.ITest;

public class Test2 {
    
    

	public static void main(String[] args) throws IOException {
    
    
		ReferenceConfig<ITest> reference = new ReferenceConfig<>();
        reference.setInterface(ITest.class);

        DubboBootstrap.getInstance()
                .application("first-dubbo-consumer")
                .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
                .reference(reference);
        
        ITest service = reference.get();
        String message = service.sayHi("dubbo");
        System.out.println("Receive result ======> " + message);
        System.in.read();
	}
	
}

実行すると多くの情報が出力され、最終的に以下の情報が確認できます

ここに画像の説明を挿入


上記のコードによれば、サービスディスカバリによる単純な RPC 呼び出しが実装されていますが、コードは単純で、基本的には一目で何を意味するのかがわかります。



SpringBoot に基づいたマイクロサービス アプリケーションを開発する

API開発と似ていますが、SpringBootはアノテーションベースの設定方法が特徴で、迅速な開発が可能です。

公式ウェブサイトの例は Maven マルチモジュールの使用であり、それぞれ 3 つのモジュールがあります

  1. インターフェース
  2. プロバイダー
  3. 消費者

上記では、プロバイダーとコンシューマーの両方がインターフェース部分を定義する必要があり、プロバイダーがインターフェースを実装し、コンシューマーがインターフェースを使用することがわかりました。インターフェース部分を共有するには、公式サンプルで使用されているマルチモジュールが必要です。


公式サンプルで使用されているIDEA、Eclipseプロセスをここにリストします

(もちろん、複数のモジュールを使用しないことも可能ですし、1つのプロジェクトや2つのプロジェクトに分割することも可能です)

新しい Maven プロジェクトを作成し、Packaging に pom を選択し、次の依存関係を pom.xml に追加します。

	<properties>
        <dubbo.version>3.2.0-beta.4</dubbo.version>
        <spring-boot.version>2.7.8</spring-boot.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </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>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

次に、3 つの新しいモジュールを作成します。

  • デモコンシューマー (消費者)
  • デモプロバイダー (プロバイダー)
  • デモインターフェース (共有インターフェース)

プロジェクトを右クリック -> 新規 -> その他 -> Maven -> Maven モジュール

ここに画像の説明を挿入


パッケージ化ではjarを選択し、モジュールを作成します

デモプロバイダーとデモコンシューマーの pom.xml コンテンツを変更し、SpringBoot に必要なコンテンツをコピーして、次の依存関係を追加します。

	<dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-samples-spring-boot-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- spring boot starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

上記の依存関係に加えて、共通部分であるdemo-interfaceも導入する必要があります。

<dependency>
    <groupId>demo-interface</groupId>
    <artifactId>demo-interface</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

プロジェクトの写真を投稿する

ここに画像の説明を挿入


共通部分(デモインターフェース)

このdemo-interfaceモジュールは共通部分で、src/main/java配下にdemoという名前の新しいパッケージを作成し、その配下にServiceという名前の新しいインターフェイスを作成します。

プロバイダコンシューマが使用する動作はServiceで定義されており、その内容は次のとおりです

ここに画像の説明を挿入


このモジュールはインターフェイスを作成するだけでよいため、pom は基本的に依存関係を導入する必要はありません。



サービスプロバイダー (デモプロバイダー)

前述のように、プロバイダーと消費者の両方が共通の部分を導入する必要がある

デモプロバイダーモジュールはプロバイダーであり、demo.provider という名前の新しいパッケージを作成し、そのパッケージの下に ServerImpl という名前の新しいクラスを作成します。

ServerImplは、共通部分(インターフェース)が提供するインターフェースServiceを以下のように実装します。

package demo.provider;

import org.apache.dubbo.config.annotation.DubboService;

import demo.Service;

@DubboService
public class ServiceImpl implements Service {
    
    

	@Override
	public String sayHi(String name) {
    
    
		return "hi, " + name;
	}

}

API ベースの開発との違いは、クラスに追加の@DubboServiceアノテーションがあることです。

@DubboService アノテーションは、サービス プロバイダー インターフェイスをマークするために使用されるアノテーションです。このアノテーションの機能は、インターフェイスを Dubbo サービス プロバイダーとしてマークし、インターフェイスの実装クラスを他のサービスから呼び出せるサービスとして Dubbo によって登録および公開できるようにすることです。@DubboService アノテーションでマークされたインターフェイス実装クラスは、Dubbo フレームワークによってスキャンされ、対応するサービス インターフェイス プロキシ オブジェクトが自動的に生成され、他のサービス コンシューマが呼び出せるように Dubbo レジストリに登録されます。このアノテーションを使用すると、Dubbo サービスの公開および公開の手順が簡素化され、開発効率が向上します。


ProviderApplication次に、次の内容でSpringBoot スタートアップ クラスを作成します。

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(ProviderApplication.class, args);
	}
	
}

注釈が追加されました@EnableDubbo。試してみたところ、この注釈はなくても問題ありませんでした(ただし、他の問題を避けるために追加した方がよいです)


SpringBoot の設定ファイルを変更します。Maven プロジェクトを作成したので、src/main/resources の下に新しい application.properties または application.yml を作成する必要があります。

プロパティ

dubbo.application.name=demo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.registry.address=zookeeper://${zookeeper.address:127.0.0.1}:2181

yml

dubbo:
  application:
    name: dubbo-springboot-demo-provider
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${
    
    zookeeper.address:127.0.0.1}:2181

このように、サービスプロバイダーは良い仕事をします



サービス消費者 (デモ消費者)

demo-consumer はコンシューマモジュールで、新しいパッケージdemo.consumerを作成し、そのパッケージの下にスタートアップクラスConsumerApplicationを作成します。内容は次のとおりです。

package demo.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(ConsumerApplication.class, args);
	}
	
}

ここでは Web インターフェイスを記述する必要があるため、pom.xml に Web 依存関係を追加する必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


次の内容を含む TestControl という名前の新しいクラスを作成します。

package demo.consumer;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import demo.Service;

@RestController
public class TestControl {
    
    

	@DubboReference
    private Service service;
	
	@GetMapping("/")
	public String test(String name) {
    
    
		return service.sayHi(name);
	}
	
}

Web インターフェイスは上記で定義されており、ルートは で/、インターフェイスはパラメーター名を受け取り、インターフェイスはサービス量の SayHi 関数を呼び出し、名前パラメーターが渡されます。

ここのサービスは@DubboReferenceアノテーションインジェクションを使用しており、sayHiの呼び出しは実際にはdemo-providerの実装クラスのsayHiの呼び出しと同等です。


ここで原理を理解するつもりはありませんが、少し推測してください。私の考えによれば、大まかに言うと、プロバイダーとコンシューマが動物園の飼育員に接続し、コンシューマは動物園の飼育員を介してプロバイダーと通信し、コンシューマは@DubboReference によって注入されたオブジェクト。RPC がプロバイダーにデータを送信すると推測します。たとえば、クラスが Service で関数がsayHi の場合、Service|sayHi を送信します。データを受信した後、プロバイダーは対応する実装クラスを見つけます。実装クラスの関数を実装し、返されたデータを実行するだけで、残りはパラメータなどの詳細です。もちろん、ここではそのようなフレームワークを実装するために私のアイデアを使用し、簡単なアイデアを提供しているだけです。詳細を知るには、ソース コード、ドキュメント、デバッグを参照する必要があります。


SpringBoot設定ファイルはプロバイダーと同じですが、Webポートを設定するにはserver.portが必要です

このように、消費者も良い仕事をしています


アノテーションではなくコンテキストを通じてサービスを取得する

ここでそれを拡張しましょう。オブジェクトの挿入にアノテーションを使用できない場合があります。このときは、他の方法でプロバイダー オブジェクトを取得する必要があります。

次のようにコードを取得します

ReferenceConfig<Service> referenceConfig = new ReferenceConfig<>();
referenceConfig.setInterface(Service.class);
Service service = referenceConfig.get();


アプリケーションを開始する

走っProviderApplicationて、ConsumerApplication


コンシューマを開始する前にプロバイダを開始する必要があることに注意してください。そうしないと、コンシューマ モジュールがエラーを報告し、プログラム全体が終了してしまいます。この問題は@DubboReferenceアノテーションによるもので、デフォルトでは起動時に該当プロバイダが利用可能かどうかチェックするようになっていますが、もちろん設定等でチェックを解除することも可能です。

解決策はいくつかあります

  1. たとえば、パラメータ check = false を注釈に追加します。@DubboReference(check = false)

  2. SpringBoot 構成ファイルにコンテンツを追加する

    • 特性が増加するdubbo.consumer.check=false

    • ymlの増加

    •   dubbo:
          consumer:
            check: false
      
  3. スタートアップ クラスまたは構成クラスに次のコードを追加します。

    •   @Bean
        public ConsumerConfig consumerConfig() {
              
              
            ConsumerConfig consumerConfig = new ConsumerConfig();
            consumerConfig.setCheck(false);
            return consumerConfig;
        }
      

開始後、コンシューマ サービスでいくつかのエラーが爆発しますが、影響はありません。ブラウザを通じてアドレスにアクセスすると、効果は次のとおりです。

ここに画像の説明を挿入


問題が解決しました

[DUBBO] qos-server can not bind localhost:22222, dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind
...

Fail to start qos server: , dubbo version: 3.2.0-beta.4, current host: 192.168.0.108, error code: 7-4. This may be caused by , go to https://dubbo.apache.org/faq/7/4 to find instructions. 

java.net.BindException: Address already in use: bind

このエラーは、Qos サービスのポートが占有されていることを意味します。QOS サーバーは、Dubbo で起動すると自動的に起動されるためです。デフォルトのポートは 22222 です。上記の同じコンピューター上でプロバイダーとコンシューマーを起動したため、このエラーを報告しました。

Dubbo の QoS (Quality of Service) サーバーは独立したサーバーであり、Dubbo サービスの品質保証を提供し、サービス関連の指標を監視および管理するために使用されます。

SpringBoot設定ファイルを変更することで解決できます

プロパティ

# 是否启用,默认启用
dubbo.application.qosEnable=true
# 端口,默认22222
dubbo.application.qosPort=12345
dubbo.application.qosAcceptForeignIp=false


今のところ、基本的な使い方は問題ありません




終わり

おすすめ

転載: blog.csdn.net/qq_41806966/article/details/131589154