个人技术分享

1. 概述

服务之间通过注册中心进行远程调用时,需要实现服务注册和服务发现:
在这里插入图片描述

在上一篇文档中,我们实现了将服务注册到Nacos,接下来我们学习如何在Nacos实现服务发现。

服务发现是指在计算机网络上,(通常使用服务名)对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。

一般分为以下两种模式:

  • 客户端发现模式:服务消费方(客户端)会定期在注册中心获取服务列表,在本地维护对应的服务注册表,在需要调用服务时,从本地注册表根据负载均衡策略选择合适的服务进行调用。
  • 服务端发现模式:在需要调用服务时,服务消费方(客户端)直接向注册中心发起请求,注册中心通过相关策略选择合适的服务进行调用,服务消费方不需要维护服务信息。

2. Open API

官网 Open API 文档

在的基本架构图中,可以看到,服务提供和消费方都是通过Open APINacos进行交互的,消费方通过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网飞公司进行维护,但是前几年网飞停止了维护EurekaHystrixFeignRibbon等项目,Feign因此被转入到了社区维护,并更名为OpenFeign,目前依然是Spring Cloud的正式成员之一。

使用Feign时,需要使用注解声明请求模板,发起请求时,将模板转为HTTP请求,通过第三方HTTP客户端进行调用,Open Feign本身并不具备服务发现和负载均衡的能力,需要集成第三方组件,之前都是使用Ribbon, 但是随着Ribbon的停更,Spring Cloud开发了自己的客户端负载均衡器,也就是Load Balancer

接下来我们使用Open FeignLoad 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,执行测试方法,成功返回,集成完毕。