【微服务专题】nacos的服务注册和发现实战

前言

  通过上一篇文章关于Nacos的搭建和启动,这篇文章将从如何将服务注册 到Nacos上并如何从Nacos上发现服务 两个方式讲解Nacos的实际使用,在介绍使用前,会通过一个简单介绍关于微服务版本的选用。那么,现在就开始我们的微服务实战之旅吧。

1. 微服务版本的选择

  本专题主要是使用Alibaba微服务体系的组件来搭建微服务架构,从本篇开始到后面的文章都是使用同一系列的版本。关于微服务各组件的版本,阿里也出了一个比较详细的版本说明文档,这里就再具体说明了,感兴趣直接点击链表查看,下面就直接列出来本专题将使用的版本号:

  • jdk Version:jdk17
  • Spring Cloud Version : 2022.0.0
  • Spring Boot Version: 3.0.2
  • Spring Cloud Alibaba Version: 2022.0.0.0
  • Nacos Version: 2.2.1
  • Sentinel Version:1.8.6
  • RocketMQ Version: 4.9.4
  • Seata Version: 1.7.0

2. 服务示例工程

  为了讲解服务的注册和发现,本文使用了两个微服务,一个是用户服务,另外一个是订单服务。两个服务都是可以单独提供api服务的springboot web应用,不同的是只能查询各自的服务,如果想通过用户服务里需要查询某个用户的订单,就需要再用户服务里调用订单服务的接口,这就是我们需要使用nacos完成的一个操作。

2.1 工程的架构

示例工程分三个模块:common(公共依赖),order(订单服务),user(用户服务):
在这里插入图片描述
最外层的pom主要是对微服务依赖的版本控制,需要引用主要的依赖:

<properties>
        <java.version>17</java.version>
        <spring-boot.version>3.0.2</spring-boot.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
        <spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2.2 集成nacos服务注册和发现步骤

2.2.1 添加pom依赖

以订单服务工程为例,只需在pom依赖中添加nacos的依赖

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

2.2.2 启动注解

在启动类添加@EnableDiscoveryClient注解,非必须,因为该版本的依赖被引入后会自动开启该注解。

2.2.3 修改项目的配置

修改 application.yml 文件,添加项目名称nacos的服务地址

spring:
  application:
    name: order
  cloud:
    nacos:
      discovery:
        server-addr: http://192.168.1.2:8848

2.2.4 启动和查看控制台

启动时,通过添加虚拟机的参数来控制服务需要启动的端口,在idea可以打开下面的配置面板进行设置
在这里插入图片描述
项目启动后,查看nacos控制台服务列表
在这里插入图片描述

3. 服务注册

按照前面的部署流程,完成一个服务部署两个实例的结构:
在这里插入图片描述
提示:使用idea可以通过复制配置的方式直接拷贝服务,拷贝后记得修改运行参数
在这里插入图片描述

注册完后可以在Nacos控制台查看服务列表
在这里插入图片描述

3.1 服务注册测试

除了从控制台可以查看服务的注册情况,还可以通过nacos提供的api来查询注册的结果,访问服务列表接口:

http://192.168.1.2:8848/nacos/v2/ns/instance/list?serviceName=order-service

返回结果:
在这里插入图片描述

至此我们的服务注册就已经集成完成,后面将介绍如何通过nacos进行服务之间的调用。

4. 服务发现/调用

4.1 需求说明

在order服务中有这个api,可以通过用户id查询所属的所有订单信息:
在这里插入图片描述
现在需要在user服务中请求该接口:http://192.168.1.2:8180/order/all-order/1
或者是
http://192.168.1.2:8181/order/all-order/1

4.2 传统方式调用

传统方式直接使用内置的RestTemplate 工具就可以访问,先注入Bean

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

controller中发起请求:

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("all-order/{id}")
    public Object getAllOrderByUserId(@PathVariable("id") Integer userId) {
        String url = "http://192.168.1.2:8180/order/all-order/" + userId;
        return restTemplate.getForEntity(url, Object.class);
    }

浏览器输入:http://192.168.1.2:8280/user/all-order/1
在这里插入图片描述
虽然可以正常请求到order服务查询到数据,但是该方式存在下面的缺点:

  1. 请求具体服务的时候需要硬编码
  2. 可读性差,当参数比较复杂时难以维护

4.3 使用LoadBalancer结合RestTemplate请求

使用@LoadBalanced注释修饰注册一个RestTemplatebean

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

controller使用LoadBalanced提供的自动替换:

	@Autowired
    private RestTemplate restTemplate;
	@RequestMapping("all-order/{id}")
    public Object getAllOrderByUserId(@PathVariable("id") Integer userId) {
        String url = "http://order/order/all-order/" + userId;
        return restTemplate.getForEntity(url, Object.class);
    }

如果服务调用时报下面的错误信息,则说明没有引用LoadBalanced相关的依赖

java.net.UnknownHostException: order-service
	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567) ~[na:na]
	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
	at java.base/java.net.Socket.connect(Socket.java:583) ~[na:na]
	at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183) ~[na:na]
	at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:531) ~[na:na]
	at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:636) ~[na:na]
	at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:279) ~[na:na]
	at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:384) ~[na:na]

在nacos版本,查看是否有LoadBalanced的依赖,像我下面的就是没有引用依赖的:
在这里插入图片描述
所以需要单独引用

<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

相比较传统方式,这种方式也是同样有难以维护,特别是参数比较复杂的情况下,并且url也是属于硬编码,可读性比较差。

4.4 Spring Cloud OpenFeign 服务调用

  Spring Cloud OpenFeign 是 Spring Cloud 在 Netflix OpenFeign 的基础上提供的一个声明式的 Web 服务客户端。它使得编写 Web 服务客户端变得更加简单,只需通过简单的接口与注解即可。本文只做简单的集成,更加详细的使用会有新的文章来阐述。

4.4.1 引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

4.4.2 开启注解

在springboot启动类添加注解

@SpringBootApplication
@EnableFeignClients
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4.4.3 编写客户端(接口)

order-service服务有一个接口: /order/all-order/{id}

@RequestMapping("all-order/{id}")
 public Object getAllOrderByUserId(@PathVariable("id") Integer userId) {
     QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
     queryWrapper.eq("user_id", userId);
     return orderMapper.selectList(queryWrapper);
 }

所以在user-service服务中可以写成

package com.sch.user.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "order-service", path = "/order")
public interface OrderRemoteService {
    @RequestMapping("all-order/{id}")
    public Object getAllOrderByUserId(@PathVariable("id") Integer userId);
}

@FeignClient注解对应的就是openfeign客户端接口的申明,value对应在nacos注册服务的名称,path是可选的参数,表示该接口类有统一的路径。

4.4.4 调用测试

使用时就跟调用本地服务一样调用

@Autowired
private OrderRemoteService orderRemoteService;

@RequestMapping("all-order/{id}")
public Object getAllOrderByUserId(@PathVariable("id") Integer userId) {
    return orderRemoteService.getAllOrderByUserId(userId);
}

总结

  本文详细探讨了微服务注册发现的实践方面。首先涉及微服务版本的选择,随后深入介绍了服务示例工程,并展示如何集成nacos进行服务注册和发现。文章还详述了服务的注册过程,并比较了不同的服务发现与调用方法,特别是利用Spring Cloud OpenFeign的调用技巧。希望能为读者提供了一个实用的微服务操作指南。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值