Eureka-服务治理
单体应用存在的问题
- 随着业务的发展,开发变得越来越复杂。
- 修改、新增某个功能,需要对整个系统进行测试、重新部署。
- 一个模块出现问题,很可能导致整个系统崩溃。
- 多个开发团队同时对数据进行管理,容易产生安全漏洞。
- 各个模块使用同一种技术进行开发,各个模块很难根据实际情况选择更合适的技术框架,局限性很大。
- 模块内容过于复杂,如果员工离职,可能需要很长时间才能完成工作交接。
分布式&集群
- 集群:一台服务器无法负荷高并发的数据访问量,那么就设置十台服务器一起分担压力,十台不行就设置一百台(物理层面)。很多人干同一件事情,来分摊压力。
- 分布式:将一个复杂问题拆分成若干个简单的小问题,将一个大型的项目架构拆分成若干个微服务来协同完成。(软件设计层面)。将一个庞大的工作拆分成若干个小步骤,分别由不同的人完成这些小步骤,最终将所有的结果进行整合实现大的需求。
服务治理
- 服务治理的核心又三部分组成:服务提供者、服务消费者、注册中心。
- 在分布式系统架构中,每个微服务在启动时,将自己的信息存储在注册中心,叫做服务注册。
- 服务消费者从注册中心获取服务提供者的网络信息,通过该信息调用服务,叫做服务发现。
服务注册中心
- 分布式微服务架构中,服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,
- 消费者通过主动查询和被动通知的方式获取服务提供者的地址信息,而不再需要通过硬编码方式得到提供者的地址信。
- 消费者只需要知道当前系统发布了那些服务,不需要知道服务具体存在于什么位置,这就是透明化路由。
启动服务提供者
服务提供者将相关服务信息主动注册到注册中心
服务消费者获取服务注册信息
pull模式:服务消费者可以主动拉取可用的服务提供者清单
push模式:服务消费者订阅服务(当服务提供者有变化时,注册中心也会主动推送更新后的服务清单给消费者
服务消费者通过注册信息直接调用服务提供者
注册中心也需要完成服务提供者的健康监控,当发现服务提供者失效时需要及时剔除;
主流服务中心对比
- Zookeeper 存储+监听通知
- Eureka 服务注册与发现组件
- Consul 分布式高可用的服务 发布和注册服务软件
- Nacos 注册中心 + 配置中心的组合
服务注册中心组件Eureka
Eureka 交互流程及原理
Eureka 包含两个组件:Eureka Server 和 Eureka Client
- Eureka Client是一个Java客户端,用于简化与Eureka Server的交互;
- Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server 进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息;
注:Eureka通过心跳检测、健康检查和客户端缓存等机制,提高系统的灵活性、可伸缩性和可用性。
图中us-east-1c、us-east-1d,us-east-1e代表不同的区也就是不同的机房
图中每一个Eureka Server都是一个集群。
图中Application Service作为服务提供者,向Eureka Server中注册服务,Eureka Server接受到注册事件会在集群和分区中进行数据同步,ApplicationClient作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信息,进行服务调用。
微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息
Eureka Server在一定时间内没有接收到某个微服务节点的心跳,EurekaServer将会注销该微服务节点(默认90秒)
每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册列表的同步
Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者
单例Eureka Server搭建
Boot与Cloud版本的说明:https://start.spring.io/actuator/info
1
2
3
4
5
6
7
8
9"spring-cloud": {
"Hoxton.SR11": "Spring Boot >=2.2.0.RELEASE and <2.3.999.BUILD-SNAPSHOT",
"Hoxton.BUILD-SNAPSHOT": "Spring Boot >=2.3.999.BUILD-SNAPSHOT and <2.4.0.M1",
"2020.0.0-M3": "Spring Boot >=2.4.0.M1 and <=2.4.0.M1",
"2020.0.0-M4": "Spring Boot >=2.4.0.M2 and <=2.4.0-M3",
"2020.0.0": "Spring Boot >=2.4.0.M4 and <=2.4.0",
"2020.0.3": "Spring Boot >=2.4.1 and <2.5.3-SNAPSHOT",
"2020.0.4-SNAPSHOT": "Spring Boot >=2.5.3-SNAPSHOT"
},
父工程
在父的pom中添加Spring Cloud 依赖
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<!--spring boot 父启动器依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.8</version>
<type>pom</type>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<spring-boot.version>2.4.8.RELEASE</spring-boot.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
<lombok.version>1.18.20</lombok.version>
<jaxb.version>2.3.0</jaxb.version>
</properties>
<dependencyManagement>
<dependencies>
<!--spring cloud依赖管理,引入了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>
</dependencies>
</dependencyManagement>JDK9以上缺失的依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<!--因为Jdk9之后默认没有加载jaxb该模块,EurekaServer使用到,所以需要手动导入,否则EurekaServer服务无法启动-->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!--引入Jaxb,结束-->添加模块常用的依赖
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<!--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>${lombok.version}</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>build工具
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>指定从aliyun上下载jar包
1
2
3
4
5
6
7
8
9
10
11
12
13
14<repositories><!-- 代码库 -->
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>完整pom.xml
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<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>org.example</groupId>
<artifactId>springcloud-study</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eureka-server-8761</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<spring-boot.version>2.4.8</spring-boot.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
<lombok.version>1.18.20</lombok.version>
<jaxb.version>2.3.0</jaxb.version>
<swagger.version>2.6.1</swagger.version>
<pagehelper.version>4.2.1</pagehelper.version>
<druid.version>1.1.10</druid.version>
<fastjson.version>1.2.62</fastjson.version>
<mybatis.version>3.4.6</mybatis.version>
</properties>
<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>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- Actuator可以帮助你监控和管理Spring Boot应用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<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依赖管理,引入了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>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<repositories><!-- 代码库 -->
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</build>
</project>
Eureka Server代码实现
添加依赖
创建子项目eureka-server-8761
pom.xml中引入Eureka server依赖
1
2
3
4
5<!--Eureka server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
修改配置文件
- application.yml添加 Eureka Server 相关配置。
1 | #eureka server服务端口 |
创建启动类
在SpringBoot启动类上面,使用
@EnableEurekaServer
声明当前项目为EurekaServer服务,提供服务注册和服务发现功能,即注册中心。1
2
3
4
5
6
7
8
9// 声明本项目是一个Eureka服务
public class EurekaServerA {
public static void main(String[] args) {
SpringApplication.run(EurekaServerA.class, args);
}
}启动项目后,访问 http://localhsot:8761/,可以看到如下的信息面板,其中 Instances currently registered with Eureka 栏是空的,说明该注册中心中还没有注册任何服务
注册服务到Eureka Server
建立子项目简历微服务,名称是service-resume-8080
简历服务部署两个实例,分别占用8080、8081端⼝
父工程中引入spring-cloud-commons依赖
1
2
3
4<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>子项目中引入eureka client的相关坐标
1
2
3
4
5<!--eureka client 客户端依赖引入-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>配置application.yml文件
在application.yml 中添加Eureka Server高可用集群的地址及相关配置
自定义实例(instance-id)的显示格式,加上版本号,便于多版本管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18server:
port: 8080
spring:
application:
name: service-resume-8080 # 应用名称,应用名称会在Eureka中作为服务名称
# eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Clien
eureka:
instance:
hostname: localhost # 当前eureka实例的主机名
prefer-ip-address: true #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
# 可以自定义实例名称: 192.168.1.103: service-resume-8080:8080,我们
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
client:
service-url:
# 配置客户端所交互的Eureka Server的访问地址
defaultZone: http://localhost:8761/eureka/
dashboard:
enabled: true
启动SpringBoot项目,再次访问Eureka的信息面板, 可以看到我们注册的实例
1
2
3
4
5
6
7
public class ResumeApplication {
public static void main(String[] args) {
SpringApplication.run(ResumeApplication.class, args);
}
}
高可用注册中心搭建
在微服务架构的分布式环境下,需要充分考虑到发生故障的情况,在生产环境中必须对给个组件进行高可用部署,注册中心也是一样,在生产环境中使用单节点显得并不是很合适,Eureka Serverde设计的时候就考虑了高可用的问题,在Eurek的服务治理中,所有的节点既是服务提供者,也是服务消费者。
Eureka的高可用实际上就是将自己作为服务向其他的注册中心注册自己,形成一组互相注册的服务注册中心,实现服务清单的互相同步。
接下来在单节点的基础上搭建双节点的服务注册中心集群。
修改hosts文件
linux是
/etc/hosts
,windows在C:\Windows\System32\drivers\etc\hosts
1
2127.0.0.1 EurekaServerA
127.0.0.1 EurekaServerB可以ping命令测试 EurekaServerA,EurekaServerB的连通性
配置文件
复制二份eureka-server-8761的配置文件
application-A|B.yml
application-A.yml 作为EurekaServerA注册中心的配置文件,application-B.yml 作为EurekaServerB注册中心的配置文件,
修改A,B配置中的hostname,将service-url指向非自身的注册中心,register-with-eureka和fetch-registry改为true
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#eureka serverA服务端口
server:
port: 8761
spring:
application:
name: eureka-server # 应用名称,应用名称会在Eureka中作为服务名称
# eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Clien
eureka:
instance:
hostname: EurekaServerA # 当前eureka实例的主机名
client:
service-url:
# 配置客户端所交互的Eureka Server的地址
#(Eureka Server集群中每一个Server其实相对于其它Server来说都是Client)
# 集群模式下,defaultZone应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可
defaultZone: http://EurekaServerB:8762/eureka/
register-with-eureka: true # 单例是false,集群模式下改成 true
fetch-registry: true # 集群模式下可以改成true
##单例模式下自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false
##集群模式下,就需要改为true,从集群上获取信息
dashboard:
enabled: true
#eureka serverB服务端口
server:
port: 8762
spring:
application:
name: eureka-server # 应用名称,应用名称会在Eureka中作为服务名称
# eureka 客户端配置(和Server交互),Eureka Server 其实也是一个Clien
eureka:
instance:
hostname: EurekaServerB # 当前eureka实例的主机名
client:
service-url:
# 配置客户端所交互的Eureka Server的地址
#(Eureka Server集群中每一个Server其实相对于其它Server来说都是Client)
# 集群模式下,defaultZone应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可
defaultZone: http://EurekaServerA:8761/eureka/
register-with-eureka: true # 单例是false,集群模式下改成true
fetch-registry: true # 集群模式下可以改成true
##单例模式下自己就是服务不需要从Eureka Server获取服务信息,默认为true,置为false
##集群模式下,就需要改为true,从集群上获取信息
dashboard:
enabled: true
启动二个服务
application.yml 配置文件中指定环境
1
2
3spring:
profiles:
active: A我想使用双节点的注册中心,每次执行修改配置文件不太好,可以复制EurekaServerA的配置,然后可以通过命令行指定VM参数实现切换
-Dspring.profiles.active
也可以在父工程中配置profiles,避免添加环境变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<profiles>
<profile>
<!-- 开发环境A -->
<id>A</id>
<activation>
<!-- 默认开发环境 -->
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<activatedProperties>A</activatedProperties>
</properties>
</profile>
<profile>
<!-- 开发环境B -->
<id>B</id>
<properties>
<activatedProperties>B</activatedProperties>
</properties>
</profile>
</profiles>在子项目中使用profiles的属性
1
2
3spring:
profiles:
active: @activatedProperties@子项目的pom文件中添加参数保证profiles的属性能成功读取
1
2
3
4
5
6
7
8<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>那么切换配置的时候,选择我门想要的环境,直接运行就可以运行了
观察信息
在启动二个Eureka服务后,访问 http://127.0.0.1:8761/ 和 http://127.0.0.1:8762/,从信息面板中我们会看到eureka-server的实例变成2个,也可以看到备份信息
自我保护
手动结束掉EurekB的服务后,查看面板信息,发现触发了自我保护机制,如果renews(last min) < renews threshold 就会激活自我保护模式
关闭自我保护
修改注册中心的配置文件
1
2
3
4
5
6eureka:
server:
# 关闭自我保护机制(生产环境推荐打开)
enable-self-preservation: false
# 如过2秒类没有收到微服务心跳,就剔除该服务,单位毫秒
eviction-interval-timer-in-ms: 2000客户端的配置
1
2
3
4
5
6eureka:
instance:
# eureka客户端发送心跳的间隔时间设置为1s,单位秒,默认30s
lease-renewal-interval-in-seconds: 1
# eureka客户端接收到心跳后等待时间上限是2s,默认90秒,超时3次就会剔除该服务
lease-expiration-duration-in-seconds: 2手动停止ServerB后
注册服务到集群
在上面的项目上进行修改
service-url指定多个Eurekaserver地址
1 | eureka: |
启动类添加注解
EnableDiscoveryClient
@EnableDiscoveryClient
和@EnableEurekaClient
⼆者的功能是一样的@EnableEurekaClient
开启Eureka Client(Eureka独有)@EnableDiscoveryClient
: 开启注册中心客户端 (通用型注解,比如注册到Eureka、Nacos等)- 说明:从SpringCloud的Edgware版本开始,不加注解也ok,但是建议大家加上
1
2
3
4
5
6
7
8
// 开启服务发现
public class ResumeApplication {
public static void main(String[] args) {
SpringApplication.run(ResumeApplication.class, args);
}
}
提供服务接口
编写服务API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class HelloController {
public Map<String, Object> hello( { String name)
Map<String, Object> map = new HashMap<>();
if (StringUtils.isEmpty(name)) {
map.put("message", "hello, I am resume server.");
} else {
map.put("message", name);
}
return map;
}
}
通过Eureka调用服务提供者
建立子项目作为微服务消费者 service-autodeliver-8090
引入eureka client 客户端依赖
1
2
3
4
5<!--eureka client 客户端依赖引入-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置application.yml文件
指定Eureka的地址,应用名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16server:
port: 8090
spring:
application:
name: service-autodeliver # 应用名称,应用名称会在Eureka中作为服务名称
#注册到Eureka服务中心
eureka:
client:
service-url:
# 注册到集群,就把多个Eurekaserver地址使用逗号连接起来即可;注册到单实例(非集群模式),那就写一个就ok
defaultZone:
- http://EurekaServerA:8761/eureka/
- http://EurekaServerB:8762/eureka/ instance:
prefer-ip-address: true #服务实例中显示ip,而不是显示主机名(兼容老的eureka版本)
# 实例名称: 192.168.1.103:service-autodeliver:8080,我们可以自定义它
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
启动类添加注解
启动类如下
1
2
3
4
5
6
7
8
9
// 开启服务发现
public class AutodeliverApplication8090 {
public static void main(String[] args) {
SpringApplication.run(AutodeliverApplication8090.class, args);
}
}
调用服务提供者
配置restTemplate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class RestTemplateConfig {
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
/** 读超时单位为ms */
factory.setReadTimeout(10000);
/** 连接超时单位为ms */
factory.setConnectTimeout(10000);
return factory;
}
}编写controller层
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
35import org.springframework.cloud.client.discovery.DiscoveryClient;
public class AutodeliverController {
private RestTemplate restTemplate;
private DiscoveryClient discoveryClient;
/**
* 服务注册到Eureka之后的改造
*
* @param userId
* @return
*/
public Map findResumeOpenState( { Long userId)
// TODO 从Eureka Server中获取我们关注的那个服务的实例信息以及接口信息
// 1、从 Eureka Server中获取lagou-service-resume服务的实例信息(使用客户端对象做这件事)
List<ServiceInstance> instances = discoveryClient.getInstances("service-resume-8080");
// 2、如果有多个实例,选择一个使用(负载均衡的过程)
ServiceInstance serviceInstance = instances.get(0);
// 3、从元数据信息获取host port 拼接请求地址
String host = serviceInstance.getHost();
int port = serviceInstance.getPort();
String url = "http://" + host + ":" + port + "/hello/" + userId;
System.out.println("===============>>>从EurekaServer集群获取服务实例拼接的url:" + url);
// 4、消费者之间调用服务提供者
// 调用远程服务—> 简历微服务接口 RestTemplate -> JdbcTempate
// httpclient封装好多内容进行远程调用
Map forObject = restTemplate.getForObject(url, Map.class);
return forObject;
}
}