
16 图 | 实战 Eureka 集群搭建+服务注册+调用(一)
大家好,我是悟空呀~
之前已经写过 7 篇 Eureka 注册中心的源码剖析和理论讲解相关的文章了,缺少一点实战。
本篇会带大家做一个实战案例,涉及内容:
• 配置服务注册到 Eureka 注册中心。
• 服务之间通过注册的服务名来访问。
• 本地如何搭建 Eureka 集群。
• 本地如何搭建微服务集群。
• 如何用 Ribbon 实现负载均衡。
目录
之前的几篇 Eureka 文章也汇总下:
本文已同步至我的个人网站:www.passjava.cn
一、基本原理
注册 + 服务调用
先上原理图:下面说下原理图中对应的场景:
场景:
• 有一个订单服务部署在一台机器上,另外有两个商品服务部署在一台机器上,三个服务的端口都不一样。
• 商品服务和订单服务都将自己的地址信息注册到 Eureka,Eureka 把这些信息都缓存到注册表中。
• 当订单服务想要调用商品服务时,其实是先从 eureka 上获取商品服务的地址信息。
• 订单服务向两个商品服务发送 HTTP 请求。
服务宕机
当有一个商品服务宕机后,eureka 会把这个服务的注册信息移除掉,订单服务也不会调用这个商品服务。下面我们按照上面服务调用的场景来简单使用下 Eureka。
需求:首先有一个订单服务 OrderService,一个商品服务 ProductService, 订单服务不知道商品服务的 IP 地址,只知道商品服务的 的名字,订单服务通过向 Eureka 注册中心获取到了商品服务的具体 IP 地址,然后成功调用商品服务的的 getProduct API。
二、创建 Eureka Server
总共会启动 4 个微服务,如下图所示:首先创建一个 Eureka 服务。
前提条件:Spring Cloud 基于 Hoxton.SR10 版本,Spring Boot 基于 2.3.2.RELEASE。
启动类
创建启动类,Eureka Server 就是这个类启动的。
/**
* @Author: 公众号 | 悟空聊架构
* @Date: 2021/9/13 7:28
* @Site: www.passjava.cn
* @Github: https://github.com/Jackson0714/eureka-learning
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置项
然后配置下 Eureka Server 的基本信息。配置信息可以放到 application.yml 文件中。
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
port:Eureka Server 监听的端口。
register-with-eureka: 是否把自己注册到 Eureka,单机情况下,不需要注册自己。
fetch-registry: 是否到 Euraka 服务抓取注册信息。
pom.xml 文件
首先需要配置 pom.xml 文件,引入 Eureka 依赖。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
启动
接下来启动 Eureka Server 的控制台。浏览器访问 http://localhost:8761/ 就可以看到控制台了。
因为还没有服务注册到 Eureka,所以控制台中的服务列表是空的。三、创建商品服务
application.yml 配置
商品服务对应的端口为 8006 和 8007,可以先启动一个商品服务,然后修改端口后,再启动另外一个商品服务。
server:
port: 8006
spring:
application:
name: ProductService
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
Controller 类
定义了获取商品的 API,提供给订单服务调用。
/**
* 订单服务的接口
*
*/
@RestController
public class ProductServiceController {
/**
* 订单服务
* @param name 商品名称
* @return 测试返回商品名
*/
@RequestMapping(value = "/product/{name}",
method = RequestMethod.GET)
public String getProduct(@PathVariable("name") String name) {
System.out.println("商品服务被调用了");
return "order" + name;
}
}
启动类
用来启动商品服务。
/**
* 商品服务
* @Author: 公众号 | 悟空聊架构
* @Date: 2021/9/13 7:28
* @Site: www.passjava.cn
* @Github: https://github.com/Jackson0714/eureka-learning
*/
@SpringBootApplication
@EnableEurekaClient
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
pom.xml 文件
引入 Eureka Client 依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
测试商品服务是否正常启动
先按照 8006 端口启动一个商品服务,然后按照 8007 端口启动另外一个商品服务。
Eureka 控制台可以看到两个商品服务已启动。测试访问商品服务
用 Postman 工具进行测试:
http://localhost:8006/getProduct/悟空聊架构专属商品
返回结果:四、创建订单服务
订单服务和商品服务的区别
• 多了一个 Ribbon 依赖。
• 订单服务会调用商品服务。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
订单服务调用商品服务的 API
@RestController
@Configuration
public class OrderServiceController {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
/**
* 根据订单 id 查找商品信息
* @param id 订单 id
* @return 商品服务返回的数据
*/
@RequestMapping(value = "/order/{id}", method = RequestMethod.GET)
public String getOrder(@PathVariable("id") String id) {
RestTemplate restTemplate = getRestTemplate();
return restTemplate.getForObject("http://ProductService/product/" + id, String.class);
}
}
我们看到有一个 @LoadBalanced 注解,这里做下说明:
RestTemplate 用来实现单个 http 请求的,加了 @LoadBalanced 注解后,就可以实现负载均衡。
负载均衡的原理可以这篇:
测试
启动订单服务,IDEA 中可以看到订单服务:可以在 eureka 控制台看到订单服务在注册列表上。
测试访问订单 API
http://localhost:9091/order/悟空聊架构专属商品
测试结果:说明订单服务 OrderService 通过 Eureka 拿到了的商品服务 ProductService 的 URL 信息,然后成功调用商品服务。如下 URl 所示,只知道商品服务的名字 ProductService,但是不知道具体的 IP 地址。
http://ProductService/product/
通过 Eureka 的注册表信息获取到了具体的 IP 地址。
192.168.10.197:ProductService:8007
192.168.10.197:ProductService:8006
Eureka + 商品服务 + 订单服务 的演示案例已经完成。
接下来我们看下怎么把两个 Eureka Server 组成 Eureka 集群。
