[SpringCloud-1] 登録センター - Eureka

dubbo の SOA アーキテクチャと比較して、springcloud マイクロサービスはワンストップの完全なソリューションを提供します。つまり、springcloud は他のコンポーネントに依存する必要がなく、従来のプロジェクトが使用する必要があるテクノロジーと問題解決ソリューションの完全なセットを提供します。例えば、dubbo は登録センターとして zk に依存する必要がありますが、springcloud には独自の登録センターがあり、その他にもリンク追跡、サービスのダウングレードなど、あらゆる種類の機能が利用できるため、springcloud ファミリー バケットと呼ばれます。理論的には、通常のプロジェクトには springcloud を使用するだけで十分です。 

ということは、Spring Cloud は完璧だということでしょうか? ダボと比べて誰を選びますか?実際、存在は合理的であり、すべて良いことです。

  • マイクロサービスは短く無駄のないサービスであり、小規模プロジェクト、迅速な開発、立ち上げ、展開に適しています。機能はシンプルであり、プロジェクトは相互に影響を与えることができません。たとえば、私たちは通常、上位レベルのビジネス システムをいくつか作成します。
  • また、マイクロサービス間の呼び出しは http なので、当然パフォーマンスは dubbo の rpc には及びません。大きさがそれほど大きくない場合は問題ありませんが、それ以外の場合はやはり rpc が推奨されます。
  • 実際には、通常は両方の組み合わせです。上位の業務システムは springcloud を、下位のミドルエンドシステムは dubbo を使用します。ミドルエンド システムは通常、比較的大規模で通話量が多いため、安定した機能を提供する必要があります。

ダボの話はやめて、springcloud を見てみましょう。 

まずプロジェクトの構造を構築します。

 上記のように、多くのモジュールは springcloud 全体で学習されるため、最初に親プロジェクトを構築し、親 pom に基本的な依存関係を導入します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lagou.edu</groupId>
    <artifactId>lagou-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>lagou-service-common</module>
        <module>lagou-service-autodeliver-8090</module>
        <module>lagou-service-autodeliver-8091</module>
        <module>lagou-service-resume-8080</module>
        <module>lagou-service-resume-8081</module>
        <module>lagou-cloud-eureka-server-8761</module>
        <module>lagou-cloud-eureka-server-8762</module>
        <module>lagou-cloud-hystrix-dashboard-9000</module>
        <module>lagou-cloud-hystrix-turbine-9001</module>
        <module>lagou-service-autodeliver-8096</module>
        <module>lagou-cloud-configserver-9006</module>
        <module>lagou-cloud-stream-producer-9090</module>
        <module>lagou-cloud-stream-consumer-9091</module>
        <module>lagou-cloud-stream-consumer-9092</module>
    </modules>
    <!--父工程打包方式为pom-->
    <packaging>pom</packaging>

    <!--spring boot 父启动器依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>



    <dependencyManagement>
        <dependencies>
            <!--spring cloud依赖管理,引入了Spring Cloud的版本-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <dependencies>
        <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok工具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <!-- Actuator可以帮助你监控和管理Spring Boot应用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!--eureka server 需要引入Jaxb(JDK9之前可以不引入,默认会加载)-->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.2.10-b140310.1920</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!--引入Jaxb,结束-->


        <!--&lt;!&ndash;spring cloud commons模块引入&ndash;&gt;
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>-->

        <!--链路追踪-->
        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>-->
    </dependencies>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

1: エウレカ ビルド:

登録センターには、主にサーバーとクライアントの 2 つの部分があります。

サーバ側:

Server1 の構成:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>lagou-parent</artifactId>
        <groupId>com.lagou.edu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lagou-cloud-eureka-server-8761</artifactId>

    <dependencies>
        <!--Eureka server依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>
#eureka server服务端口
server:
  port: 8761
spring:
  application:
    name: lagou-cloud-eureka-server # 应用名称,应用名称会在Eureka中作为服务名称

    # eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Client
eureka:
  instance:
    hostname: LagouCloudEurekaServerA  # 当前eureka实例的主机名
  client:
    service-url:
      # 配置客户端所交互的Eureka Server的地址(Eureka Server集群中每一个Server其实相对于其它Server来说都是Client)
      # 集群模式下,defaultZone应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可(这里只是本机测试,最好还是写ip地址)
      defaultZone: http://LagouCloudEurekaServerB:8762/eureka
    register-with-eureka: true  # 集群模式下可以改成true,将自己注册到Eureka Server中
    fetch-registry: true # 集群模式下可以改成true,自己作为客户端,要从Eureka Server获取服务信息,默认为true
  dashboard:
    enabled: true

 Server2 の構成:

#eureka server服务端口
server:
  port: 8762
spring:
  application:
    name: lagou-cloud-eureka-server # 应用名称,应用名称会在Eureka中作为服务名称

    # eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Client
eureka:
  instance:
    hostname: LagouCloudEurekaServerB  # 当前eureka实例的主机名
  client:
    service-url: # 配置客户端所交互的Eureka Server的地址
      defaultZone: http://LagouCloudEurekaServerA:8761/eureka
    register-with-eureka: true
    fetch-registry: true

スタートアップクラス:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
// 声明当前项目为Eureka服务
@EnableEurekaServer
public class LagouEurekaServerApp8761 {

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

クライアント側:

登録センターを用意したら、あとはエウレカをクライアントとしてビジネスサービスを登録するだけです。ビジネス サービスは、サービス プロバイダーとサービス コンシューマーに分かれています。

まず、親プロジェクトの pom にパブリック依存関係を導入します。

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-commons</artifactId>
</dependency>

サービスプロバイダー:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>lagou-parent</artifactId>
        <groupId>com.lagou.edu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lagou-service-resume-8080</artifactId>
    
    <dependencies>
        <!--功能接口:根据用户id查询该用户默认简历的公开状态-->
        <dependency>
            <groupId>com.lagou.edu</groupId>
            <artifactId>lagou-service-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--eureka client 客户端依赖引入-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>


        <!--Config 客户端依赖-->
<!--        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>-->
    </dependencies>
</project>

設定ファイルyml:

server:
  port: 8080
spring:
  application:
    name: lagou-service-resume
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/lagou?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
  jpa:
    database: MySQL
    show-sql: true
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl  #避免将驼峰命名转换为下划线命名
  cloud:
    # config客户端配置,和ConfigServer通信,并告知ConfigServer希望获取的配置信息在哪个文件中
    config:
      name: lagou-service-resume  #配置文件名称
      profile: dev  #后缀名称
      label: master #分支名称
      uri: http://localhost:9006    #ConfigServer配置中心地址
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
#注册到Eureka服务中心
eureka:
  client:
    service-url:
      # 注册到集群,就把多个Eurekaserver地址使用逗号连接起来即可;注册到单实例(非集群模式),那就写一个就ok
      defaultZone: http://LagouCloudEurekaServerA:8761/eureka,http://LagouCloudEurekaServerB:8762/eureka
  instance:
    prefer-ip-address: true  #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
    # 实例名称: 192.168.1.103:lagou-service-resume:8080,我们可以自定义它
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
    # 自定义Eureka元数据
    metadata-map:
      cluster: cl1
      region: rn1
management:
  endpoints:
    web:
      exposure:
        include: "*"

スタートアップクラス:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@SpringBootApplication
@EntityScan("com.lagou.edu.pojo")
//@EnableEurekaClient  // 开启Eureka Client(Eureka独有)
@EnableDiscoveryClient // 开启注册中心客户端 (通用型注解,比如注册到Eureka、Nacos等)
                       // 说明:从SpringCloud的Edgware版本开始,不加注解也ok,但是建议大家加上
public class LagouResumeApplication8080 {

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

}

 サービスプロバイダーは構成されていますが、サービスコンシューマーも同様です。これらはすべて Eureka のクライアント側として使用されるためです。では、消費者はどのようにしてプロバイダーに電話をかけるのでしょうか?

注: 上記の例では、構成ファイルはすべて構成されたホスト名であり、ポートも区別されます。実際のプロジェクトでは必要ありません。コードのセットは異なるサーバー (異なる IP、同じポート) に公開されます。ip:port として構成するだけです。

2:エウレカ詳細:

生データ:

1.標準メタデータ: ホスト名、IPアドレス、ポート番号、およびその他の情報。これらはサービス間の呼び出しのためにサービス レジストリに公開されます。

2. カスタム メタデータ: KEY /VALUEに準拠するeureka.instance.metadata-map構成 を使用できます。
保存形式。これらのメタデータにはリモート クライアントからアクセスできます。に似ている

エウレカクライアント:

サービスプロバイダーでもコンシューマーでも、Eurekaクライアントと呼ばれます。

サービスは登録センターへのリース(ハートビート)を30秒ごとに更新します。更新がない場合、リースは 90 秒後に期限切れとなり、サービスは無効になります。30秒ごとの更新動作をハートビート検出と呼びます。多くの場合、これら 2 つの構成を調整する必要はありません。

さらに、(コンシューマ) サービスが開始されると、サービス リストを取得してローカルにキャッシュし、 その後 30秒ごとに サービスがレジストリから取得されます。この時間は構成によって変更できます。

エウレカサーバー:

オフラインサービス

1 ) サービスが正常にシャットダウンすると、サービスをオフラインにするための RESTリクエストが EurekaServer に送信されます
2 ) リクエストを受信した後、サービスセンターはサービスをオフラインにします。
失敗の拒否
Eureka Server は、インスタンスが特定の時間内にあることが判明した場合、 定期的にチェックします (間隔値は eureka.server.eviction-interval-timer-in-ms 、デフォルトは 60s ) (この値はクライアント eureka.instance によって設定されます)。 .lease -expiration-duration-in-秒の定義、デフォルト値は 90 秒です )、ハートビートが ) 以内に受信されない場合、インスタンスはログアウトされます。

自己防衛メカニズム

eureka-server側で自己保護機構が有効になっている場合、上記の障害解消は行われません。ネットワークの問題 (サービスの利用不能ではない) が原因でハートビート検出が失敗し、インスタンスが誤って削除されるのを防ぎます。実稼働環境を有効にすることをお勧めします。閉じることができます。構成は次のとおりです。

3: ソースコード分析 - 起動プロセス 

1.エウレカの起動プロセス:

エントリ: Spring Cloud は、SpringBootの自動アセンブリ機能を最大限に活用します。eureka-serverjarパッケージを観察しMETA-INFの下に設定ファイル spring.factories があることを確認します

Springboot アプリケーションの起動時に、 EurekaServerAutoConfiguration 自動構成クラスがロードされます。

上記の3つのポイントを踏まえて、詳しく見ていきましょう。

1. Eureka Serverをアセンブルするには マーカー Bean が必要です 。このマーカーは、実際には次のように @EnableEurekaServer アノテーションによって決定されます。

 したがって、@EnableEurekaServer アノテーションが追加された場合にのみ、フォローアップ アクションが行われます。これが EurekaServer になるための前提条件です

2. EurekaServerAutoConfiguration を表示します。これはコア構成クラスであり、いくつかの Bean がアセンブルされています。これらの Bean の役割は次のとおりです。

2 番目のピアツーピア ノード登録は、簡単に理解すると、各サーバー インスタンスをサーバー クラスター内のノードとして登録することです。ノード情報をカプセル化して更新するには、3 番目の Bean PeerEurekaNodes に依存する必要があります。PeerEurekaNodes を詳しく見てみましょう。

 スレッド プールを構築する start メソッドがあり、スレッド タスクが run メソッドを実行すると、更新されたメソッドが実行されます。

スレッドタスクはいつ実行されますか? コア構成クラスに戻ると、DefaultEurekaServerContext と呼ばれる Bean もアセンブルされます。

 アセンブリ プロセス中に、DefaultEurekaServerContextがインスタンス化されると、独自の初期化メソッドが呼び出されます。その中で、PeerEurekaNodes の start メソッドが呼び出されます。

最後に、メイン構成クラスにはさらに 2 つの Bean を確認する必要があります。

3. EurekaServer InitializerConfiguration に注意してください。このクラスは、コア構成クラスで導入された別の構成クラスです。

进⼊EurekaServerBootstrap#contextInitialized

 次に、コンテキストの詳細を入力します。 

実際、主なことは、他のノードの情報を同期し、外部にサービスを提供することです (スケジュールされたタスクを同時に開始し、60 秒ごとに障害の排除を実行します)。 

おすすめ

転載: blog.csdn.net/growing_duck/article/details/130027494