《Spring Cloud学习笔记:Nacos配置管理 & OpenFeign & Getway》

发布时间:2023年12月25日
  • 基于Feign的声明式远程调用(代码更优雅),用它来去代替我们之前的RestTemplate方式的远程调用

1. Nacos配置管理

  • Nacos除了可以做注册中心,同样也可以做配置管理来使用。?
  • 利用Nacos实现统一配置管理以及配置的热更新:解决微服务的配置文件重复和配置热更新问题

1.1 统一配置管理

  • 配置的热更新:服务不用重启配置就可以生效。?

当微服务部署的实例越来越多时,逐个修改微服务配置就会效率低下,而且很容易出错,所以我们需要一种统一配置管理方案,可以集中管理所有实例的配置。

而Naocs除了可以做注册中心,同样也可以做配置管理来使用:

  • Nacos一方面可以将配置集中管理,另一方面可以在配置变更时,及时通知微服务,实现配置的热更新。?

在nacos中添加配置文件:把配置交给Nacos去实现配置的统一管理

如何在nacos中管理配置呢?

然后在弹出的表单中,填写配置信息:

注意:
  • 项目的核心配置,需要热更新的配置才有放到nacos管理的必要基本不会变更的一些配置还是保存在微服务本地比较好。 ?

从微服务拉取配置

微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动:

  • 但是Nacos地址是配置在application.yml当中,我们先读取Nacos中的配置文件之前,要先获取Nacos的地址,那如何得知Nacos的地址呢??

因此Spring引入了一种新的配置文件:bootstrap.yml文件,会在application.yml之前被读取,流程如下:?

  • bootstrap.yml的配置文件的优先级会比application.yml配置文件的优先级要高很多。
  • 与Nacos地址和配置文件相关的所有信息都应该放在bootstrap.yml当中。

1. 引入nacos-config依赖:引入Nacos的配置管理依赖

  • 在服务消费者中的pom.xml中引入依赖?
<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2. 在resource目录中添加一个bootstrap.yml文件,这个文件是引导文件,它的优先级高于? ? ? ? ? ? ? ? application.yml

配的就是Data ID:?

spring:
  application:
    name: userservice # 配置服务名称
  profiles:
    active: dev #开发环境,这里是dev 
  cloud:
    nacos:
      server-addr: localhost:8848 # 配置Nacos地址
      config:
        file-extension: yaml # 文件后缀名

3. 读取nacos配置

在user-service中的UserController中添加业务逻辑,读取pattern.dateformat配置:

针对于本例用来格式化时间

?

?

1.2 配置热更新

  • 我们最终的目的,是修改nacos中的配置后,微服务无需重启即可让配置生效,也就是配置热更新。 ?

要实现配置热更新,可以使用两种方式:需要通过下面两种配置实现

方式一:在@Value注入的变量所在类上添加注解@RefreshScope

方式二:使用@ConfigurationProperties注解代替@Value注解 ?

  • 需要自定义配置类

1.3 多环境配置共享

当nacos、服务本地同时出现相同属性时,多种配置的优先级有高低之分:

  • 本地配置的优先级是最低的,而线上配置也就是Nacos中的配置是更高一点儿的。
  • 当前环境的配置肯定要比多环境共享配置的优先级更高。?

1.4 搭建Nacos集群

  • 注意:Nacos生产环境下一定要部署为集群状态~!
  • SLB指的是负载均衡器

2. OpenFeign远程调用

  • http客户端Feign

RestTemplate方式调用存在的问题:

  • 代码可读性差,编程体验不统一
  • 遇到参数复杂的URL难以维护

Feign的介绍

其作用就是帮助我们优雅的实现HTTP请求的发送~!

OpenFeign的介绍

OpenFeign是一个声明式的HTTP客户端,是Spring Cloud在Eureka公司开源的Feign基础上改造而来,官方地址:https://github.com/OpenFeign/feign?

其作用就是基于SpringMVC的常见注解,帮我们优雅的实现http请求的发送~!

OpenFeign快速入门?

OpenFeign已经被Spring Cloud自动装配,实现起来非常简答:

  1. 引入依赖,包括OpenFeign和负载均衡组件SpringCloudLoadBalancer?
        <!--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>

旧版本中用的才是Ribbon,新版本中用的都是loadbalancer。?

2. 在启动类通过添加@EnableFeignClients注解,启用OpenFeign功能

?

编写OpenFeign客户端

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

其中代码如下:

package com.hmall.cart.client;

import com.hmall.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

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

使用FeignClient?
  • feign替我们完成了服务拉取、负载均衡、发送http请求的所有工作,而且,这里我们不再需要RestTemplate了,还省去了RestTemplate的注册。?

OpenFeign连接池

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

  • HttpURLConnection:默认实现,不支持连接池 => 每一次都需要重新创建连接,因此效率极低

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

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

引入依赖:?

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

开启连接池:

  • application.yml配置文件中开启Feign的连接池功能
feign:
  okhttp:
    enabled: true # 开启OKHttp功能

重启服务,连接池就生效了。?

所谓最近实践,就是使用过程中总结的经验,最好的一种使用方式。 ??

日志配置

OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:

  • NONE不记录任何日志信息,这是默认值。

  • BASIC(推荐)仅记录请求的方法,URL以及响应状态码和执行时间

  • HEADERS在BASIC的基础上,额外记录了请求和响应的头信息

  • FULL记录所有请求和响应的明细,包括头信息、请求体、元数据。

Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。

要自定义日志级别需要声明一个类型为Logger.Level的Bean,在其中定义日志级别:

  • 也可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象

public class DefaultFeignConfiguration  {
 ? ?@Bean
 ? ?public Logger.Level feignLogLevel(){
 ? ? ? ?return Logger.Level.BASIC; // 日志级别为BASIC
 ?  }
}

如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:

@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 

如果是局部生效,则把它放到对应的@FeignClient这个注解中:

@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 

3. Getway服务网关?

  • 统一网关Getway

由于每个微服务都有不同的地址或端口,入口不同,在与前端做联调时会发现:

  • 请求不同数据时要访问不同的入口,需要维护多个入口地址,麻烦
  • 前端无法调用Nacos,无法实时更新服务列表

单体架构时我们只需要完成一次用户登录、身份校验,就可以在所有业务中获取到用户信息,而微服务拆分后,每个微服务都独立部署,这就存在一些问题:

  • 如果没有网关做校验,微服务直接摆在那里,允许任何人都可以来请求访问,这是不安全的
  • 如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用,这样无疑增加了代码编写的复杂性
  • 服务地址过多,而且将来可能变化,前端不知道该请求谁?
  • 认证复杂,每个服务都需要独立认证:每个服务都可能需要登录用户信息,难道每个微服务都需要编写JWT登录校验、用户信息获取的功能吗?
  • 当微服务之间调用时,该如何传递用户信息?

可以通过API网关技术来解决上述问题。

网关概述?

网关的核心功能特性?

网关就是网络的关口,是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,负责请求的路由 => 服务路由(告诉你在几楼几号这叫做路由)、转发(你找不着带你过去这叫做转发)以及用户登录时的身份校验(身份认证和权限校验,做过滤拦截)(检查你户口本)

数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验。

网关的作用:

网关是所有微服务的统一入口?

  1. 对用户请求做身份认证、权限校验
  2. 将用户请求路由到微服务,并实现负载均衡
  3. 对用户请求做限流?

?

  • 网关路由:解决前端请求入口的问题
  • 网关鉴权:解决统一登录校验和用户信息获取的问题

?更通俗的来讲,网关就像是以前园区传达室的大爷。

  • 外面的人要想进入园区,必须经过大爷的认可,如果你是不怀好意的人,肯定被直接拦截。

  • 外面的人要传话或送信,要找大爷。大爷帮你带给目标人。

现在,服务网关就起到同样的作用,前端请求不能直接访问微服务,而是要请求网关:

  • 网关可以做安全控制,也就是做登录身份校验,网关作为微服务入口,需要校验用户是否有请求资格,校验通过才放行,如果校验不通过则需要进行拦截
  • 一切请丢都必须先经过网关,但网关不处理业务,通过网关认证后,网关再根据前端的请求判断应该访问哪个微服务,这个判断的过程就是请求路由,然后再将请求转发过去,转发到具体的微服务,当路由的目标服务有多个时,还需要做负载均衡
  • 网关它也是一个微服务,网关也是需要将自己的信息注册到注册中心上,并且网关会去注册中心去拉取所有的服务地址
  • 有了网关以后,我们微服务的地址再也不需要暴露给前端了,要暴露给前端的仅仅是网关地址,这对于微服务来讲也是一种保护,而且,对前端来讲,由于它只知道网关地址,因此整个微服务对它来讲是隐藏的,是一个黑盒的,也就是说在前端看来,后端跟原来的单体架构其实是没什么区别的,这样它的开发体验也是一致的
  • 一切请求,一定要先到网关,再到微服务~!
  • 限流:当请求流量过高时,在网关中按照下游的微服务能够接受的速度来放行请求,避免服务压力过大

如果微服务有做集群,网关还要进行负载均衡:?

在Spring Cloud当中,提供了两种网关的实现方案:

  • Netfilx Zuul:它是Netflix出品,基于Servlet的阻塞式编程,早期实现,目前已经淘汰,需要调优才能获得与Spring Cloud Getway类似的性能
  • Spring Cloud Getway:Spring官方出品,基于Spring 5 中提供的的WebFlux技术,完全支持响应式编程,属于响应式编程的体现 => 基于WebFlux的响应式编程,吞吐能力更强,具备更好的性能,无需调优即可获得优异性能
注意:
  • Spring Cloud Alibaba技术栈中并没有提供自己的网关,我们可以采用Spring Cloud Getway来做网关。

?

文章来源:https://blog.csdn.net/weixin_53622554/article/details/135173545
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。