0


【SpringCloud】02 注册中心Eureka的原理与使用

文章目录

阅读提示:

本文是SpringCloud系列第二篇,请先阅读前置文章。
所有代码都基于01认识微服务,了解服务拆分与远程调用中的基础代码cloud-demo,可以前往下载。

一、问题引入

在上一篇文章中,我们在OrderService类的queryOrderById方法里,使用RestTemplate里向user-service微服务发起调用请求,根据用户id查询用户信息,代码如下:

// 2.使用RestTemplate发起http请求 实现远程调用String url ="http://localhost:8081/user/"+order.getUserId();User user = restTemplate.getForObject(url,User.class);

当前存在的问题
在微服务中,往往一个服务模块如这里的user-service服务,会部署在多台机器上以应对高并发访问,因此会有多个实例及地址,以本机部署三个user-service服务为例,它们的端口号分别为8081,8082,8083,如下图:
在这里插入图片描述
那么这时我依然使用之前的RestTemplate发起访问请求,会存在以下几个问题:

// 2.使用RestTemplate发起http请求 实现远程调用String url ="http://localhost:8081/user/"+order.getUserId();User user = restTemplate.getForObject(url,User.class);
  • user-service实例的ip地址和端口变化时,order-service该如何得知? 很显然目前我们只能把user-service实例的地址写死在order-service的配置文件中,当user-service实例的地址和端口变化,也要修改order-service的配置文件,说不定还有很多其他微服务,也要调用user-service,当不得已修改user-service实例的地址和端口时,重新部署非常麻烦。
  • 有多个user-service实例的地址时,order-service该选择哪一个? 1.首先固定选择其中某一个实例,肯定是不合适,因为只要这个user-service实例宕机,调用它的order-service实例也就宕机了,会影响微服务架构的稳定性、可用性。 2.那么该怎么选择呢?这很难选,因为order-service不知道哪一个实例是健康的,哪一个已经宕机;或者哪一个当前服务器资源比较紧张,暂时不应该访问的(负载均衡)。而且RestTemplate的url地址是写死的,虽然可以在运行过程中修改url地址,但还是回到了问题本身,不清楚该选择哪一个。

二、Eureka的结构与作用

上述问题都需要利用SpringCloud中的注册中心来解决,其中最广为人知的注册中心就是Eureka,其结构如下:
在这里插入图片描述
回答上述两个问题。

  • user-service实例的ip地址和端口变化时,order-service该如何得知? user-service服务实例启动后,将自己的信息注册到eureka-server(Eureka服务端),这个叫服务注册。 eureka-server保存服务名称到服务实例地址列表的映射关系。 order-service根据user-service服务名称,拉取其实例地址列表。这个叫服务发现。 在这种服务注册与发现的方式下,order-service甚至不需要把user-service的具体地址写入自己的配置文件中,只需要在访问user-service时,去Eureka服务端拉取目前的user-service服务实例的地址即可。
  • 有多个user-service实例的地址时,order-service该选择哪一个? 使用@LoadBalanced注解,让order-service从user-service的实例列表中利用负载均衡算法选择其中一个实例地址;并且user-service的实例会定时向Eureka服务端发送心跳,超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除,order-service拉取服务时,就能将故障实例排除了,这就保证了order-service选择user-service实例时,既能保证保证均衡,又能保证排除故障实例。

因此注册中心解决的主要问题就是微服务之间进行远程调用时,让微服务之间能够互相发现对方,同时一定程度上可以监测微服务的健康状态,并提供负载均衡的功能,归根到底解决的就是远程调用时选择哪个实例这一个问题。

注意: 一个微服务,既可以是服务提供者,又可以是服务消费者,因此eureka将服务注册、服务发现等功能统一封装到了eureka-client端,且每个微服务启动时都会将自己注册到Eureka服务端中。

三、搭建Eureka-server

首先搭建注册中心服务端:eureka-server,这必须是一个独立的微服务。
在cloud-demo模块下,创建一个子模块maven工程,命名为eureka-server。
在这里插入图片描述
引入SpringCloud为eureka提供的starter依赖:

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

给eureka-server服务编写一个启动类,一定要添加一个@EnableEurekaServer注解,开启eureka的注册中心功能:

packagecn.itcast.eureka;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication@EnableEurekaServerpublicclassEurekaApplication{publicstaticvoidmain(String[] args){SpringApplication.run(EurekaApplication.class, args);}}

编写配置文件application.yml,内容如下:这里我们设置eureka-server的ip为本机的10086端口

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

启动微服务EurekaApplication,然后在浏览器访问:http://127.0.0.1:10086
看到下面结果就是成功了:
在这里插入图片描述

四、服务注册与发现

前面已经说过,一个微服务既可以是服务的提供者,也可以是服务消费者,因此只需要使用同一个依赖spring-cloud-starter-netflix-eureka-client,就可以同时实现一个微服务的注册与发现。

4.1 配置user-service

(1) 引入依赖
在user-service的pom文件中,引入下面的eureka-client(eureka客户端)依赖:

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

(2) 修改配置文件
在user-service中,修改application.yml文件,添加服务名称、eureka地址:
后续其他服务要访问user-service,就是通过这个服务名称来发起请求,因此这里命名最好规范。

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

(3) 使用IDEA启动多个user-service实例
首先,右键复制原来的user-service启动配置:
在这里插入图片描述
修改运行实例名称为UserApplication2,点击Modify options,点击Add VM Options
在这里插入图片描述
在这里插入图片描述
接着填写-Dserver.port=8082来修改运行端口号
在这里插入图片描述
启动两个User-service实例,可以在eureka控制台看到如下信息:
在这里插入图片描述

4.2 配置order-service

之前说过,服务发现、服务注册统一都封装在eureka-client依赖,因此引入依赖和与配置文件的修改和user-service基本一致。
(1) 引入依赖
在order-service的pom文件中,引入下面的eureka-client依赖

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

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

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

(3) 服务拉取与负载均衡
负载均衡的设置
在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解:

/**
     * 创建RestTemplate并注入Spring容器
     * @return
     */@Bean@LoadBalancedpublicRestTemplaterestTemplate(){returnnewRestTemplate();}

服务拉取
修改order-service服务中的cn.itcast.order.service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名userservice代替ip+端口的url

publicOrderqueryOrderById(Long orderId){// 1.查询订单Order order = orderMapper.findById(orderId);// 2.使用RestTemplate发起http请求 实现远程调用String url ="http://userservice/user/"+order.getUserId();User user = restTemplate.getForObject(url,User.class);// 封装到order中
        order.setUser(user);// 4.返回return order;}

@LoadBalanced注解可以让RestTemplate能够识别服务的名称而不是直接使用URL。这样,发送HTTP请求时,RestTemplate会根据服务名称来选择一个可用的实例进行调用。它会根据负载均衡策略,在多个实例之间分配请求,以达到负载均衡的效果,当然前提是结合注册中心使用。
详细原理请阅读:https://zhuanlan.zhihu.com/p/617967367

4.3 效果测试

重新启动OrderApplication,浏览器访问localhost:8080/order/101,可以发现IDEA控制台中8081和8082端口的UserApplication服务轮流打印信息,因此注册中心部署和服务注册、发现,负载均衡都成功实现。


本文转载自: https://blog.csdn.net/qq_43856972/article/details/134765665
版权归原作者 蒲公英的岁月 所有, 如有侵权,请联系我们删除。

“【SpringCloud】02 注册中心Eureka的原理与使用”的评论:

还没有评论