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,结束-->
<!--<!–spring cloud commons模块引入–>
<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-serverのjarパッケージを観察し、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 秒ごとに障害の排除を実行します)。