Spring Cloud系列之服务注册与发现(二)
鉴于上篇初识(一)引入如下思考:
如果每个组件的服务分布在不同的节点,那么通过每次的硬编码去实现域名(服务识别)解析是多么痛苦的一件事,况且还没有涉及到服务的主动发现。这个时候我们急需引用一种方案来解决此问题,那么此阶段我将引入 EureKa 的应用。而在 Dubbo 体系中是通过 Zookeeper 集群来实现服务注册与发现的,后续有机会将会对 Dubbo 做学习与分析。
Eureka 架构
通过架构图我们会发现实际上 Eureka 包含两个组件:Eureka Server 和 Eureka Client,它们的作用如下:
- Eureka Server 提供服务发现的能力(这种能力个人理解是被动的),即各个微服务启动的时候会主动向 Server 注册自己的信息(例如IP、端口、微服务名称等)
- Eureka Client 则是一个客户端,与 Eureka Server 进行交互
- 微服务启动后会周期性的(默认为30s)向 Server 端发送心跳,以证明自己是存活状态,以此“续约”租期
- 如果 Server 端在一定时间内未接收到某个微服务发送的心跳,则 Server 会注销该实例(默认为90s)。【拓展:没有收到心跳可能有多种原因引起的,在业务上可能由于网络抖动或者瞬时高峰引起的问题,面对这种现象实际上在架构时就应该考虑,后面我会做进一步的学习分享。】
- 默认情况下,Eureka Server 同时也是 Eureka Client,当时这是配置可控的。多个 Eureka Server 实例之间会通过复制来实现服务注册表中的数据同步。
- Eureka Client 会缓存服务注册表中的信息。这样有利于减轻对 Server 端的压力,而且即使短暂的 Server 端宕掉或者出现问题,Client 也可以通过缓存数据完成调用。
以下我会根据系列(一)的文章进行拓展,在原来的基础上进行拓展,整体工程组织如下图:
比系列文章(一)多了 Server 服务。
Eureka Server
microservice-discover-eureka
pom
文件如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kirago.sc</groupId>
<artifactId>microservice-discovery-eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>microservice-discovery-eureka</name>
<description>microservice-discovery-eureka project for Spring cloud</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-test</artifactId>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>- 启动类通过注解 @EnableEurekaServer 声明为此应用为 Eureka Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package com.kirago.sc.microservicediscoveryeureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class MicroserviceDiscoveryEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceDiscoveryEurekaApplication.class, args);
}
} - application.yaml 配置文件如下:这样 Eureka Server 就算是配置好了,如果运行没有问题,我们会嗨皮的发现如下的页面:
1
2
3
4
5
6
7
8server:
port: 8000
eureka:
client:
register-with-eureka: false #标识是否将自己注册到 Eureka Server 中,默认为 true。
fetch-registry: false #表示是否从 Eureka Server 获取注册信息,默认为 true,由于此 demo 为单点 Server,不需要同步其他的 Server,故配置为 false
service-url:
defaultZone: http://localhost:8000/eureka/ #设置与 Eureka Server 交互的地址,默认端口为 8761,这里先卖个关子,就是某些配置问题或者再导入已有项目的时候尤其是如 IDEA 这种工具如果配置没做好的话就会引用默认端口,而没法示例化自己配置的端口,反正我是遇到。
这个时候我们下一步需要做的就是将 Eureka Client 注册到 Eureka Client 中了,话不多说,直接撸起来。
服务提供者微服务
microservice-provider-user
pom
文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kirago.sc</groupId>
<artifactId>microservice-provider-user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>microservice-provider-user</name>
<description>microservice-provider-user project for Spring cloud</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>application.yaml
文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40spring:
application:
name: microservice-provider-user #用于指定注册到 Eureka Server 上的应用名称
jpa:
generate-ddl: false
show-sql: true
hibernate:
ddl-auto: update
datasource:
platform: h2
schema: classpath:sql/schema.sql
data: classpath:sql/data.sql
url: jdbc:h2:mem:dbtest
username: root
password: root
driver-class-name: org.h2.Driver
h2:
console:
settings:
web-allow-others: true
path: /h2
enabled: true
logging:
level:
root: INFO
org.hibernate: INFO
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka/
instance:
perfer-ip-address: true #表示将自己的 IP 注册到 Eureka Server
server:
port: 8001- 编写启动类:
1
2
3
4
5
6
7
8
9
10
11
12package com.kirago.sc.microserviceprovideruser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MicroserviceProviderUserApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceProviderUserApplication.class, args);
}
}服务消费者微服务
microservice-consumer-movie
同理我们也需将服务消费者注册到 Eureka Server 中。具体实现就不写了,后面我会在文章的末尾处附上本人 github 上的代码链接。由于是 demo ,在其中 controller 层中,我就直接做了硬编码处理。 - 单独测试
microservice-provider-user
微服务接口如下: - 通过
microservice-consumer-movie
微服务接口如下:
在这里留个思考题,就是上面有解释到 Eureka Server 其实是可以做多副本高可用的,那么可以拓展了解下如何去做配置,还有一般来说 Eureka 在实际的场景中也是需要通过用户认证访问,这些其实在前期都是需要考虑的,有兴趣的可以拓展了解下
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 kirago杂谈!