Eureka基本使用

35 阅读7分钟
  • 携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

1. 服务拆分

1、单一职责:不同微服务,不要重复开发相同业务 2、数据独立:不要访问其它微服务的数据库 3、面向服务:将自己的业务暴露为接口,供其它微服务调用

1.1 根据订单id查询订单功能

  • 需求:根据订单id查询订单的同时,把订单所属的用户信息一起返回 在这里插入图片描述

  • 远程调用分析方式 1、 user 模块对外暴露了 restful 的接口,只要在浏览器输入对应的请求地址就一定能拿到对应的请求信息。 2、user模块接收到请求信息就会去数据库查询请求的信息,然后把对应的信息返回给浏览器 3、如果order模块也能发起http的请求,user模块也会返回对应的信息给order模块 4、order模块再结合本地数据库信息,就可以查询出完整的订单信息 在这里插入图片描述

  • 如何在Java代码中发起HTTP请求

  • 需要在order-service中 向user-service发起一个http的请求,调用http://localhost:8081/user/{userId} 这个接口。

1.2 实现方式

微服务远程调用-查询订单

1、注册一个RestTemplate的实例到Spring容器 在order-service的OrderApplication中注册RestTemplate

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

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

    /**
     * 创建 RestTemplate并注入到 Spring 容器中
     * @return
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2、修改order-service服务中的OrderService类中的queryOrderById方法,根据Order对象中的userId查询User

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate并发起http请求,查询用户
        // 2.1 url路径
        String url = "http://localhost:8081/user/" + order.getUserId();
        // 2.2 发送http请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);
        // 3. 封装 user 到 order 中
        order.setUser(user);
        // 4.返回
        return order;
    }
}

在这里插入图片描述

1.3 小结

微服务调用方式

  • 基于RestTemplate发起的http请求实现远程调用

  • http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可。

  • 实现跨服务的远程调用,其实就是实现http请求

2. 提供者与消费者

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

  • 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口) 在这里插入图片描述

  • 服务A调用服务B,服务B调用服务C,那么服务B是什么角色? 答:B既是提供者也是消费者。一个服务既可以是提供者,又可以是消费者。

  • 服务调用关系 1、服务提供者:暴露接口给其它微服务调用 2、服务消费者:调用其它微服务提供的接口 3、提供者与消费者角色其实是相对的 4、一个服务可以同时是服务提供者和服务消费者

3. Eureka注册中心

3.1 服务调用出现的问题

  • 假如服务提供者user-service部署了多个实例,如图:

在这里插入图片描述

  • order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?
  • 有多个user-service实例地址,order-service调用时该如何选择?
  • order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

3.2 Eureka的结构和作用

在这里插入图片描述

问题1:order-service如何得知user-service实例地址?

获取地址信息的流程如下:

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

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

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

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

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

注意:一个微服务,既可以是服务提供者,又可以是服务消费者,因此eureka将服务注册、服务发现等功能统一封装到了eureka-client端

3.3 小结

在Eureka架构中,微服务角色有两类:

1、EurekaServer:服务端,注册中心 ①记录服务信息 ②心跳监控

2、EurekaClient:客户端

  • Provider:服务提供者,例如案例中的 user-service
    • 注册自己的信息到EurekaServer
    • 每隔30秒向EurekaServer发送心跳
  • consumer:服务消费者,例如案例中的 order-service
    • 根据服务名称从EurekaServer拉取服务列表
    • 基于服务列表做负载均衡,选中一个微服务后发起远程调用

4. 搭建eureka-server

注册中心服务端:eureka-server,必须是一个独立的微服务

4.1 创建eureka-server服务

1、在cloud-demo父工程下,创建一个子模块 2、引入eureka依赖,引入SpringCloud为eureka提供的starter依赖:

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

3、编写启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

4、编写配置文件 编写一个application.yml文件,内容如下:

server:
  port: 10086
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka

5、启动服务 启动微服务,然后在浏览器访问:http://127.0.0.1:10086 在这里插入图片描述

4.2 小结

  • 搭建EurekaServer ①引入eureka-server依赖 ②添加@EnableEurekaServer注解 ③在application.yml中配置eureka地址

5. 服务注册

  • 将user-service注册到eureka-server中

1、引入依赖 在user-service的pom文件中,引入下面的eureka-client依赖:

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

2、配置文件 在user-service中,修改application.yml文件,添加服务名称、eureka地址:

spring:
  application:
    name: userservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  • orderservice 注册同上

3、启动多个user-service实例

  • 为了演示一个服务有多个实例的场景,添加一个SpringBoot的启动配置,模拟多实例部署,再启动一个user-service。

  • 首先,复制原来的user-service启动配置: 在这里插入图片描述

  • 为了避免端口冲突,需要修改端口设置: 在这里插入图片描述 在这里插入图片描述

  • 查看eureka-server管理页面: 在这里插入图片描述

6. 服务发现

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

1、引入依赖

服务发现、服务注册统一都封装在eureka-client依赖,因此这一步与服务注册时一致。 在order-service的pom文件中,引入下面的eureka-client依赖:

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

2、配置文件

服务发现也需要知道eureka地址,因此第二步与服务注册一致,都是配置eureka信息: 在order-service中,修改application.yml文件,添加服务名称、eureka地址

spring:
  application:
    name: orderservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

3、服务拉取和负载均衡

eureka-server中拉取user-service服务的实例列表,并且实现负载均衡。 不过这些动作不用我们去做,只需要添加一些注解即可。

  • 在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解:
@MapperScan("cn.xdr630.order.mapper")
@SpringBootApplication
public class OrderApplication {

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

    /**
     * 创建 RestTemplate并注入到 Spring 容器中
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  • 修改order-service服务中的service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名代替ip、端口: 在这里插入图片描述

  • spring会自动从eureka-server端,根据userservice这个服务名称,获取实例列表,而后完成负载均衡。

  • 测试:访问 orderservice 服务调用 userservice 的用户信息,访问6次后,可以在控制台看到请求的是 userservice:8081 或 userservice:8082 ,可以观察出orderservice是随机访问 userservice 8081或 8082 的,说明实现了负载均衡。

7. 小结

1、搭建EurekaServer ①引入eureka-server依赖 ②添加@EnableEurekaServer注解 ③在application.yml中配置eureka地址 2、服务注册 ①引入eureka-client依赖 ②在application.yml中配置eureka地址 ③服务发现 3、引入eureka-client依赖 ①在application.yml中配置eureka地址 ②给RestTemplate添加@LoadBalanced注解 ③用服务提供者的服务名称远程调用