Feign 实战指南:从 REST 替代到性能优化与最佳实践

Feign 实战指南:从 REST 替代到性能优化与最佳实践

  • 一 . Feign 替代 RestTemplate
    • 1.1 RestTemplate 方式调用存在的问题
    • 1.2 Feign 的介绍
    • 1.3 定义和使用 Feign 客户端
      • 1.3.1 引入依赖
      • 1.3.2 添加注解
      • 1.3.3 编写 Feign 的客户端进行接口声明
      • 1.3.4 测试
      • 小结
    • 1.4 通过 POST 请求进行远程调用
  • 二 . 自定义配置
    • 2.1 配置文件方式
      • ① 全局生效
      • ② 局部生效
    • 2.2 Java 代码方式
      • ① 全局配置
      • ② 局部配置
    • 2.3 小结
  • 三 . 性能优化
    • 3.1 引入依赖
    • 3.2 配置连接池
    • 3.3 小结
  • 四 . 最佳实践
    • 4.1 继承方式
    • 4.2 抽取方式
    • 4.3 实现抽取方式
      • ① 抽取
      • ② 在 order-service 中使用 feign-api
      • ③ 重启测试
      • ④ 解决扫描包问题
  • 五 . 扩展
    • 5.1 Feign 调用注意事项

在微服务架构中,服务间通信的便捷性与性能至关重要。本文将深入解析 Feign 这一声明式 HTTP 客户端的核心应用,从替代传统 RestTemplate 解决调用痛点开始,逐步讲解自定义配置、性能优化及企业级最佳实践。内容涵盖 Feign 客户端定义与使用、日志级别配置、连接池优化,以及通过继承或抽取方式实现代码复用,帮助读者构建高效、可维护的微服务通信体系。
在这里插入图片描述

本专栏的内容均来自于 B 站 UP 主黑马程序员的教学视频,感谢你们提供了优质的学习资料,让编程不再难懂。
专栏地址 : https://blog.csdn.net/m0_53117341/category_12835102.html

一 . Feign 替代 RestTemplate

1.1 RestTemplate 方式调用存在的问题

先来看一下我们之前通过 RestTemplate 方式发起远程调用的代码

这种方式是通过 URL 地址指明要访问的服务名称、请求路径以及请求的参数信息 , 由 RestTemplate 来负责发起请求 .

那这段代码存在一些问题 :

  1. 代码可读性差 , 编程体验不够统一 : 在代码中引入了 URL , 导致代码不够统一
  2. 参数复杂 URL 难以维护 : 就比如我们访问的 Nacos 的路径 , 他的 URL 就非常复杂

1.2 Feign 的介绍

Feign 是一个声明式的 HTTP 客户端

声明式 : 比如早期 , 我们学习 MySQL 的事务的时候 , 我们需要手动开启关闭事务 . 那后来学习 Spring 的时候 , 就提供了 Spring 的声明式事务 , 只需要在配置文件中告诉 Spring 对谁加事务即可 . 那以后所有的事务都交给 Spring 来帮我们做 .

那声明式 HTTP 客户端也是如此 , 我们如果要发送 HTTP 请求 , 那只需要将发送请求所需要的信息声明出来 , 剩下的工作 Feign 帮助我们来做 .

Feign 的作用就是帮助我们优雅地实现 HTTP 请求的发送 , 解决上面提出的问题 .

1.3 定义和使用 Feign 客户端

1.3.1 引入依赖

在 order-service 服务中引入依赖

<!-- Feign 客户端依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

1.3.2 添加注解

我们需要在 order-service 的启动类中添加开启 Feign 功能的注解

package com.example.order;import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@MapperScan("com.example.order.mapper")
@SpringBootApplication
@EnableFeignClients // 开启 Feign 功能
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}// 随机轮训// @Bean// public IRule randomRule() {//     return new RandomRule();// }
}

1.3.3 编写 Feign 的客户端进行接口声明

我们需要在该接口上添加一个注解 @FeignClient , 并且指定要调用的服务名称

接下来我们编写一个方法 , 方法的返回值就是我们想获取到的结果 , 方法的参数就是我们要传的参数

然后我们还需要在方法上面添加一个注解声明请求的方式

那上面用了动态参数 , 下面我们也需要用 @PathVariable 注解来接收

package com.example.order.clients;import com.example.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;// 1. 指定服务名称
@FeignClient("userservice")
public interface UserClient {// 3. 声明请求方式@GetMapping("/user/{id}")// 4. 在参数前面加上 @PathVariable 注解User findById(@PathVariable("id") Long id);// 2. 方法的返回值就是我们想获取到的结果 , 方法的参数就是我们要传的参数
}

1.3.4 测试

那我们可以将之前的 RestTemplate 的方式替换掉了

首先 , 需要注入刚才实现的 UserClient

然后下面我们只需要调用 userClient 的 findById 方法即可

package com.example.order.service;import com.example.order.clients.UserClient;
import com.example.order.mapper.OrderMapper;
import com.example.order.pojo.Order;
import com.example.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {// 1. 查询订单Order order = orderMapper.findById(orderId);// 2. 查询用户 IDLong userId = order.getUserId();// 3. 用 Feign 来实现远程调用User user = userClient.findById(userId);// 4. 将获取到的用户信息添加到 user 字段中order.setUser(user);// 5. 返回return order;}
}

在运行之前 , 先将我们的 bootstrap.yml 修改回 8848

成功通过 Feign 的方式调用

小结

Feign 的使用步骤

  1. 引入依赖
  2. 在启动类中添加 @EnableFeignClients 注解
  3. 编写 FeignClient 接口
  4. 使用 FeignClient 中定义的方法代替 RestTemplate

1.4 通过 POST 请求进行远程调用

第一步 : 添加 @PostMapping 注解

第二步 : 参数使用 @RequestBody 接收即可

package com.example.order.clients;import com.example.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;// 1. 指定服务名称
@FeignClient("userservice")
public interface UserClient {// 3. 声明请求方式@PostMapping("/user/add")// 4. 在参数前面加上 @RequestBody 注解String add(@RequestBody User user);
}

二 . 自定义配置

Feign 可以运行自定义的配置来去覆盖默认的配置 , 那可以修改的配置如下 :

类型作用说明
feign.Logger.Level修改日志的级别包含四种不同的级别 :
+ NONE
+ BASIC
+ HEADERS
+ FULL
feign.codec.Decoder解码将 HTTP 远程调用的结果进行解析 (比如 : 解析 JSON 字符串为 Java 对象)
feign.codec.Encoder编码将请求参数进行编码 (比如转化成二进制) , 便于通过 HTTP 请求发送
feign.Contract支持的注解格式默认是 Spring MVC 的注解
feign.Retryer失败重试机制请求失败的重试机制 , 一般通过 Ribbon 的重试机制

日志的级别分为四种 :

  • NONE : 不记录任何日志信息 , 这是默认值
  • BASIC : 仅记录请求的方法、URL 以及相应状态码和执行时间
  • HEADERS : 在 BASIC 的基础上 , 额外记录了请求和响应的头信息
  • FULL : 记录所有请求和响应的明细 , 包括 : 头信息、请求体、元数据

在非生产环境中 , 我们一般配置日志级别为 FULL , 在生产环境中 , 我们一般配置日志级别为 NONE / BASIC

那配置 Feign 日志有两种方式

2.1 配置文件方式

我们可以配置日志级别全局生效 , 也可以设置日志级别局部生效

① 全局生效

feign:client:config:default: # 默认全局所有的 Feign 的客户端都设置为该级别loggerLevel: FULL # 设置日志级别

那我们可以重启 order-service 服务 , 然后观察它的日志

日志中展示了详细的 HTTP 信息 .

② 局部生效

feign:client:config:default: # 针对所有微服务来去做配置loggerLevel: FULL # 设置日志级别userservice: # 针对特定的微服务来去做配置loggerLevel: BASIC

那 default 以及 userservice 配置全部存在 , 最后会执行哪个配置呢 ?

重启 user-service 服务

那这就代表最后会执行 userservice 这一层配置

2.2 Java 代码方式

我们可以声明一个配置类

然后在类上添加 @Configuration 注解 , 表示当前的类是一个配置类

然后在里面声明一个 Bean 对象 , 我们也能够看到一系列选项

package com.example.order.config;import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FeignConfig {@Beanpublic Logger.Level loggerLevel() {return Logger.Level.BASIC;}
}

① 全局配置

如果是全局配置 , 那就将他放到启动类中的 @EnableFeignClients 注解中

我们可以看一下 @EnableFeignClients 注解的选项

那我们就使用这个默认的参数

那就代表 , 所有的 Feign 都会走 FeignConfig 这个配置

② 局部配置

如果是局部配置 , 那就将他放到 @FeignClient 这个注解中

我们也可以看一下 @FeignClient 注解默认的选项

那我们就可以在选项中填写这个参数

package com.example.order.clients;import com.example.order.config.FeignConfig;
import com.example.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;// 1. 指定服务名称
@FeignClient(value = "userservice", configuration = {FeignConfig.class})
public interface UserClient {// 3. 声明请求方式@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);// 2. 方法的返回值就是我们想获取到的结果, 方法的参数就是我们要传的参数
}

那我们就需要将配置文件中配置的自定义配置注释掉

重启一下

2.3 小结

Feign 的日志配置 :

方式一是配置文件 , feign.clent.config.xxx.loggerLevel

  1. 如果 xxx 是 default , 则代表全局
  2. 如果 xxx 是服务名称 , 例如 : userservice 就代表某服务

方式二是通过 Java 代码配置 Logger.Level 这个 Bean

  1. 如果在 @EnableFeignClients 注解中声明 , 则代表全局
  2. 如果在 @FeignClient 注解中声明 , 则代表某服务

三 . 性能优化

Feign 底层的客户端实现 :

  • URLConnection : 默认实现 , 不支持连接池
  • Apache HttpClient : 支持连接池
  • OKHttp : 支持连接池

因此 , 提高 Feign 的性能的主要手段就是使用连接池代替默认的 URLConnection

那这里我们用 Apache 的 HttpClient 来演示

3.1 引入依赖

在 order-service 的 pom.xml 中引入依赖 :

<!-- httpClient 的依赖 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>

3.2 配置连接池

在 order-service 的 applicatiom.yml 中添加配置

feign: httpclient:enabled: true # 开启 feign 对 HttpClient 的支持max-connections: 200 # 设置最大连接数max-connections-per-route: 50 # 设置每个路径的最大连接数

设置每个路径的最大连接数的意思就是设置每个接口的最大连接数

我们重新运行一下 , 由于这个性能提升了多少我们不太好衡量 , 所以保证不报错就可以了

3.3 小结

Feign 的优化 :

  1. 使用 HttpClient 或者 OKHttp 代替 URLConnection
    1. 引入 feign-httpClient 依赖
    2. 配置文件开启 httpClient 功能 , 设置连接池参数
  2. 日志级别生产环境尽量用 basic

四 . 最佳实践

所谓的最佳实践 , 就是在使用的过程中总结出来的经验 , 找到的最好的一种使用方式 .

我们提供给大家两种最佳的实践思路

4.1 继承方式

继承方式就是给消费者的 FeignClient 和提供者的 controller 定义统一的父接口作为标准

我们可以通过代码来了解一下

首先 , 来看 UserClient 这个接口 , 它的作用就是通过注解来声明远程调用需要用到的一系列的信息 , 比如 : 请求的方式、路径、参数、返回值类型等等 .

那这段代码的意义就是让消费者基于这些信息发送一个 HTTP 请求 , 那这个请求最终就会到达 user-service 服务中的某个实例上 .

那我们再来看一下 user-service 服务中的 controller 层的代码

那我们可以对比一下两个方法

那这两个方法非常非常相似 , 那我们可不可以对这两个方法进行一个抽取呢 ?

但是这种方式其实是存在一些问题的 , Spring 官方也提醒我们了

一般情况下 , 我们不推荐接口被服务端和客户端所共享 . 因为他会造成紧耦合 , 将来接口发生变化 , 服务端和客户端就都需要进行更改 . 而且这种方案是不对 Spring MVC 起作用的 .

4.2 抽取方式

我们可以将 FeignClient 抽取为独立模块 , 并且把接口有关的 POJO、默认的 Feign 配置都放到这个模块中 , 提供给所有消费者使用 .


Feign 的最佳实践 :

  1. [继承方式] : 让 controller 和 FeignClient 继承同一接口
  2. [抽取方式] : 将 FeignClient、POJO、Feign 的默认配置都定义到一个项目中 , 供所有消费者使用

4.3 实现抽取方式

① 抽取

首先 , 创建一个 module , 命名为 feign-api , 然后引入 feign 的 starter 依赖

然后在 feign-api 中引入 feign 的依赖

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

然后我们就需要将 order-service 中的 Feign 客户端、配置、实体类都挪动到 feign-api 模块下

然后我们将这几个类该导的包导入进来

那之后其他服务想要进行远程调用 , 只需要调用 feign-api 即可 , 所以我们的 order-service 服务中的这些内容就可以删除掉了

那此时 Order 实体类会报错

② 在 order-service 中使用 feign-api

我们只需要引入 feign-api 依赖即可

<!-- 引入 feign-api -->
<dependency><groupId>com.example.demo</groupId><artifactId>feign-api</artifactId><version>1.0</version>
</dependency>

此时我们重新导入一下包即可 , 我们需要重新导入 Order 实体类、OrderService、启动类这三个部分

③ 重启测试

那我们重启 order-service 服务

他报错的信息是未发现 UserClient 对象 , 这是因为我们已经将 UserClient 移动到 feign-api 模块下了 , 现在他们已经属于不同的服务了 , 我们不能跨服务调用 .

④ 解决扫描包问题

当定义的 FeignClient 不在 SpringBootApplication 的扫描包范围时 , 这些 FeignClient 无法使用 . 那我们有两种解决方案

  1. 指定 FeignClient 所在的包
@EnableFeignClients(basePackages = "com.example.feign.UserClient")
  1. 指定 FeignClient 字节码
@EnableFeignClients(clients = {UserClient.class})

那我们可以实现一下第二种方式

package com.example.order;import com.example.feign.clients.UserClient;
import com.example.feign.config.FeignConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@MapperScan("com.example.order.mapper")
@SpringBootApplication
@EnableFeignClients(clients = {UserClient.class}, defaultConfiguration = {FeignConfig.class})
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}}

那我们再重启一下


小结 :

不同包的 FeignClient 的导入有两种方式 :

  1. 在 @EnableFeignClients 注解中添加 basePackages , 指定 FeignClient 所在的包
  2. 在 @EnableFeignClients 注解中添加 clients , 指定具体 FeignClient 的字节码

五 . 扩展

5.1 Feign 调用注意事项

我们先来回顾一下目前所做的工作

order-service 远程调用 user-service 这个微服务 , 我们无需再使用 RestTemplate 这种方式了 , 我们使用 Feign 这种声明式的客户端 .

我们目前已经引入了 Feign 客户端以及 HTTP 连接池的依赖

然后在 order-service 服务的启动类中开启了 Feign 远程调用

然后我们定义了一个接口 , 在后面指定了我们要调用的微服务 , 那每个微服务也需要暴露自己的接口 .

那目前我们是传一个参数的 , 如果传两个参数呢 ?

那我们要想访问这个接口 , URL 就需要长成这个样子 : http://localhost:8081/user/testData2?userName=xx&age=18

那我们如何定义这个接口对应的 Feign 方法呢 ?

直接将这个方法体部分复制过去

此时我们重启 order-service 与 user-service 服务 , 发现 order-service 就已经报错了

那我们怎样解决这个问题呢 ?

我们需要在 Feign 部分的参数前面添加 @RequestParam(“”) 参数表示从 query string 中获取数据

此时重新运行就不报错了


小结 :

  1. Feign 核心能力与使用
    1. 替代 RestTemplate:通过声明式接口简化远程调用,解决 URL 维护复杂、代码可读性差的问题,使用步骤包括引入依赖、添加注解、定义客户端接口。
    2. 请求方式支持:支持 GET、POST 等多种请求方式,POST 请求需通过 @RequestBody 传递参数。
  2. 自定义配置与日志
    1. 配置类型:可自定义日志级别、编解码器、重试机制等,日志级别分为 NONE、BASIC、HEADERS、FULL 四级。
    2. 配置方式:支持配置文件(全局 / 局部)和 Java 代码(全局 / 局部)两种方式,优先级为局部配置 > 全局配置。
  3. 性能优化实践
    1. 连接池优化:使用 Apache HttpClient 或 OKHttp 替代默认 URLConnection,通过配置连接池参数(最大连接数、路径连接数)提升性能。
    2. 日志策略:生产环境建议使用 BASIC 级别减少日志开销。
  4. 最佳实践与扩展
    1. 代码复用:推荐抽取 FeignClient 为独立模块,共享 POJO 和配置,避免继承方式的紧耦合问题。
    2. 多参数调用:使用 @RequestParam 明确标注查询参数,确保远程调用参数解析正确。

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

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

相关文章

什么是国际期货?期货交易平台搭建

国际期货&#xff08;International Futures&#xff09;&#xff0c;又称外盘期货或全球期货&#xff0c;是指在中国大陆以外的交易所进行标准化合约交易的金融衍生品市场。其核心特征、功能及与国内期货的区别如下&#xff1a; &#x1f4cd; 一、定义与核心特征 全球化交易…

考取华为HCIE-AI有什么用?

在人工智能技术重塑各行各业的浪潮中&#xff0c;掌握核心AI能力成为专业人士的制胜关键。华为推出的HCIE-AI Solution Architect&#xff08;华为认证ICT专家-AI解决方案架构师&#xff09;&#xff0c;正是面向这一领域顶尖人才设立的最高级别认证。主要是为了培养和认证掌握…

Maven 使用说明和配置

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 一、前言 Apache Maven (opens new window)是一个软件项目管理、构建和依赖工具。基于项目对象模型 (POM) 的概念&#xff0c;Maven 可以通过中央信息来管理项目的构建、…

【Docker管理工具】安装Docker容器自动更新工具Watchtower

【Docker管理工具】安装Docker容器自动更新工具Watchtower 一、Watchtower介绍1.1 Watchtower简介1.2 Watchtower使用注意1.3 Watchtower使用场景1.4 Docker容器介绍 二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版…

AI优化SEO关键词精进

内容概要 随着人工智能技术的飞速发展&#xff0c;其在搜索引擎优化&#xff08;SEO&#xff09;领域的应用正引发深刻变革。本文将系统探讨AI如何革新传统的关键词优化策略&#xff0c;通过更智能的分析与匹配方法&#xff0c;显著提升内容在搜索结果中的可见度与排名。核心议…

canvas面试题200道

下面是一份 200 条关于 HTML5 Canvas 的面试题合集,适用于前端开发岗位的中高级工程师面试准备。内容涵盖基础概念、绘图操作、性能优化、动画实现、安全机制等多个方面,并附有参考答案或解析建议。 🧠 一、Canvas 基础知识(1-40) 1. 什么是 HTML5 Canvas? <canvas&…

Java 大视界 -- Java 大数据在智能安防视频监控系统中的目标轨迹预测与防范策略制定(325)

Java 大视界 -- Java 大数据在智能安防视频监控系统中的目标轨迹预测与防范策略制定&#xff08;325&#xff09; 引言&#xff1a;正文&#xff1a;一、Java 驱动的安防视频数据采集与预处理架构1.1 多路异构视频流合规接入层&#xff08;GB/T 28181-2021 全协议适配&#xff…

【Python】实现对LGBT+ rights worldwide (2025)数据集的可视化展示

我用夸克网盘分享了「lgbtq_rights_by_country数据集」&#xff0c;点击链接即可保存。 链接&#xff1a;https://pan.quark.cn/s/aa0fa91491e8 摘要&#xff1a; 本文运用Python编程实现对LGBTQ权利相关数据的处理与可视化展示。通过直方图与地图两种可视化方式&#xff0c;分…

车载通信架构 --- ECU刷写与busoff原则

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

【windows处理技巧】如何缩小PDF

原因&#xff1a;近日输出的PDF太大&#xff0c;渲染需要较多的时间&#xff0c;所以需要缩小一下PDF。 操作工具&#xff1a;adobe acrobat pro 方法&#xff1a;导入--另存为--缩减 初始&#xff1a; 压缩后

OpenCV图像添加水印

一、前言 在数字图像处理中&#xff0c;为图片添加水印是一项常见且重要的技术。无论是版权保护、品牌宣传还是防止未经授权的使用&#xff0c;水印都能发挥重要作用。OpenCV作为一款强大的计算机视觉库&#xff0c;提供了丰富的功能来实现各种水印效果。本教程将详细介绍如何…

OpenCV CUDA模块设备层-----双曲正弦函数sinh()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV的CUDA 模块&#xff08;cv::cudev&#xff09;中的一个设备端数学函数&#xff0c;用于在 GPU 上对 uchar3 类型的像素值&#xff08;如R…

使用 Xinference 命令行工具(xinference launch)部署 Nanonets-OCR-s

使用Xinference命令行工具(xinference launch)部署Nanonets-OCR-s 一、核心优势与适用场景 通过xinference launch命令可直接在命令行完成模型部署,无需编写Python代码,适合快速验证或生产环境批量部署。 二、部署步骤:从命令行启动模型 1. 确认环境与依赖 已安装Xinf…

鸿蒙 List 组件解析:从基础列表到高性能界面开发指南

一、引言&#xff1a;列表布局 —— 鸿蒙应用的数据展示中枢 在鸿蒙应用开发体系中&#xff0c;列表布局是处理结构化数据展示的核心场景。从新闻资讯的信息流、电商平台的商品陈列到任务管理的待办事项&#xff0c;几乎所有中大型应用都依赖高效的列表组件实现数据可视化。鸿…

原生微信小程序中限制多选框(Checkbox)可选个数的实现详解

在实际业务场景中&#xff0c;我们经常会遇到表单中的复选框多选限制需求。例如最多只能选择 3 个爱好、标签、兴趣点等&#xff0c;这时就需要在微信小程序中手动控制 Checkbox 的选择行为。 本文将通过一个完整的示例&#xff0c;演示如何实现最多只能选择 N 个的 Checkbox …

OpenCV CUDA模块设备层-----线性插值函数log()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于创建线性插值访问器&#xff0c;支持对GPU内存中的图像数据进行双线性插值采样。主要应用于图像缩放、旋转等几何变换中需要亚像素级精…

Redis 单线程的“天花板”与集群的必要性

虽然 Redis 以其单线程模型&#xff08;主要是处理请求的核心逻辑&#xff09;带来了极高的性能和简洁性&#xff0c;但这并不意味着它没有瓶颈。 CPU 瓶颈&#xff1a;当业务逻辑复杂&#xff0c;或者 Redis 执行大量计算密集型操作&#xff08;比如使用 Lua 脚本进行复杂处理…

16.7 Prometheus+Grafana实战:容器化监控与日志聚合一站式解决方案

《Prometheus+Grafana实战:容器化监控与日志聚合一站式解决方案》 关键词:容器化监控、日志聚合、Prometheus、Grafana、ELK Stack、用户反馈收集 容器化监控与日志系统的架构设计 在 LanguageMentor Agent 生产部署中,监控系统需要覆盖以下维度: #mermaid-svg-I7cOqUK0i…

商务创业项目策划计划书PPT模版

创业商业融资计划书PPT模版&#xff0c;商务商业计划融资书PPT模版&#xff0c;创业融资计划书PPT模版&#xff0c;框架完整创业融资计划书PPT模版 商务创业项目策划计划书PPT模版&#xff1a;https://pan.quark.cn/s/d07d22408497

【软考高级系统架构论文】论面向方面的编程技术及其应用

论文真题: 请围绕“论软件测试中缺陷管理及其应用”论题,依次从以下三个方面进行论述: 概要叙述你参与管理和开发的软件项目以及承担的工作。详细论述常见的缺陷种类及级别,论述缺陷管理的基本流程。结合你具体参与管理和开发的实际项目,说明是如何进行缺陷管理的。请具体…