【Eureka】搭建Eureka Server,实现服务注册和服务发现

张裕  金牌会员 | 2024-10-27 08:59:32 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 573|帖子 573|积分 1719

1. Eureka介绍

Eureka是NetflixOSS套件中关于服务注册和发现的解决⽅案.SpringCloud对Eureka进⾏了集成,并作为优先推荐⽅案进⾏宣传,虽然⽬前Eureka2.0已经停⽌维护,新的微服务架构设计中,也不再发起使用,但是⽬前依然有⼤量公司的微服务系统使⽤Eureka作为注册中⼼.
官方文档:https://github.com/Netflix/eureka/wiki
Eureka主要分为两部分:


  • Eureka Server: 作为注册中央Server端,向微服务应用步伐提供服务注册,发现,健康检查等本领.
  • Eureka Client: 服务提供者,服务启动时,会向Eureka Server 注册本身的信息(IP,端口,服务信息等),Eureka Server 会存储这些信息
2. 什么是注册中央

在最初的架构体系中,集群的概念还不那么盛行,且机器数目也比力少,此时直接使用DNS+Nginx就可以满意几乎所有服务的发现.相关的注册信息直接设置在Nginx.但是随着微服务的盛行与流量的激增机器规模逐渐变大,并且机器会有频繁的上下线行为,这种时间需要运维手动地去维护这个设置信息是一个很贫困的操纵,所以开发者们开始希望有这么一个东西,它能维护一个服务列表,哪个机器上线了哪个机器宕机了,这些信息都会自动更新到服务列表上,客户端拿到这个列表,直接进行服务调用即可这个就是注册中央.
注册中央主要有三种脚色:


  • 服务提供者(Server):一次业务中,被其它微服务调用的服务.也就是提供接口给其它微服务
  • 服务消费者(Client):一次业务中,调用其它微服务的服务,也就是调用其它微服务提供的接口
  • 服务注册中央(Registry):用于保存Server 的注册信息,当Server节点发生变更时,Registry 会同步变更.服务与注册中央使用肯定机制通讯,假如注册中央与某服务长时间无法通讯,就会注销该实例
他们之间的关系以及工作内容,可以通过两个概念来描述:服务注册:服务提供者在启动时,向 Registry注册自身服务,并向 Registry 定期发送心跳汇报存活状态,


  • 服务发现:服务消费者从注册中央查询服务提供者的地址,并通过该地址调用服务提供者的接口.
  • 服务发现的一个重要作用就是提供给服务消费者一个可用的服务列表.

常见的注册中央:
1. Zookeeper:Zookeeper的官方并没有说它是一个注册中央,但是国内Java体系,大部分的集群环境都是依赖Zookeeper来完成注册中央的功能
2. Eureka:Eureka是Netflix开发的基于REST的服务发现框架,主要用于服务注册,管理,负载平衡和服务故障转移.
官方声明在Eureka2.0版本停止维护,不发起使用.但是Eureka是SpringCloud服务注册/发现的默认实现,所以现在还是有许多公司在使用.
3. Nacos:Nacos是Spring Cloud Alibaba架构中重要的组件,除了服务注册,服务发现功能之外,Nacos还支持设置管理,流量管理,DNS.动态DNS等多种特性
3. 搭建Eureka Server

Eureka-server时一个独立的微服务,我们可以通过创建子项目的方式创建,当然也可以单独创建一个独立的项目,作为Eureka-server.
3.1 创建Eureka-server子模块


3.2 引入Rureka-server依赖

  1. <dependency>
  2.     <groupId>org.springframework.cloud</groupId>
  3.     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  4. </dependency>
复制代码
3.3 项目构建插件

  1.     <build>
  2.         <plugins>
  3.             <plugin>
  4.                 <groupId>org.springframework.boot</groupId>
  5.                 <artifactId>spring-boot-maven-plugin</artifactId>
  6.             </plugin>
  7.         </plugins>
  8.     </build>
复制代码
3.4 编写设置文件

  1. # Eureka相关配置
  2. # Eureka 服务
  3. server:
  4.   port: 8761
  5. spring:
  6.   application:
  7.     name: eureka-server
  8. eureka:
  9.   instance:
  10.     hostname: localhost
  11.   client:
  12.     fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false
  13.     register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.
  14.     service-url:
  15.       # 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址
  16.       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
复制代码
3.5完善启动类

给该项⽬编写⼀个启动类,并在启动类上添加 @EnableEurekaServer 注解,开启eureka注册中⼼服务
  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  4. @EnableEurekaServer
  5. @SpringBootApplication
  6. public class EurekaServerApplication {
  7.     public static void main(String[] args) {
  8.         SpringApplication.run(EurekaServerApplication.class, args);
  9.     }
  10. }
复制代码
3.6 启动服务

启动服务,访问注册中央:http://localhost:8761/

4. 服务注册

服务注册也就是服务提供方需要来做的事变,我这里实现准备好了两个子项目分别是order-service和product-service,分别表示订单服务和商品服务。并且这里订单服务有查询订单的接口,商品服务有查询商品的接口,并且order-service通过RestTemplate远程调用product-service,根据订单查询订单信息时, 根据订单⾥产物ID, 获取产物的详细信息.
https://www.cnblogs.com/54chensongxia/p/11414923.html
https://www.cnblogs.com/54chensongxia/p/11414923.html -- RestTemplate 详细使⽤可参考

现在我的场景下的是谁需要来进行服务注册?也就是服务提供者-被调用的一方:product-service.
接下来我们吧product-service注册到eureka-service中
4.1 引入Eureka-client依赖

  1. <dependency>
  2.      <groupId>org.springframework.cloud</groupId>
  3.      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  4. </dependency>
复制代码
4.2 完善设置文件

添加服务名称和eureka地址

4.3 启动服务

   刷新注册中⼼:   http://127.0.0.1:10010/   

5. 服务发现

服务发现就是需要从Eureka中获取到对应的服务,在我们的场景中,order-service从eureka-server拉取product-service的服务信息, 实现服务发现。服务发现就是主动调用的一方。
5.1 引入依赖

这里和前面的服务注册引入的依赖划一,都是引入client
  1. <dependency>
  2.      <groupId>org.springframework.cloud</groupId>
  3.      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  4. </dependency>
复制代码
5.2 完善设置文件

      服务发现也需要知道eureka地址, 因此设置内容依然与服务注册⼀致,都是设置eureka信息      
  1. spring:
  2.   application:
  3.     name: order-service
  4. #Eureka client
  5. eureka:
  6.   client:
  7.     service-url:
  8.       defaultZone: http://127.0.0.1:8761/eureka/
复制代码
  5.3 远程调用

       远程调⽤时, 我们需要从eureka-server中获取product-service的列表(可能存在多个服务), 并选择此中⼀个进⾏调⽤。也就是从众多的服务中,选出我们需要的服务,然后使用。         
  1. import com.guan.order.mapper.OrderMapper;
  2. import com.guan.order.model.OrderInfo;
  3. import com.guan.product.model.ProductInfo;
  4. import jakarta.annotation.Resource;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.cloud.client.ServiceInstance;
  8. import org.springframework.cloud.client.discovery.DiscoveryClient;
  9. import org.springframework.stereotype.Service;
  10. import org.springframework.web.client.RestTemplate;
  11. import java.util.List;
  12. @Service
  13. @Slf4j
  14. public class OrderService {
  15.     @Autowired
  16.     private OrderMapper orderMapper;
  17.     @Resource
  18.     private DiscoveryClient discoveryClient;
  19.     @Autowired
  20.     private RestTemplate restTemplate;
  21.     public OrderInfo selectOrderByID(Integer orderID){
  22.         OrderInfo orderInfo = orderMapper.selectOrderById(orderID);
  23.         // String url =  "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();
  24.         // 从Eureka获取服务列表
  25.         List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
  26.         String uri = instances.get(0).getUri().toString();
  27.         String url =  uri + "/product/"+ orderInfo.getProductId();
  28.         log.info("远程调用url:{}",url);
  29.         ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
  30.         orderInfo.setProductInfo(productInfo);
  31.         return orderInfo;
  32.     }
  33. }
复制代码
   需要注意这里使用的是,springframework.cloud.client.discovery包下面的DiscoveryClient。

       5.4 启动服务

刷新注册中央:http://localhost:8761/

   可以看到order-service已经注册到 eureka上了,  访问接⼝:   http://127.0.0.1:8080/order/1         
       可以看到, 远程调⽤也成功了      6. Eureka和Zookeeper区别

     Eureka和Zookeeper都是⽤于服务注册和发现的⼯具,区别如下:     

  • Eureka是Netflix开源的项目,而Zookeeper是Apache开源的项目;
  • Eureka基于AP原则,保证高可用,Zookeeper基于CP原则,保证数据划一性
  • Eureka每个节点 都是均等的,Zookeeper的节点区分Leader和Follower 或 Observer,也正因为这个原因,假如Zookeeper的Leader发生故障时,需要重新选举,选举过程集群会有短暂时间的不可用
  注:
  CAP 三个核心概念:
  

  • 划一性 (Consistency):

    • 所有节点在同一时间看到的数据是划一的。
    • 每次读取都可以读取到最近写入的数据(或写入操纵发生的错误)。
    • 换句话说,在所有成功的写操纵之后,所有节点都应立即反映出雷同的数据。

  • 可用性 (Availability):

    • 每个请求都能吸收到非错误的相应——尽管它不保证返回最新写入的数据。
    • 系统始终处于运行状态,并且可以或许相应请求。
    • 换句话说,即使部分节点发生故障,系统仍然可以或许正常工作。

  • 分区容错性 (Partition Tolerance):

    • 系统可以或许在网络分区(即网络通讯中断,节点无法相互通讯)的情况下继承运行。
    • 分布式系统中存在网络分区时,仍然可以或许继承提供划一性和可用性(需要在划一性和可用性之间做权衡)。
    • 系统必须可以或许处理恣意数目的消息丢失或延长,并保证系统的正常运行。

  CAP 定理的核心结论:
  在一个分布式系统中,同时满意划一性、可用性和分区容错性这三者是不可能的,只能最多满意此中的两项:
  

  • CA(划一性 + 可用性): 系统在网络没有分区的情况下保证划一性和可用性。

    • 例子:传统的关系型数据库(如 MySQL 在单节点设置下),在网络分区出现时,系统无法继承正常工作。

  • CP(划一性 + 分区容错性): 系统在网络分区的情况下选择划一性,但牺牲了肯定的可用性。

    • 例子:Zookeeper、HBase 等系统在网络分区发生时,会拒绝部分请求来维持划一性。

  • AP(可用性 + 分区容错性): 系统在网络分区的情况下选择可用性,但可能牺牲划一性。

    • 例子:Cassandra、DynamoDB 等系统在网络分区时仍然能处理请求,但差异节点可能返回差异的数据(终极划一性)。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张裕

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表