Nacos服务注册和服务发现


title: Nacos服务注册和服务发现
tag: 笔记 微服务组件

image-20240321214956622

Nacos服务注册和服务发现

启动了一个Nacos注册中心之后,我们就可以将项目注册到注册中心,这样该服务的接口就给微服务的其它提供服务或者调用其它服务的接口。

主要包括两个部分的内容:

  • 服务注册
  • 服务发现

我们这里使用一个购物车和商品的服务来作为实例:购物车服务需要调用商品服务的接口

服务注册

我们先将商品模块item-service注册到Nacos注册中心。

大致步骤如下:

  • 引入依赖
  • 配置Nacos地址
  • 重启

添加依赖

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置Nacos

item-serviceapplication.yml中添加nacos地址配置:

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.12.136:8848

启动服务实例

Nacos还支持一个服务多个实例的情况,我们可以配置两个item-service的启动项。

image-20240321213928808

然后我们启动两个服务,查看Nacos服务管理:

image-20240321214125303

如此,我们就成功注册了一个服务到Nacos中。

服务发现

服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:

  • 引入依赖
  • 配置Nacos地址
  • 发现并调用服务

引入依赖

服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。

我们在cart-service中的pom.xml中添加下面的依赖:

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

可以发现,这里Nacos的依赖于服务注册时一致,这个依赖中同时包含了服务注册和发现的功能。因为任何一个微服务都可以调用别人,也可以被别人调用,即可以是调用者,也可以是提供者。

因此,等一会儿cart-service启动,同样会注册到Nacos

配置Nacos地址

cart-serviceapplication.yml中添加nacos地址配置:

spring:
  cloud:
    nacos:
      server-addr: 192.168.12.136:8848

发现并调用服务

接下来,服务调用者cart-service就可以去订阅item-service服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。

因此,服务调用者必须利用负载均衡的算法,从多个实例中挑选一个去访问。常见的负载均衡算法有:

  • 随机
  • 轮询
  • IP的hash
  • 最近最少访问

这里我们可以选择最简单的随机负载均衡。

另外,服务发现需要用到一个工具,DiscoveryClientSpringCloud已经帮我们自动装配,我们可以直接注入使用:

private final RestTemplate restTemplate;

private final DiscoveryClient discoveryClient;

其中RestTemplate可以通过请求提供服务的地址拿到数据。

下面是通过购物车的id去请求之前注册到Nacos的商品服务拿到对于的商品信息的逻辑:

private void handleCartItems(List<CartVO> vos) {
    //干掉之后修改
    // 1.获取商品id
    Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
    // 2.查询商品
    //2.1 根据服务名称获取服务的实例列表
    List<ServiceInstance> instances = discoveryClient.getInstances("item-service");
    if (CollUtil.isEmpty(instances)){
        return;
    }
    //2.2 手写负载均衡,从实力列表中挑选一个实例
    ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));

    //2.3 利用RestTemplate发起http请求,得到http响应
    ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(instance.getUri() + "/items?ids={ids}",
            HttpMethod.GET,
            null,
            new ParameterizedTypeReference<List<ItemDTO>>() {
            },
            CollUtils.join(itemIds, ","));
    //2.2 解析响应
    if (!response.getStatusCode().is2xxSuccessful()){
        //查询失败,直接结束
        return;
    }
    List<ItemDTO> items = response.getBody();
}

这里我们通过discoveryClient来获取商品服务的IP地址并通过restTemplate发起请求拿到数据完成了一次远程调用。

测试

然后我们可以将两个商品服务和购物车服务一起启动:

image-20240321214956622

然后我们通过PostMan发起请求:

[
    {
        "id": "7",
        "itemId": "100000006163",
        "num": 1,
        "name": "巴布豆(BOBDOG)柔薄悦动婴儿拉拉裤XXL码80片(15kg以上)",
        "spec": "{}",
        "price": 67100,
        "newPrice": null,
        "status": 1,
        "stock": 10,
        "image": "https://m.360buyimg.com/mobilecms/s720x720_jfs/t23998/350/2363990466/222391/a6e9581d/5b7cba5bN0c18fb4f.jpg!q70.jpg.webp",
        "createTime": "2023-05-20T21:07:09"
    }
]

“image”: “https://m.360buyimg.com/mobilecms/s720x720_jfs/t23998/350/2363990466/222391/a6e9581d/5b7cba5bN0c18fb4f.jpg!q70.jpg.webp”,
“createTime”: “2023-05-20T21:07:09”
}
]


可以看到我们成功通过远程调用拿到了购物车中的商品信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值