一:Eureka简介
1:问题引入
在介绍Eureka之前,我先讲两个概念,一是服务提供者,它指的是在一次业务中被其它微服务调用的服务(提供接口给其它微服务),也就是暴露接口给其它微服务调用;另一个是服务消费者,它是指再一次业务中调用其它服务的服务(调用其它服务提供的接口)。要注意的是,提供者与消费者之间的角色是相对的,就好比当你去买东西时候,相对于卖东西给你那个人你就是消费者;当你去卖东西时候相对于买你东西那个人你就是提供者。
在没有引入Eureka之前,我们可以通过RestTemplate指定URL路径来发送http请求,实现远程调用,举个例子:
// 2.利用RestTemplate发起Http请求,查询用户 //2.1 url路径 String url = "http://localhost:8081/user/" + order.getUserId(); //2.2 发送http请求,实现远程调用 User user = restTemplate.getForObject(url,User.class);
当我们需要调用8081端口提供的服务的时候,就可以通过上诉方法进行服务调用。上述方法是通过硬编码实现的,会存在很多的问题,比如我们需要调用大量不同的服务时候,就需要指定很多的URL,而且你还需要清楚地知道每个服务的IP和端口号,这样显然是很不友好的;此外,当一个服务提供很多实例时候,采用了上述硬编码方式消费者如何进行选择呢?就比如某一服务提供了三个实例,采用上述方式永远只能选定一个实例,另外两个实例永远不会被调用,除非你直接对代码进行更改。
最后还存在一个问题,消费者如何得知服务提供者的健康状态呢?当请求的服务已经挂掉了,就算服务列表还有其他实例可以调用,由于采用的是硬编码形式,其他健康的服务提供者也无法被调用。那么有没有办法可以解决上述问题呢?答案是肯定的,Eureka的出现就解决了上面提到了问题。
2:Eureka的作用
在介绍Eureka的作用之前,我们首先来看一张图:
编辑
在Eureka架构中,微服务角色有两类:
- EurekaServer:服务端,注册中心
- 记录服务信息
- 心跳监控
- EurekaClient:客户端
- Provider:服务提供者,例如上图的user-service
- 注册自己的信息到Eureka
- 每隔一定时间向EurekaServer发送心跳
- consumer:服务消费者,例如上图的order-service
- 根据服务名称从EurekaServer拉取服务列表
- 基于服务列表做负载均衡,选中一个之后发起远程调用
每一个服务提供者启动时候都会向Eureka注册自己的信息(包括它自身),Eureka将会保存这些信息,这时候消费者就能通过服务名称向Eureka拉取提供者的信息。假如有多个服务提供者,比如user-service有8081、8082、8083这三个服务提供者,当消费者向EurekaServer注册中心拉取user-service信息的时候,注册中心就会返回user-service的服务列表,消费者再根据负载均衡算法进行选择。这样就能解除硬编码不能实现动态选择的问题,那么如何获取服务提供者的健康状态呢?
每个服务提供者都会每隔一段时间向EurekaServer发送心跳请求以报告自己的健康状态,Eureka会更新记录服务列表的信息,以剔除心跳不正常的服务提供者,以保证向消费者提供的服务都是健康的。
二:Eureka的搭建
1:搭建EurekaServer
1).单独创建一个EurekaServer模块并引入相关依赖(整体项目架构如下)
编辑
<dependencies> <!--eureka服务端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
2).编写启动类,添加@EnableEurekaServer注解
package cn.itcast.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
3).添加application.yml文件并编写配置信息
server: port: 10086 # 服务端口 spring: application: name: eurekaServer # eureka的服务名称 eureka: client: service-url: # eureka的地址信息 defaultZone: http://127.0.0.1:10086/eureka
2:服务注册
- 引入eureka-client依赖
<!--eureka客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- 在application.yml中配置eureka地址
eureka: client: service-url: # eureka的地址信息 defaultZone: http://127.0.0.1:10086/eureka
3:服务发现
- 引入eureka-client依赖
<!--eureka客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- 在application.yml中配置eureka地址
eureka: client: service-url: # eureka的地址信息 defaultZone: http://127.0.0.1:10086/eureka
- 给RestTemplate添加@LocalBalanced注解
/** * 创建RestTemplate并注入Spring容器 */ @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
- 用服务提供者的服务名称远程调用
// 2.利用RestTemplate发起Http请求,查询用户 //2.1 url路径 String url = "http://userServer/user/" + order.getUserId(); //2.2 发送http请求,实现远程调用 User user = restTemplate.getForObject(url,User.class);