> 技术文档 > 如何用Eureka实现服务注册?手把手教你订单调用商品服务

如何用Eureka实现服务注册?手把手教你订单调用商品服务


一、背景引入

1.1、单体架构

        本文将介绍微服务架构。在此之前,我们采用的都是单体架构模式,即将前端、后端和数据库等所有功能模块都打包在同一个项目中,最终生成单个 war 包或 jar 包,这种架构方式就被称为单体架构

        这种架构开发部署便捷,单个项目即可集成所有功能,避免了多项目间的交互与调用损耗。但随着用户量增长,请求量激增会导致服务器压力加大。当负载达到临界点时,可能出现服务不可用的情况。此外,每次功能更新或新增都需要重新构建和发布整个项目,甚至细微的bug也可能导致整个应用崩溃。为此,我们引入了分布式系统架构

1.2、分布式系统架构

        当前场景:我们创建了一个父子工程,子工程包含订单系统和商品系统,功能仅实现了订单系统远程调用商品系统:

1.3、注册中心

1.3.1、三种角色:

服务提供者(Server)
        在业务交互中,提供接口供其他微服务调用的服务方


服务消费者(Client)
        在业务交互中,主动调用其他微服务接口的服务方


服务注册中心(Registry)
        负责维护服务提供者的注册信息,实时同步服务节点变更状态。注册中心与服务之间通过心跳机制保持通信,若长时间无法建立连接,将自动注销该服务实例

1.3.2、核心工作机制:

服务注册
        服务提供者启动时,向注册中心完成服务注册,并通过定期心跳上报存活状态


服务发现
        服务消费者从注册中心获取服务提供者的地址信息,并据此发起服务调用。该机制的核心价值在于为消费者动态维护可用的服务列表

1.4、CAP理论

        CAP理论指出:分布式系统无法同时满足 数据一致性(Consistency)、服务可用性(Availability) 分区容错性(Partition Tolerance)这三个基本要求,只能实现其中两项的平衡

        由于分布式系统中网络故障不可避免,而服务又必须保持可用状态,因此分区容错性成为必须保证的特性,这就意味着我们只能在一致性和可用性之间做出选择,从而形成 CP 或 AP 两种不同的系统架构

        常见的注册中心有ZookeeperEureka Nacos ,本篇我们来讲解 Eureka

二、Eureka 介绍

        Eureka 是 Netflix OSS 套件中提供的服务注册与发现解决方案。Spring Cloud 对其进行了集成,并作为首选方案进行推广。虽然目前 Eureka 2.0 已停止维护,且在新的微服务架构设计中不再推荐使用,但仍有大量企业的微服务系统采用 Eureka 作为注册中心

官方文档:https://github.com/Netflix/eureka/wiki

Eureka 主要由两部分组成:

  • Eureka Server:作为注册中心的服务器端,为微服务应用提供服务注册、发现和健康检查等功能
  • Eureka Client:作为服务提供方,在启动时会向 Eureka Server 注册自身信息(包括IP地址、端口和服务信息等),这些信息会被 Eureka Server 存储

学习 Eureka 主要包含以下三个部分:

  1. 搭建 Eureka Server
  2. 将 order-service 和 product-service 注册到 Eureka
  3. 实现 order-service 远程调用时从 Eureka 获取 product-service 的服务列表并进行交互

三、搭建 Eureka Server

3.1、创建项目

        创建子项目,右键父项目 -> 选择Module -> 新建Java项目即可

3.2、pom引入Eureka的依赖

   org.springframework.cloud spring-cloud-starter-netflix-eureka-server      org.springframework.boot spring-boot-maven-plugin   

3.3、配置文件

        在resource文件目录下,创建appication.yml配置文件,并添加如下:

# Eureka相关配置# Eureka 服务server: port: 10010spring: application: name: eureka-servereureka: instance: hostname: localhost client: fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false. service-url: # 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.4、启动类

        创建启动类,并添加@EnableEurekaServer注解,开启注册中心服务

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

        运行该程序,并访问http://127.0.0.1:10010/ 观察到下图,证明Eureka注册中心搭建完成!

四、服务注册

        此处针对服务提供者——商品系统项目

4.1、加入Eureka的依赖

 org.springframework.cloud spring-cloud-starter-netflix-eureka-client

4.2、修改配置信息

server: port: 9090spring: application: name: product-service datasource: url: jdbc:mysql://127.0.0.1:3306/cloud_product?characterEncoding=utf8&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver# 设置 Mybatis 的 xml 保存路径mybatis: mapper-locations: classpath:mapper/*Mapper.xml configuration: # 配置打印 MyBatis 执行的 SQL log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true #自动驼峰转换#Eureka Clienteureka: client: service-url: defaultZone: http://127.0.0.1:10010/eureka/ 

4.3、观察结果

        我们也启动商品系统程序:

五、服务发现

5.1、加入Eureka依赖

 org.springframework.cloud spring-cloud-starter-netflix-eureka-client

5.2、修改配置信息

server: port: 8080spring: application: name: order-service datasource: url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver# 设置 Mybatis 的 xml 保存路径mybatis: mapper-locations: classpath:mapper/*Mapper.xml configuration: # 配置打印 MyBatis 执行的 SQL log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true #自动驼峰转换#Eureka Clienteureka: client: service-url: defaultZone: http://127.0.0.1:10010/eureka/

5.3、修改远程调用代码

@Slf4j@Servicepublic class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private RestTemplate restTemplate; @Autowired private DiscoveryClient discoveryClient; public OrderInfo selectOrderById(Integer orderId) { OrderInfo orderInfo = orderMapper.selectOrderById(orderId);// String url=\"http://127.0.0.1:9090/product/\"+orderInfo.getProductId(); //从Eureka中获取服务列表 List instances = discoveryClient.getInstances(\"product-service\"); String uri = instances.get(0).getUri().toString(); String url=uri+\"/product/\"+orderInfo.getProductId(); log.info(\"远程调用URL:{}\",url); ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class); orderInfo.setProductInfo(productInfo); return orderInfo; }}

5.4、观察结果

        刷新注册中心:Eureka ,可以看到order-service已经注册到eureka上了

        访问:127.0.0.1:8080/order/1 可看到,远程调用成功了