【SpringCloud】Eureka的基本原理与使用

一、Eureka-提供者与消费者

【问】如果服务A调用了服务B,而服务B又调用了服务C,服务B的角色是什么?

二、Eureka的结构和作用

什么是Eureka?

Eureka 解决服务调用的问题

order-service 如何得知 user-service实例地址?

order-service如何从多个user-service实例中选择具体的实例?

order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

三、Eureka 的使用

搭建步骤

1. 搭建注册中心EurekaServer

(1)创建项目,引入 spring-cloud-starter-netflix-eureka-server 的依赖 

(2)编写启动类,添加 @EnableEurekaServer 注解

(3)添加 application.yml 配置文件

【注】自身就是Eureka,为什么要配置自身的地址信息呢???

访问 Eureka服务

2. 服务注册

(1)引入 spring-cloud-starter-netflix-eureka-client 依赖

(2)applicaiton.yml 配置文件

3. 服务发现

(1)修改 order-service 的代码,修改访问路径,用服务名代替IP、端口

(2)在 order-service 项目的启动类中的 RestTemplate添加负载均衡的注解

运行结果

【SpringCloud】Eureka的基本原理与使用

一、Eureka-提供者与消费者

在服务调用关系中,会有两个不同的角色

  • 服务提供者:一次业务中,其它微服务调用的服务。(提供接口给其它微服务)
  • 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)

java服务从eureka发现服务 eureka服务之间调用_微服务

【问】如果服务A调用了服务B,而服务B又调用了服务C,服务B的角色是什么?

  • 对于A调用B的业务而言:A是服务消费者,B是服务提供者
  • 对于B调用C的业务而言:B是服务消费者,C是服务提供者

所以,服务提供者与服务消费者的角色并不是绝对的,而是相对于业务而言。服务B既可以是服务提供者,也可以是服务消费者

二、Eureka的结构和作用

什么是Eureka?

Eureka是Spring Cloud Netflix 模块中的子模块。

Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:

  • Eureka Server:Eureka 服务注册中心,主要用于提供服务注册功能。当微服务启动时,会将自己的服务注册到 Eureka Server。Eureka Server 维护了一个可用服务列表,存储了所有注册到 Eureka Server 的可用服务的信息,这些可用服务可以在 Eureka Server 的管理界面中直观看到。
  • Eureka Client:Eureka 客户端,通常指的是微服务系统中各个微服务,主要用于和 Eureka Server 进行交互。在微服务应用启动后,Eureka Client 会向 Eureka Server 发送心跳(默认周期为 30 秒)。若 Eureka Server 在多个心跳周期内没有接收到某个 Eureka Client 的心跳,Eureka Server 将它从可用服务列表中移除默认 90 秒)。 

Eureka的作用

java服务从eureka发现服务 eureka服务之间调用_微服务_02

Eureka 解决服务调用的问题

order-service 如何得知 user-service实例地址?

  • user-service 服务实例启动后,将自己的信息注册到 eureka-server(Eureka服务端)。这个叫服务注册
  • eureka-server 保存服务名称服务实例地址列表的映射关系
  • order-service 根据服务名称,拉取实例地址列表。这个叫服务发现服务拉取

order-service如何从多个user-service实例中选择具体的实例?

  • order-service 从实例列表中利用负载均衡算法选中一个实例地址
  • 向该实例地址发起远程调用

order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

  • user-service 会每隔一段时间(默认30秒)向 eureka-server 发起请求,报告自己状态,称为心跳
  • 当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除
  • order-service 拉取服务时,就能将故障实例排除

三、Eureka 的使用

搭建步骤

  1. 搭建注册中心,搭建EurekaServer
  2. 服务注册,将user-service、order-service都注册到Eureka中
  3. 服务发现,在order-service中完成服务拉取,然后通过负载均衡挑选一个服务,实现远程调用!

1. 搭建注册中心EurekaServer

(1)创建项目,引入 spring-cloud-starter-netflix-eureka-server

<dependencies>
    <!-- eureka服务端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

(2)编写启动类,添加 @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

配置文件中配置3个信息,服务端口号、服务名称、eureka的地址信息

【注】自身就是Eureka,为什么要配置自身的地址信息呢???

是这样子的!因为Eureka自身也是一个微服务,所以,在启动的时候,会将自己也注册到eureka上!这是为了之后Eureka集群通信,假如启动了多个eureka,那么这些 Eureka之间会相互做注册,这样子它们之间就可以做数据交互了!

访问 Eureka服务

地址:http://127.0.0.1:10086/eureka (我们刚刚在application.yml配置的)

java服务从eureka发现服务 eureka服务之间调用_spring_03

服务每部署一份就是一个实例

2. 服务注册

我们这里是要将 user-service 注册到 eureka-server 中去

(1)引入 spring-cloud-starter-netflix-eureka-client 依赖

user-service模块 的 pom.xml 文件中,引入下面的 spring-cloud-starter-netflix-eureka-client 依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

(2)applicaiton.yml 配置文件

server:
  port: 8081

spring:
  application:
    name: userservice  # eureka的服务名称
  ...

eureka:
  client:
    service-url:  # eureka 的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

所以,我们可以总结一下,注册一个服务大致有如下2个步骤

(1)导入 eureka-client 依赖

(2)在applicaiton.yml 中配置 Erueka地址

3. 服务发现

我们将 order-service 的逻辑修改:向 eureka-server 拉取 user-service 的信息实现服务发现

(1)修改 order-service 的代码,修改访问路径,用服务名代替IP、端口

@Service
public class OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private RestTemplate restTemplate;

    /**
     * 使用restTemplate 方式进行远程调用
     * @param orderId
     * @return
     */
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);

        // 2.利用restTemplate发起http请求
        // 为了负载均衡使用服务名称
        String url = "http://userservice/user/" + order.getUserId();
        // 得到的结果是json风格,getForObject()可以将json反序列化!
        User user = restTemplate.getForObject(url, User.class);

        // 3.封装user到Order
        order.setUser(user);

        // 4.返回
        return order;
    }
}

(2)在 order-service 项目的启动类中的 RestTemplate添加负载均衡的注解

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * @LoadBalanced: 表示restTemplate发起的请求要被 Ribbon处理
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

运行结果

IDEA运行情况 

java服务从eureka发现服务 eureka服务之间调用_spring_04

通过 OrderService 模块去调用 UserService 模块,获取 User信息

java服务从eureka发现服务 eureka服务之间调用_java服务从eureka发现服务_05