深入理解SpringCloud之Zuul

引言

在微服务里,系统通常被拆分成许多小的、独立的服务,每个服务都有自己的职责和生命周期。但这么多服务怎么协同工作呢?这就需要一个交通警察来指挥交通,确保数据能安全、高效地流动。在Spring Cloud生态系统中,这个角色就是由Zuul来扮演的。

Zuul是Netflix开发的一款提供动态路由、监控、弹性、安全等边缘服务的网关。咱们可以把它想象成微服务架构中的大门,所有进出的请求都要经过这扇门。这样做的好处是显而易见的,比如,可以在网关层面统一进行身份验证、权限校验,或者把常见的响应缓存起来,减轻后端服务的压力。

举个例子,如果咱们有个电商平台,包括商品服务、订单服务和用户服务等多个微服务。用户的请求首先到达Zuul,Zuul根据请求的类型,决定是把请求路由到商品服务、订单服务还是用户服务。这样不仅简化了客户端的逻辑,还能灵活地管理服务之间的通信。

Zuul的基础:核心概念和架构

说到Zuul,咱们不能不提它的核心——过滤器。Zuul的过滤器是它实现灵活路由、安全等功能的基石。过滤器可以做很多事,比如修改请求头和响应头、记录请求日志、校验请求参数等。

Zuul的工作流程大致可以分为四个阶段:PRE(前置过滤器)、ROUTING(路由过滤器)、POST(后置过滤器)和ERROR(错误过滤器)。每个请求在通过Zuul时,都会依次经过这些过滤器。

  • PRE过滤器用于在路由请求之前执行,比如安全校验、日志记录。
  • ROUTING过滤器则决定请求的路由路径。
  • POST过滤器在请求被路由到具体服务后执行,用于添加响应头、收集统计信息等。
  • ERROR过滤器用于处理请求流程中发生的异常。

下面是一个简单的示例,展示如何使用Java创建一个PRE类型的过滤器,用于在请求被路由之前记录请求信息:

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;// 自定义一个前置过滤器
public class PreLogFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre"; // 表示这是一个前置过滤器}@Overridepublic int filterOrder() {return 1; // 定义过滤器的执行顺序}@Overridepublic boolean shouldFilter() {return true; // 表示这个过滤器需要执行}@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();// 记录下请求的HTTP方法和请求地址System.out.println("请求进来了,方法:" + request.getMethod() + " 地址:" + request.getRequestURL().toString());return null;}
}

通过上面的代码,咱们定义了一个简单的前置过滤器,它会在请求被路由之前记录下请求的方法和URL。

快速入门:搭建你的第一个Zuul网关

既然已经了解了Zuul在微服务架构中的作用以及它的核心概念,现在咱们来动手实践,一起搭建第一个Zuul网关。通过这个实践,咱们能更加深入地理解Zuul的工作方式和如何在项目中使用它。

咱们需要创建一个Spring Boot应用。在这个应用中,咱们将引入Zuul依赖,这样才能使用Zuul提供的网关功能。接下来,咱们就一步步来完成这个任务。

步骤1:创建Spring Boot项目

使用你喜欢的IDE或者Spring Initializr网站创建一个新的Spring Boot项目。在创建项目时,需要添加spring-cloud-starter-netflix-zuul依赖。这个依赖是使用Zuul作为网关的关键。

步骤2:配置Zuul代理

在咱们的Spring Boot应用的application.yml(或者application.properties)配置文件中,添加Zuul的配置信息。这里咱们定义一些路由规则,告诉Zuul如何将请求转发到不同的后端服务。

zuul:routes:user-service:path: /user/**url: http://localhost:8000/order-service:path: /order/**url: http://localhost:8001/

在这个配置中,咱们定义了两个服务的路由规则。如果请求的路径以/user开头,那么这个请求会被转发到运行在8000端口的用户服务。同理,以/order开头的请求会被转发到运行在8001端口的订单服务。

步骤3:启用Zuul代理

在咱们的Spring Boot应用的主类上添加@EnableZuulProxy注解,以启用Zuul代理功能。这个注解是开启Zuul的关键,它会让Spring Cloud自动配置Zuul的一些默认行为。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@SpringBootApplication
@EnableZuulProxy // 启用Zuul代理
public class ZuulGatewayApplication {public static void main(String[] args) {SpringApplication.run(ZuulGatewayApplication.class, args);}
}
步骤4:测试Zuul网关

现在,咱们的Zuul网关已经配置好了。启动Spring Boot应用,Zuul会自动根据配置的路由规则转发请求。咱们可以通过访问Zuul网关的地址(默认是http://localhost:8080/),加上相应的前缀(/user/order),来测试是否能成功转发到对应的服务。

比如,咱们可以使用Postman或者浏览器访问http://localhost:8080/user/,这个请求应该会被转发到用户服务。同样,访问http://localhost:8080/order/,请求会被转发到订单服务。

通过这个简单的例子,咱们已经成功搭建了第一个Zuul网关,并且理解了如何配置和使用Zuul进行路由转发。

深入过滤器:自定义过滤器实现复杂逻辑

在Zuul中,过滤器扮演着极其关键的角色,它们负责在请求路由的各个阶段执行各种任务,比如安全认证、请求日志记录、参数校验等。通过自定义过滤器,咱们可以实现更加复杂和定制化的逻辑来满足特定的业务需求。下面,小黑将带领咱们一探究竟,如何编写和使用自定义过滤器。

自定义过滤器的基础

要创建一个自定义过滤器,咱们需要继承ZuulFilter类,并实现其四个抽象方法:filterType()filterOrder()shouldFilter()run()

  • filterType():返回一个字符串代表过滤器的类型,在Zuul中主要有四种类型:prerouteposterror
  • filterOrder():返回一个int值来指定过滤器的执行顺序,数值越小,优先级越高。
  • shouldFilter():返回一个布尔值,判断该过滤器是否需要执行。
  • run():过滤器的具体逻辑。
编写自定义过滤器

下面是一个简单的自定义前置过滤器示例,用于检查请求中是否含有access-token参数,如果没有,则拒绝访问。

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;import javax.servlet.http.HttpServletRequest;public class AccessTokenFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre"; // 设置过滤器类型为前置过滤器}@Overridepublic int filterOrder() {return 1; // 设置执行顺序}@Overridepublic boolean shouldFilter() {return true; // 该过滤器总是生效,即总是执行过滤逻辑}@Overridepublic Object run() throws ZuulException {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();// 检查请求参数中是否有access-tokenString accessToken = request.getParameter("access-token");if (accessToken == null) {ctx.setSendZuulResponse(false); // 不对该请求进行路由ctx.setResponseStatusCode(401); // 设置响应状态码ctx.setResponseBody("access token is empty"); // 设置响应体内容ctx.getResponse().setContentType("text/html;charset=UTF-8"); // 设置响应类型}return null; // 过滤器返回值目前无具体意义,保留扩展}
}

在这个例子中,如果请求中没有包含access-token参数,那么过滤器将阻止请求被路由到下游服务,并返回401状态码以及一条错误信息。

注册自定义过滤器

编写好自定义过滤器后,还需要在Spring Boot应用中将其注册为一个Bean,这样Zuul才能识别并使用它。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ZuulConfig {@Beanpublic AccessTokenFilter accessTokenFilter() {return new AccessTokenFilter();}
}

通过上面的配置类,咱们就成功注册了AccessTokenFilter过滤器。现在,每当有请求经过Zuul网关时,都会先经过这个过滤器的检查。

通过自定义过滤器,Zuul为微服务架构提供了强大而灵活的扩展能力。咱们可以根据实际的业务需求,编写各种过滤器来实现身份验证、日志记录、请求和响应的修饰等功能。

Zuul的高级功能:动态路由、负载均衡和熔断

在微服务架构中,服务的动态性、可靠性和弹性是非常重要的特性。幸运的是,Zuul通过集成Spring Cloud的其他组件,如Eureka、Ribbon和Hystrix,提供了动态路由、负载均衡和熔断等高级功能。这一章,小黑将带咱们深入了解这些功能如何工作,以及如何配置它们以增强咱们的Zuul网关。

动态路由与服务发现

动态路由允许Zuul网关根据实际运行的服务实例动态地路由请求,而服务发现则是动态路由的基石。借助Eureka等服务发现组件,Zuul能够自动发现和路由到新注册的服务实例。

首先,确保咱们的服务(包括Zuul网关)都注册到了Eureka服务中心。然后,在Zuul的配置文件中使用服务ID而不是具体的URL来定义路由规则,这样Zuul就能根据服务ID动态地从Eureka中查找服务实例并进行路由。

zuul:routes:user-service:path: /user/**serviceId: USER-SERVICEorder-service:path: /order/**serviceId: ORDER-SERVICE
负载均衡

Ribbon是一个客户端负载均衡工具,它可以在调用微服务时自动提供负载均衡。结合Eureka,Ribbon可以从服务注册中心获取所有可用的服务实例列表,然后根据预定义的策略(如轮询、随机等)选择一个实例来发送请求。

在Zuul中,Ribbon是默认集成的,所以当咱们通过Zuul调用微服务时,负载均衡是自动进行的。这意味着如果有多个实例提供相同的服务,Ribbon会帮助咱们在这些实例之间分摊请求负载。

熔断

熔断器模式是微服务架构中一个重要的概念,它能够防止一个服务的故障成为连锁反应,影响到整个系统。Hystrix是Netflix开发的一个实现熔断器模式的库。在Zuul中,咱们可以使用Hystrix来为路由添加熔断功能,当后端服务不可用时,可以快速失败,返回一个预设的响应,而不是长时间等待或抛出错误。

要在Zuul中启用熔断功能,首先需要在application.yml中启用Hystrix:

hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 5000

然后,咱们可以为特定路由配置熔断回调,比如:

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;@Component
public class UserServiceFallbackProvider implements FallbackProvider {@Overridepublic String getRoute() {return "user-service"; // 指定熔断功能应用于哪些路由的服务}@Overridepublic ClientHttpResponse fallbackResponse(String route, Throwable cause) {return new ClientHttpResponse() {// 省略实现方法,通常返回一个简单的错误提示或静态响应};}
}

通过实现FallbackProvider接口,咱们可以为特定的服务定制熔断时的回调逻辑。

安全加固:使用Zuul保护你的微服务

在微服务架构中,确保服务之间的通信安全是非常重要的。幸运的是,Zuul提供了强大的过滤器功能,让咱们可以轻松地在网关层面添加安全控制,如身份验证、权限校验以及限流等,以保护后端服务不受恶意访问的影响。本章节,小黑将带咱们深入了解如何利用Zuul增强微服务的安全性。

身份验证与权限校验

在微服务架构中,通常会有一个认证服务负责用户的登录与权限分配。Zuul可以作为所有请求的入口,拦截请求并校验请求是否携带了有效的身份认证信息,比如JWT(Json Web Token)。

咱们可以通过自定义一个前置过滤器来实现这个功能。这个过滤器会检查HTTP请求的头部是否包含有效的Authorization信息。如果不包含,或者认证信息无效,则直接拒绝请求。

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;public class AuthFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return -100; // 确保这个过滤器在其他前置过滤器之前运行}@Overridepublic boolean shouldFilter() {return true; // 对所有请求都执行过滤}@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();String authToken = request.getHeader("Authorization");if (!isValidToken(authToken)) {ctx.setSendZuulResponse(false); // 不对请求进行路由ctx.setResponseStatusCode(401); // 设置401状态码ctx.setResponseBody("Unauthorized"); // 设置响应体内容ctx.getResponse().setContentType("application/json;charset=UTF-8"); // 设置响应体类型}return null;}private boolean isValidToken(String authToken) {// 这里应实现验证逻辑,现在只是示意return authToken != null && authToken.startsWith("Bearer ");}
}

限流

为了防止系统被过多的请求压垮,或者减少恶意攻击的风险,咱们可以在Zuul网关层面实现限流。Google的Guava库提供了RateLimiter,咱们可以利用它来简单实现限流的功能。

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;public class RateLimitFilter extends ZuulFilter {// 每秒只发放5个令牌private static final RateLimiter RATE_LIMITER = RateLimiter.create(5);@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return -50; // 在认证过滤器之后执行}@Overridepublic boolean shouldFilter() {return true; // 对所有请求都执行过滤}@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();if (!RATE_LIMITER.tryAcquire()) {ctx.setSendZuulResponse(false); // 不对这些过多的请求进行路由ctx.setResponseStatusCode(429); // 返回429状态码ctx.setResponseBody("Too Many Requests"); // 响应体内容ctx.getResponse().setContentType("application/json;charset=UTF-8"); // 响应体类型}return null;}
}

通过以上两个示例,咱们可以看到,Zuul提供的过滤器功能非常强大,足以支持咱们实现复杂的安全需求,从身份验证到权限校验。

调试与监控:让Zuul更加透明

在微服务架构中,有效的调试和监控是保证服务健康、及时发现并解决问题的关键。Zuul作为微服务架构中的网关,其性能和稳定性直接影响到整个系统。因此,对Zuul进行适当的调试和监控就显得尤为重要。本章节中,小黑将介绍如何利用Spring Boot Actuator和其他工具,来增强Zuul的可监控性和透明度。

使用Spring Boot Actuator监控Zuul

Spring Boot Actuator是Spring Boot的一个子项目,它提供了一套完善的监控和管理端点,允许咱们查看应用的内部状态。通过集成Actuator,咱们可以非常方便地监控和管理Zuul网关。

首先,需要在pom.xml文件中添加Spring Boot Actuator的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

一旦添加了这个依赖,Actuator就会自动启用,并且开放一系列端点,例如/health/metrics/trace等,咱们可以通过这些端点获取应用的健康状态、性能指标、请求追踪等信息。

接下来,配置application.yml以暴露需要的端点:

management:endpoints:web:exposure:include: health, metrics, trace

现在,咱们可以通过访问这些端点来监控Zuul网关的状态。例如,访问http://localhost:8080/actuator/health可以检查应用的健康状况,而http://localhost:8080/actuator/metrics则提供了更详细的性能指标。

调试Zuul过滤器

在开发和维护Zuul过滤器时,可能会遇到各种问题,这时候有效的调试就显得非常重要。Spring Boot支持各种调试技术,例如日志记录、断点调试等。

咱们可以在自定义过滤器中添加适当的日志记录语句,以帮助诊断问题。例如:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class MyFilter extends ZuulFilter {private static final Logger logger = LoggerFactory.getLogger(MyFilter.class);@Overridepublic Object run() {// 添加日志记录,帮助调试logger.debug("Inside MyFilter");// 省略其他代码return null;}
}

此外,咱们还可以利用IDE提供的断点调试功能,对过滤器进行逐行调试,这在复杂逻辑的排查中非常有帮助。

使用Zipkin进行分布式跟踪

在微服务架构中,一个请求可能会跨越多个服务,这使得传统的调试和监控变得更加复杂。Zipkin是一个分布式跟踪系统,它帮助咱们跟踪请求通过系统的路径。

要在Zuul中集成Zipkin,首先需要添加相应的依赖,并配置Zipkin服务器的地址。一旦配置完成,每个通过Zuul的请求都会被赋予一个唯一的跟踪ID,咱们可以通过这个ID在Zipkin界面上查看请求的完整路径和延迟信息,这对于诊断延迟问题和理解系统行为非常有用。

结语:Zuul的未来和替代方案

随着微服务架构的日益普及,服务网关在系统中扮演着越来越重要的角色。Zuul作为Netflix OSS套件的一部分,一直是微服务网关的佼佼者,提供了路由、过滤、监控等强大功能。但随着技术的发展,Zuul本身也在不断进化,同时也有新的技术和工具出现,为微服务架构提供更多的选择。本章节,小黑将讨论Zuul的未来方向以及一些流行的替代方案。

Zuul 2的新特性

Zuul 1.x虽然功能强大,但它是基于阻塞I/O操作的,这在处理大量并发请求时可能成为瓶颈。Netflix意识到了这个问题,并推出了Zuul 2。Zuul 2完全重写了Zuul的核心,采用了异步非阻塞I/O的架构,大大提高了性能和可伸缩性。此外,Zuul 2还引入了更多新特性和改进,比如更灵活的路由规则、动态加载和卸载过滤器等,使得它更加强大和易用。

Spring Cloud Gateway作为替代方案

随着Spring Cloud生态系统的不断发展,Spring Cloud Gateway应运而生,它是专为微服务架构设计的一个新一代API网关。与Zuul 1.x相比,Spring Cloud Gateway基于异步非阻塞模型,能更好地处理高并发场景。它利用了Spring Framework 5、Spring Boot 2和Project Reactor等现代技术,提供了路由、过滤、限流等功能,并且与Spring生态系统的集成更加紧密。

Spring Cloud Gateway支持动态路由配置、熔断、负载均衡等功能,而且配置方式更加灵活,可以使用Java代码、配置文件甚至是动态配置源(如Consul、Nacos)来配置路由规则和过滤器。这使得Spring Cloud Gateway成为构建现代微服务架构的强有力的选择。

总结

选择Zuul还是Spring Cloud Gateway,或者考虑其他的API网关产品,主要取决于咱们的具体需求、技术栈以及对性能和可伸缩性的要求。Zuul 1.x因其稳定性和成熟性仍适用于许多生产环境,而Zuul 2和Spring Cloud Gateway则为微服务架构提供了更现代化、高性能的网关解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gemini 试用(python)

1. 非stream方式&#xff08;requests&#xff09; import os import json import requestsdef test_gemini_no_stream(apikey, text):url fhttps://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key{apikey}headers {Content-Type: appli…

BUUCTF--极客大挑战php

文章目录 1.网站备份文件www.zip2.下载后发现class.phpindex.phpflag.php 3.分析php代码绕过__wakeup方法变量权限为私有或保护python方法url方法 1.网站备份文件www.zip 2.下载后发现 class.php <?php include flag.php; error_reporting(0);class Name{private $usernam…

创邻科技获评环紫金港创新生态圈智源创新企业

3月1日&#xff0c;由杭州城西科创大走廊管理委员会指导&#xff0c;中共杭州市西湖区委员会、西湖区人民政府主办的“环紫金港创新生态圈”行动推进大会暨2024年紫金港科技城经济高质量发展大会在杭州举办。凭借重要的生态位置和创新业务成果&#xff0c;创邻科技受邀参会并被…

java-springboot 源码 01

01.springboot 是一个启动器 先安装maven&#xff0c;按照网上的流程来。主要是安装完成后&#xff0c;要修改conf目录下的setting.xml文件。 添加&#xff1a;阿里云镜像 <mirror><id>aliyunmaven</id><mirrorOf>*</mirrorOf><name>ali…

【vue3之Pinia:状态管理工具】

Pinia:状态管理工具 一、认识Pinia二、定义store三、gettters四、Action1.定义普通函数2.异步实现 五、storeToRefs工具函数六、pinia持久化插件1. 安装插件2. main.js 使用3. 开启4.其他配置 一、认识Pinia Pinia 是 Vue 的最新 状态管理工具 &#xff0c;是 Vuex 的 替代品 …

OpenCV 视频处理(关于摄像头和视频文件的读取、显示、保存等等)

1、前言 OpenCV不仅能够处理图像&#xff0c;还能够处理视频 视频是由大量的图像构成的&#xff0c;这些图像是以固定的时间间隔从视频中获取的。这样&#xff0c;就能够使用图像处理的方法对这些图像进行处理&#xff0c;进而达到处理视频的目的。要想处理视频&#xff0c;需…

PCL官方demo的编译使用教程

写在前面 本文内容 PCL官方demo的编译使用教程&#xff1b; 后续对PCL demo中比较常用的算法、应用demo会出专门的博客讲解、拓展&#xff1b; 更多点云基础、算法相关内容请关注专栏&#xff1a; 点云处理基础 点云配准(PointCloud Registration) Open3D点云处理 PCL点云处理 …

Docker本地部署Redis容器结合内网穿透实现无公网ip远程连接

文章目录 前言1. 安装Docker步骤2. 使用docker拉取redis镜像3. 启动redis容器4. 本地连接测试4.1 安装redis图形化界面工具4.2 使用RDM连接测试 5. 公网远程访问本地redis5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Ub…

Python与FPGA——局部二值化

文章目录 前言一、局部二值化二、Python局部二值化三、FPGA局部二值化总结 前言 局部二值化较全局二值化难&#xff0c;我们将在此实现Python与FPGA的局部二值化处理。 一、局部二值化 局部二值化就是使用一个窗口&#xff0c;在图像上进行扫描&#xff0c;每扫出9个像素求平均…

探索AI视频创新:Sora的奇迹

探索AI视频创新&#xff1a;Sora的奇迹 随着科技的不断演进&#xff0c;AI视频模型已经成为人工智能领域的一颗新星。在这场技术的风暴中&#xff0c;OpenAI的Sora模型以其杰出的性能和前瞻性的技术脱颖而出&#xff0c;正引领着AI视频领域的全新创新浪潮。 Sora的技术之光 …

【深度学习笔记】优化算法——小批量随机梯度下降

小批量随机梯度下降 到目前为止&#xff0c;我们在基于梯度的学习方法中遇到了两个极端情况&#xff1a; :numref:sec_gd中使用完整数据集来计算梯度并更新参数&#xff0c; :numref:sec_sgd中一次处理一个训练样本来取得进展。 二者各有利弊&#xff1a;每当数据非常相似时&a…

电脑蓝牙在哪里打开?不同系统详解

在现代计算机的多功能性中&#xff0c;蓝牙技术的广泛应用使得我们能够轻松连接各种外部设备&#xff0c;实现无线传输和分享。无论是连接无线耳机、键盘&#xff0c;还是与其他设备快速交换文件&#xff0c;蓝牙在电脑中的角色很重要。然而&#xff0c;对于一些用户而言&#…

centos7 使用rpm包部署filebeat

先决条件参考 虚拟机部署elasticsearch集群-CSDN博客 下载并安装filebeat的rpm包 curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.18-x86_64.rpmrpm -vi filebeat-7.17.18-x86_64.rpm 修改配置文件 配置文件内容可以参考 Repositories…

5G工业网关是什么?

随着科技的飞速发展&#xff0c;5G技术已经逐渐渗透到我们生活的方方面面。而在工业领域&#xff0c;5G工业网关作为连接工业设备与网络的关键组件&#xff0c;正发挥着越来越重要的作用。HiWoo Box其5G工业网关产品以其卓越的性能和稳定性&#xff0c;正助力企业实现数字化转型…

【异常处理】Vue报错 Component template should contain exactly one root element.

问题描述 启动VUE项目后控制台报错&#xff1a; Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.翻译为&#xff1a;组件模板应该只包含一个根元素 查看vue代码&#xff0…

【Redis】Redis的应用场景

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Redis ⛺️稳中求进&#xff0c;晒太阳 Redis的应用场景&#xff1a; 限流 要求10s内只能访问一次 RequestMapping("xian")public String xianLiu(String sign){String sign1 …

前端处理接口直接返回的图片

有时候接口会直接返回图片而不是连接&#xff0c;前端需要处理后才能使用。 首先你可能需要设置responseType: blob’处理响应数据格式。 直接使用 将接口及参数动态拼接成img.src直接使用 <img src"http://test.com/api/img?size50x50" alt"">i…

SpringBoot和Vue 实现增删改查、分页查询、模糊查询

文章目录 前言统一的设置返回类型Vue安装axios&#xff0c;封装request查询所有的用户前端页面请求后端接口编写 条件查询前台请求后台处理请求 分页查询前台发送请求后台接受请求 新增、编辑管理员信息前台后台 删除操作前台请求后台 前言 SpringBoot实现增删改查、分页查询、…

出口内销双循环,诺赛特企业走出发展新路子

在外贸圈这个深水池中&#xff0c;企业的命脉早已与规模、市场地位等因素牢牢绑定。大型外贸企业掌握大资源、大曝光&#xff0c;不用为订单发愁&#xff1b;中型外贸企业&#xff0c;投入相当大的人力、财力、物力&#xff0c;孤注一掷&#xff0c;虎口夺食&#xff1b;小型外…

LLM 大模型框架 LangChain 可观测性最佳实践

LLM&#xff08;Large Language Model&#xff09;大模型的可观测性是指对模型内部运行过程的理解和监控能力。由于LLM大模型通常具有庞大的参数量和复杂的网络结构&#xff0c;因此对其内部状态和运行过程的理解和监控是一个重要的问题。 什么是 LangChain&#xff1f; Lang…