本期目录
- 1. Eureka介绍
- 1.1 Eureka能解决的问题
- 2. Eureka原理
- 3. 搭建Eureka Server
- 3.1 引入依赖
- 3.2 编写启动类
- 3.3 修改配置文件
- 3.4 启动Eureka微服务
- 4. 服务注册
- 4.1 导入依赖
- 4.2 修改配置文件
- 4.3 重启微服务
- 4.4 启动多个微服务实例
- 5. 服务发现
- 5.1 修改业务层代码
- 5.2 在RestTemplate上添加负载均衡注解
- 5.3 重启OrderApplication
1. Eureka介绍
- Eureka 是 Spring Cloud 中的一个组件,主要是作为注册中心。
1.1 Eureka能解决的问题
- 服务注册
- 服务发现:服务消费者如何获取服务提供者的地址信息?
- 负载均衡:如果有多个服务提供者,消费者应该和选择?
- 健康检测:消费者如何得知服务提供者的健康状态?
- 以上都是 Eureka 能家具的问题。
2. Eureka原理
- Eureka 是 C/S 架构。自己本身是 Server 服务端,而微服务容器实例都是客户端。
- 每一个微服务容器实例启动的那一刻,都会把自己的信息 (微服务名称、IP 、端口) 注册给 Eureka 。
- 此时,如果有微服务想要远程调用其他微服务,就去找 Eureka 注册中心,Eureka 查询注册列表,如果有,就把对于的微服务信息发送给消费者。
- 消费者拿到多个提供者实例列表,就要从中挑选一个实例作为提供者,这时会采用负载均衡策略来挑选。
- 挑选出来一个提供者后,就向这个提供者发起远程调用。
- 如何保证服务提供者是健康的呢?在 Eureka 注册的微服务实例,每隔 30 秒都会向 Eureka 发送一次心跳续约,来确认自己的健康状态。如果有一天,Eureka 没有收到某个微服务实例的心跳,就会把它从注册列表中剔除掉。这样,消费者向 Eureka 拉取注册列表时,就不会拉取到宕机的微服务信息了。
3. 搭建Eureka Server
3.1 引入依赖
-
创建新的微服务,这个微服务就是专门用来做 Eureka 的服务端。
-
这个微服务命名为
eureka-server
,选择 Maven 工程。 -
创建完成后,在
eureka-server
微服务的pom.xml
文件中引入 spring-cloud-starter-netflix-eureka-server 的 Maven 坐标。 -
这个依赖中,Spring 已经把 Eureka 自动装配,几乎可以做到零配置直接用。
<!-- Eureka注册中心服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
-
可以看到,导入 Eureka 的 Maven 坐标时,并没有指定其版本。这是在 Spring Boot 中学过的内容。这是因为在
eureka-server
微服务的父工程 (cloud-demo) 中,已经把所有依赖的版本都管理好了。我们可以打开父工程cloud-demo
的pom.xml
文件,可以看到在<parent>
标签下有spring-boot-starter-parent
:也可以在
<properties>
标签下看到 Spring Cloud 的版本:在
<denpendencies>
标签下,可以看到 Spring Cloud 的依赖:点进【
<artifactId>spring-cloud-dependencies</artifactId>
】,可以看到在<properties>
标签下定义好了大量的 Spring Cloud 组件的版本信息。所以当我们导入 Spring Cloud 组件时,无需指定版本。
3.2 编写启动类
-
打开
eureka-server
微服务的启动类Main.java
(把它重命名为EurekaApplication.java
) 。添加 Spring Boot 注解@SpringBootApplication
。 -
添加
@EnableEurekaServer
注解来打开 Eureka 服务。@SpringBootApplication @EnableEurekaServer @Slf4j public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); log.info("Eureka注册中心启动成功"); } }
3.3 修改配置文件
-
在
src/main/resources
目录下创建配置文件application.yml
。 -
修改
application.yml
配置文件,加入下面的配置。server: port: 10086 # 服务端口 spring: application: name: eurekaserver # 微服务名称 eureka: client: service-url: # Eureka的地址信息 defaultZone: http://localhost:10086/eureka
其中,为什么要在 Eureka 的 client 客户端把 Eureka 微服务自己也配置进去呢?因为 Eureka 自己也是微服务,Eureka 启动时,也会把自己也注册进 Eureka 上。这是为了将来 Eureka 集群之间通信使用的。例如,我启动了 3 个 Eureka 服务,那么这 3 个 Eureka 服务就相互注册,这样他们就可以做数据交流了。只是因为现在只有一台 Eureka 服务,所以只配了自己。
3.4 启动Eureka微服务
-
在 Eureka 微服务的启动类
EurekaApplication.java
中启动。 -
可以在底栏
Services
中发现多了一个正在运行的微服务,那就是 Eureka 。 -
此时我们可以在浏览器中输入
http://localhost:10086/
来访问 Eureka 的主页。也可以在 IDEA 底栏的Services
中,点击EurekaApplication:10086/
的端口号直接打开浏览器访问。如果你能看到这个页面,说明你的 Eureka 注册中心就搭建成功了。这个页面中,最重要的部分就是中间的
Instances currently registered with Eureka
。这里罗列了当前注册到 Eureka 的微服务实例信息。
4. 服务注册
- 接下来,我们把用户微服务
user-service
注册到 EurekaServer 中。一共两步,与搭建 Eureka 的步骤非常相似。
4.1 导入依赖
-
在用户微服务
user-service
的pom.xml
文件中导入 spring-cloud-starter-netflix-eureka-client 的 Maven 坐标。注意这里是客户端client
。<!-- Eureka注册中心客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client </artifactId> </dependency>
4.2 修改配置文件
-
打开用户微服务
user-service
的配置文件application.yml
,加入以下内容。spring: application: name: userservice # 微服务名称 eureka: client: service-url: # Eureka的地址信息 defaultZone: http://localhost:10086/eureka/
-
经过这两步,用户微服务
user-service
就成功注册到 Eureka 中了。同理,按照同样的步骤,把订单微服务order-service
也注册到 Eureka 中。
4.3 重启微服务
-
重启用户微服务
user-service
和订单微服务order-service
。 -
此时在浏览器中输入
http://localhost:10086/
来访问 Eureka 的主页。可以看到用户微服务
user-service
和订单微服务order-service
都成功注册到 Eureka 中了。
4.4 启动多个微服务实例
-
在企业的实际开发中,一个微服务往往有多个实例,以达到高可用的目的。实际开发部署中,多个微服务实例是通过 Docker 将微服务构建成镜像,然后依照这个镜像创建多个 Docker 容器实例来实现的。鉴于有一部分同学还没接触过 Docker ,这里先使用 IDEA 的功能来本地运行多个用户微服务
user-service
实例。 -
进入 IDEA 底栏的 Services ,找到
UserApplication
,右击,选择【Copy Configuration…】。 -
然后随便起个名字,点击【Modify options】。
-
添加虚拟机选项【Add VM options】。
-
然后换个端口,否则端口会冲突。在【VM options】一栏输入
-Dserver.port=8082
。 -
点击【OK】后,会发现多出来一个用户微服务
UserApplication2
,启动它。 -
然后回到 Eureka 主页,发现注册列表中,用户微服务
USERSERVICE
的实例个数变成 2 了,且能看到 2 个 IP:端口。到此,使用 Eureka 实现服务注册就完成了。
5. 服务发现
- 本节,我们将设定订单微服务
order-service
为消费者,用户微服务user-service
为提供者,订单微服务远程调用用户微服务的查询服务。 - 本节我们将使用订单微服务
order-service
拉取服务注册列表。 - 服务拉取是基于服务名称获取服务列表,然后再对服务列表做负载均衡选取出一个微服务实例进行远程调用。
5.1 修改业务层代码
- 修改订单微服务
order-service
的业务层代码OrderService.java
。修改 RestTemplate 的访问 URL 路径,用要远程调用的微服务名代替原来的 IP 和端口。
【小贴士】
- 如果你对 RestTemplate 感到陌生,可以参考我的这篇博文《基于RestTemplate发送HTTP请求实现微服务远程调用》进行学习。
String url = "http://userservice/user/" + order.getUserId();
OrderService.java
:
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
// 自动注入RestTemplate,用于发起HTTP请求远程调用
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.使用RestTemplate发起HTTP请求,查询订单所属用户信息
// 2.1 根据查询的订单order中的userId动态生成HTTP请求的url
String url = "http://userservice/user/" + order.getUserId();
// 2.2 发送HTTP请求,实现远程调用
User user = restTemplate.getForObject(url, User.class);
// 3.把远程调用获得的user封装进order对象中
order.setUser(user);
// 4.返回order订单信息
return order;
}
}
5.2 在RestTemplate上添加负载均衡注解
-
在订单微服务
order-service
的启动类OrderApplication.java
中的RestTemplate
上添加@LoadBalanced
负载均衡注解。 -
OrderApplication.java
:
// 注册RestTemplate,用来发起HTTP请求远程调用
@Bean
@LoadBalanced // 负载均衡注解
public RestTemplate restTemplate() {
return new RestTemplate();
}
5.3 重启OrderApplication
-
接下来,把两个
UserApplication
的日志清空,以便查看OrderApplication
是如何来选取用户微服务UserApplication
进行远程调用的。 -
在 Postman 中,向发送 2 个请求
http://localhost:8080/order/101
和http://localhost:8080/order/102
。 -
回到两个
UserApplication
的日志中,可以看到第一次调用了 8082 端口的用户微服务;而第二次则调用了 8081 端口的用户微服务。
说明负载均衡成功实现。在使用 RestTemplate 发起 HTTP 远程调用时,我们不需要关心想要远程调用的 IP 地址和端口号,只需要把对于的微服务名写在 URL 上,Eureka 会自动帮我们在多个微服务实例中均衡地选取一个进行远程调用。
-
以上,就称为服务发现和服务拉取。