什么是Nacos???Nacos是干啥的???如何使用Nacos???

目录

1.引言:

2.服务调用

3.注册中心原理

3.1. 服务注册者(Service Registrar)

3.2. 服务消费者(Service Consumer)

3.3 注册中心(Service Registry)

4.Nacos注册中心

5.服务注册

5.1.添加依赖

5.2.配置Nacos

5.3.启动服务实例

6.服务发现

6.1.引入依赖

6.2配置Nacos地址

6.3.发现并调用服务

7.OpenFeign

7.1.引入依赖

7.1.1.spring-cloud-starter-openfeign

7.1.2.spring-cloud-starter-loadbalancer

7.2.启用OpenFeign

7.3.编写OpenFeign客户端

7.4.使用FeignClient

8.连接池

8.1.连接池的好处

8.2.OKHttp的优势

 8.3.引入依赖

8.4.开启连接池

9.总之:

 多练!多研!多学! 坚持!!!!!! 


1.引言:

在进行项目的微服务拆分中,不同的模块功能被拆分成了许多的微服务项目,服务拆分之后,不可避免的会出现跨微服务的业务,比如在业务中查询购物车业务模块时需要查询商品信息业务模块,而商品信息不在当前服务 ,此时微服务之间就需要进行远程调用

2.服务调用

微服务之间的远程调用被称为RPC,即远程过程调用。RPC的实现方式有很多,比如:

  • 基于Http协议

  • 基于Dubbo协议

使用的是Http方式,这种方式不关心服务提供者的具体技术实现,只要对外暴露Http接口即可,更符合微服务的需要。

Java发送http请求可以使用Spring提供的RestTemplate

在Spring框架中,RestTemplate默认使用Java的标准SimpleClientHttpRequestFactory作为底层的HTTP客户端实现。这个HTTP客户端实现是基于Java标准库中的HttpURLConnection来进行HTTP请求和响应的处理。RestTemplate来使用其他的HTTP客户端,比如Apache HttpClient或OkHttp等。这些客户端通常提供了更多的功能和配置选项,以满足特定的需求

RestTemplate可以方便的实现Http请求的发送,使用的基本步骤如下:

  • 注册RestTemplate到Spring容器

  • 调用RestTemplate的API发送请求,常见方法有:

    • getForObject:发送Get请求并返回指定类型对象

    • PostForObject:发送Post请求并返回指定类型对象

    • put:发送PUT请求

    • delete:发送Delete请求

    • exchange:发送任意类型请求,返回ResponseEntity

不过这种手动发送Http请求的方式存在一些问题。

试想一下,假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署,如图:

此时,每个item-service的实例其IP或端口不同,问题来了:

  • item-service这么多实例,cart-service如何知道每一个实例的地址?

  • http请求要写url地址,cart-service服务到底该调用哪个实例呢?

  • 如果在运行过程中,某一个item-service实例宕机,cart-service依然在调用该怎么办?

  • 如果并发太高,item-service临时多部署了N台实例,cart-service如何知道新实例的地址?

为了解决上述问题,就必须引入注册中心的概念了,接下来我们就一起来分析下注册中心的原理。

3.注册中心原理

在微服务远程调用的过程中,包括两个角色:

  • 服务提供者:提供接口供其它微服务访问,比如上面图片中item-service(购物模块)

  • 服务消费者:调用其它微服务提供的接口,比如上面图片中cart-service(商品模块)

在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下:

流程如下:

  • 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

  • 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)

  • 调用者自己对实例列表负载均衡,挑选一个实例

  • 调用者向该实例发起远程调用

当服务提供者的实例宕机或者启动新实例时,调用者如何得知呢?

  • 服务提供者会定期向注册中心发送请求,报告自己的健康状态(心跳请求)

  • 当注册中心长时间收不到提供者的心跳时,会认为该实例宕机,将其从服务的实例列表中剔除

  • 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表

  • 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表

简单理解就是

3.1. 服务注册者(Service Registrar)

例子:想象一个大型商场(微服务架构系统)中的商家(服务)。每个商家在开业前(服务启动时),都需要到商场的管理中心(注册中心)进行登记,告知自己的店铺名称(服务名称)、位置(IP地址和端口号)、营业时间(服务状态)等信息。这个登记的过程就是服务的注册。

作用:服务注册者的主要作用是将自己的信息(如服务名称、地址、端口等)注册到注册中心,以便其他服务(如服务消费者)能够找到并与之通信。通过注册,服务注册者成为了微服务架构中可被发现和调用的实体。

3.2. 服务消费者(Service Consumer)

例子:还是在这个大型商场中,顾客(服务消费者)想要去某家特定的餐厅(服务)用餐。他们不会直接去找餐厅的位置,而是会先查看商场的导览图(注册中心)或询问商场工作人员(服务发现机制),以获取餐厅的详细信息(如楼层、位置等)。

作用:服务消费者的主要作用是通过注册中心查找并调用所需的服务。在微服务架构中,服务消费者不需要知道服务提供者的具体地址,只需通过注册中心获取服务实例的列表,然后根据一定的策略(如负载均衡)选择一个实例进行通信。

3.3 注册中心(Service Registry)

例子:商场的管理中心(注册中心)负责维护所有商家的登记信息,并提供查询服务。当顾客需要找到某家餐厅时,管理中心会根据顾客的需求提供餐厅的详细信息。同时,管理中心还会定期检查商家的营业状态(健康检查),确保顾客能够找到并顺利使用服务。

作用:注册中心是微服务架构中的核心组件,它充当了服务注册者和服务消费者之间的中介。注册中心负责接收服务注册者的注册信息,并维护这些信息的准确性和实时性。同时,它还向服务消费者提供服务发现功能,帮助服务消费者找到并调用所需的服务。此外,注册中心还提供了健康检查、负载均衡等高级功能,以确保微服务架构的稳定性和可靠性。

4.Nacos注册中心

目前开源的注册中心框架有很多,国内比较常见的有:

  • Eureka:Netflix公司出品,目前被集成在SpringCloud当中,一般用于Java应用

  • Nacos:Alibaba公司出品,目前被集成在SpringCloudAlibaba中,一般用于Java应用

  • Consul:HashiCorp公司出品,目前集成在SpringCloud中,不限制微服务语言

以上几种注册中心都遵循SpringCloud中的API规范,因此在业务开发使用上没有太大差异。由于Nacos是国内产品,中文文档比较丰富,而且同时具备配置管理功能(配置共享配置热更新,搭配网关gateway动态路由都是比较重要的),因此在国内使用较多。

我们在虚拟机上通过Dacker来部署Nacos的注册中心。完成后启动页面如下

5.服务注册

5.1.添加依赖

item-servicepom.xml中添加依赖:

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

5.2.配置Nacos

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.xxx.xxx:8848 # nacos地址 修改为自己虚拟机地址

5.3.启动服务实例

访问nacos控制台,可以发现服务注册成功:

后续就可以通过注册中心来远程调用需要的端口了下面就是在cart-servic项目模块中来调用item-servic

6.服务发现

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

  • 引入依赖

  • 配置Nacos地址

  • 发现并调用服务

6.1.引入依赖

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

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

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

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

6.2配置Nacos地址

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

spring:
  cloud:
    nacos:
      server-addr: 192.168.xxx.xxx:8848

6.3.发现并调用服务

接下来,服务调用者cart-service就可以去订阅item-service服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。我们可以利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了这里我们直接使用OpenFeign

远程调用像本地方法调用一样简单。而这就要用到OpenFeign组件了。

其实远程调用的关键点就在于四个:

  • 请求方式

  • 请求路径

  • 请求参数

  • 返回值类型

所以,OpenFeign就利用SpringMVC的相关注解来声明上述4个参数,然后基于动态代理帮我们生成远程调用的代码,而无需我们手动再编写,非常方便。

7.OpenFeign

7.1.引入依赖

cart-service服务的pom.xml中引入OpenFeign的依赖和loadBalancer依赖:

  <!--openFeign-->
  <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>
7.1.1.spring-cloud-starter-openfeign

作用

  • spring-cloud-starter-openfeign 是Spring Cloud对Netflix的Feign客户端的封装,旨在简化微服务之间的HTTP调用。通过定义服务接口并使用注解的方式,可以轻松地调用其他服务提供的接口,就像调用本地方法一样。
  • 它集成了Ribbon(在Spring Cloud 2020.0及之前版本)或Spring Cloud LoadBalancer(在Spring Cloud 2020.x及之后版本)作为客户端负载均衡器,以支持服务的负载均衡。
  • 提供了声明式的Web服务客户端,让编写Web服务客户端变得更加简单。
  • 支持多种注解,如@FeignClient用于指定调用的服务名,@RequestMapping@GetMapping等用于定义具体的HTTP请求信息。

优点

  • 简化了微服务之间的调用。
  • 支持多种HTTP请求方式。
  • 提供了负载均衡的支持。
  • 易于集成和使用。
7.1.2.spring-cloud-starter-loadbalancer

作用

  • 从Spring Cloud 2020.0开始,spring-cloud-starter-loadbalancer 替代了Ribbon作为客户端负载均衡的实现。这是因为Ribbon已经进入了维护模式,并且不再接收新功能。
  • 它提供了基于Spring Framework 5的RestTemplateWebClient的客户端负载均衡支持。
  • spring-cloud-starter-loadbalancer与Spring Cloud Gateway的负载均衡器集成,提供了更灵活的负载均衡策略。

优点

  • 提供了与Spring Framework 5更好的集成。
  • 支持RestTemplateWebClient,使得负载均衡的配置更加灵活。
  • 提供了与Spring Cloud Gateway等项目的无缝集成。
  • 作为Ribbon的替代者,拥有更好的维护和未来支持。

7.2.启用OpenFeign

启动类上添加注解,启动OpenFeign功能:

为了接口的重利用也可以下定义一个新的module用来放这些抽取出来的公共接口,这样子避免重复编码,然后需要指定扫描公共所在的包即可

7.3.编写OpenFeign客户端

定义一个新的接口,编写Feign客户端:

其中代码如下:

package com.hmall.api.client;

import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
@FeignClient("item-service")

public interface ItemClient {
    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);

}

这里只需要声明接口,无需实现方法。接口中的几个关键信息:

  • @FeignClient("item-service") :声明服务名称

  • @GetMapping :声明请求方式

  • @GetMapping("/items") :声明请求路径

  • @RequestParam("ids") Collection<Long> ids :声明请求参数

  • List<ItemDTO> :返回值类型

有了上述信息,OpenFeign就可以利用动态代理帮我们实现这个方法,并且向http://item-service/items发送一个GET请求,携带ids为请求参数,并自动将返回值处理为List<ItemDTO>

我们只需要直接调用这个方法,即可实现远程调用了。item-service 就是我们模块的服务名字,根据服务名字就会从我们的注册中心中找到对应模块的端口,这样我们就可以实现远程调用了

7.4.使用FeignClient

直接调用ItemClient的方法

feign替我们完成了服务拉取、负载均衡、发送http请求的所有工作,是不是看起来优雅多了。

而且,这里我们不再需要RestTemplate了,还省去了RestTemplate的注册。

8.连接池

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:

  • HttpURLConnection:默认实现,不支持连接池

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http.

8.1.连接池的好处

  1. 性能提升:连接池通过重用现有的连接来减少创建和销毁连接的开销,这可以显著提高应用程序的性能,特别是在高并发场景下。

  2. 资源优化:频繁地创建和销毁连接会消耗大量的系统资源,如内存和CPU。使用连接池可以优化这些资源的使用,减少资源浪费。

  3. 响应时间缩短:由于连接池中的连接已经建立并准备好发送请求,因此可以更快地发送请求并接收响应,从而缩短应用程序的响应时间。

8.2.OKHttp的优势

除了支持连接池之外,OKHttp还有其他一些优势,这些优势也是选择它作为Feign底层HTTP客户端的原因之一:

  1. 现代和高效:OKHttp是一个现代的HTTP客户端,它使用最新的HTTP协议特性,如HTTP/2和SPDY(尽管现在HTTP/2已经取代了SPDY),以提供更高效的网络通信。

  2. 强大的功能:OKHttp提供了许多高级功能,如拦截器(Interceptors)、请求和响应的缓存、透明的GZIP压缩等,这些功能可以帮助开发者更轻松地处理复杂的网络请求。

  3. 广泛的社区支持:OKHttp是一个广泛使用的HTTP客户端,拥有庞大的用户社区和丰富的文档资源,这有助于开发者更快地解决问题和获取帮助。

  4. 与Retrofit的集成:OKHttp与Retrofit(另一个流行的RESTful API客户端)紧密集成,如果你的项目中已经使用了Retrofit,那么使用OKHttp作为Feign的底层HTTP客户端可能会更加自然和方便。

 8.3.引入依赖

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

8.4.开启连接池

application.yml配置文件中开启Feign的连接池功能:

feign:
  okhttp:
    enabled: true # 开启OKHttp功能

Debug方式启动cart-service,请求一次查询我的购物车方法,进入断点:跟踪源码:

底层就会是连接池这种模式,性能就会好很多!!!有时间还是可以多尝试跟踪学习下底层源码的实现,可以深入理解Java是如何在底层实现的。也可以提高我们的问题解决能力:当你在开发过程中遇到问题时,比如性能瓶颈、内存泄漏、难以理解的异常等,直接查看相关框架或库的源码可以帮助你快速定位问题原因。

9.总之

 多练!多研!多学! 坚持!!!!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何政@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值