1. 概述
服务之间通过注册中心进行远程调用时,需要实现服务注册和服务发现:
在上一篇文档中,我们实现了将服务注册到Nacos
,接下来我们学习如何在Nacos
实现服务发现。
服务发现是指在计算机网络上,(通常使用服务名)对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。
一般分为以下两种模式:
- 客户端发现模式:服务消费方(客户端)会定期在注册中心获取服务列表,在本地维护对应的服务注册表,在需要调用服务时,从本地注册表根据负载均衡策略选择合适的服务进行调用。
- 服务端发现模式:在需要调用服务时,服务消费方(客户端)直接向注册中心发起请求,注册中心通过相关策略选择合适的服务进行调用,服务消费方不需要维护服务信息。
2. Open API
在的基本架构图中,可以看到,服务提供和消费方都是通过Open API
和Nacos
进行交互的,消费方通过Open API
查询服务注册表以查找服务的可用实例:
/nacos/v2/ns/instance/list
查询指定服务下的实例详情信息列表:
{
"code":0,
"message":"success",
"data":{
"name":"DEFAULT_GROUP@@order-demo", // 分组名@@服务名
"groupName":"DEFAULT_GROUP", // 分组名
"clusters":"", // 集群名
"cacheMillis":10000, // 缓存时间
"hosts":[ // 实例列表
{
"ip":"192.168.142.1", // 实例IP
"port":9001, // 实例端口号
"weight":1, // 实例权重
"healthy":true, // 实例是否健康
"enabled":true, // 实例是否可用
"ephemeral":true, // 是否为临时实例
"clusterName":"DEFAULT", // 实例所在的集群名称
"serviceName":"DEFAULT_GROUP@@order-demo", // 服务名
"metadata":{ // 实例元数据
"preserved.register.source":"SPRING_CLOUD"
},
"ipDeleteTimeout":30000, // 实例删除超时时间
"instanceHeartBeatTimeOut":15000, // 实例心跳超时时间
"instanceHeartBeatInterval":5000 // 实例心跳间隔
}
],
"lastRefTime":1695347152335, // 上次刷新时间
"checksum":"", // 校验码
"allIPs":false, //
"reachProtectionThreshold":false, // 是否到达保护阈值
"valid":true // 是否有效
}
}
在实际开发中,业务代码调用远程服务时,肯定不需要我们手动去查询可用服务,而是集成相应的微服务组件,比如:
Dubbo
-
Open Feign
&Load Balancer
3. 集成 Open Feign & Load Balancer
3.1 简介
在服务之间进行远程调用,最易用的方式就是使用HTTP
客户端,根据服务名查询IP
及端口信息,然后发起Http
请求,但是自己这么写还是非常繁琐的。
而Feign
就是一个声明式服务调用组件,像调用本地方法一样调用远程方法,开发者完全感知不到这是远程方法,更感知不到这是个HTTP
请求。无需关注与远程的交互细节,更无需关注分布式环境开发。
Feign
最早是由Netfilx
网飞公司进行维护,但是前几年网飞停止了维护Eureka
、Hystrix
、Feign
、Ribbon
等项目,Feign
因此被转入到了社区维护,并更名为OpenFeign
,目前依然是Spring Cloud
的正式成员之一。
使用Feign
时,需要使用注解声明请求模板,发起请求时,将模板转为HTTP
请求,通过第三方HTTP
客户端进行调用,Open Feign
本身并不具备服务发现和负载均衡的能力,需要集成第三方组件,之前都是使用Ribbon
, 但是随着Ribbon
的停更,Spring Cloud
开发了自己的客户端负载均衡器,也就是Load Balancer
。
接下来我们使用Open Feign
加Load Balancer
集成Nacos
实现远程服务调用。
3.2 集成
在服务提供方order-demo
中,定义一个测试接口:
@RequestMapping("/order")
@RestController
public class OrderController {
@GetMapping("/getById")
public String getById(@RequestParam String orderId) {
return orderId;
}
}
服务消费方user-demo
添加Spring Cloud Open Feign & Load Balancer
依赖:
<!--Open Feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--客户端负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
user-demo
添加Feign
接口:
@FeignClient("order-demo")
public interface OrderFeignClient {
@GetMapping("/order/getById")
String getById(@RequestParam("orderId") String orderId);
}
user-demo
启动类添加@EnableFeignClients
注解开启扫描@FeignClient
注解扫描:
@EnableFeignClients
@SpringBootApplication
public class UserDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserDemoApplication.class, args);
}
}
3.3 测试
user-demo
测试类中,注入Feign
客户端并调用:
@SpringBootTest
class UserDemoApplicationTests {
@Autowired
OrderFeignClient orderFeignClient;
@Test
void feignTest() {
String id = orderFeignClient.getById("123456");
System.out.println(id);
}
}
启动Nacos
服务端、order-demo
,执行测试方法,成功返回,集成完毕。