当前位置: 首页 > news >正文

SpringCloudAlibaba OpenFeign整合及详解

SpringCloudAlibaba OpenFeign

在前面,我们使用Nacos服务注册发现后,服务远程调用可以使用RestTemplate+Ribbon或者OpenFeign调用。实际开发中很少使用RestTemplate这种方式进行调用服务,每次调用需要填写地址,还要配置各种的参数,很麻烦。使用OpenFeign的方式就可以解决这种问题。

那么说起了OpenFeign,就需要提及一下Feign了,因为OpenFeign是Feign的增强版。Feign是一个轻量级Restful HTTP服务客户端,内置ribbon用作客户端负载均衡,使用Feign时只需要定义一个接口加上注解,符合面向接口的编程习惯,使远程调用服务更加容易。

OpenFeign是对Feign的进一步封装,使其支持Spring MVC的标准注解和HttpMessageConverters,如@RequestMapping等。

集成OpenFeign

在消费者客户端中集成OpenFeign

导入依赖

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

bootstrap.yml中增加OpenFeign对Sentinel的支持,增加feign.sentinel.enabled配置项

server:port: 9001
spring:application:name: consumer # 应用名cloud:nacos:discovery:server-addr: localhost:8848 # nacos服务地址sentinel:transport:port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描dashboard: 127.0.0.1:8080 # 仪表版访问地址
feign:	# 增加对sentinel的支持sentinel:enabled: true

这里说一下如果不加feign.sentinel.enabled=true的配置,那么在@FeignClient中定的fallback属性定义的异常、限流等自定义的处理逻辑不会生效

在主启动类上加入@EnableFeignClients注解,标记为启用OpenFeign,具体如下:

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

笔者这里再提一句,假如是分布式项目,将openfeign抽取为一个单独的服务模块时,可能出现我openfeign中的包名和其他模块不一致,可以自己声明FeignClient组件的basePackages设置一下FeignClient的扫描路径。示例如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.alibaba.provider.feigns")
public class Consumer {public static void main(String[] args) {SpringApplication.run(Consumer.class, args);}
}

增加一个FeignClient的客户端

/*** "provider" : 表示调用的生产者服务名* fallback:异常时进入的处理类*/
@FeignClient(value = "provider", fallback = OpenFeignTestServiceFallback.class)
public interface OpenFeignTestService {@RequestMapping(value = "/openFeignProviderTest", method = RequestMethod.GET)public String openFeignProviderTest();}

创建OpenFeignTestServiceFallback做fallback处理

@Component
public class OpenFeignTestServiceFallback implements OpenFeignTestService{@Overridepublic String openFeignProviderTest() {return "我是兜底方法";}
}

创建controller做个接口,方便调用

@RestController
public class OpenFeignTestController {@Resourceprivate OpenFeignTestService openFeignTestService;@RequestMapping("/openFeignTest")public String openFeignTest() {return openFeignTestService.openFeignProviderTest();}}

在服务生产者方,提供接口

@RestController
public class OpenFeignProviderTest {@RequestMapping("/openFeignProviderTest")public String openFeignProviderTest() {return "OpenFeignTestController#openFeignProviderTest" + RandomUtils.nextInt(0, 1000);}}

测试接口

使用curl或浏览器都行,调用服务消费者方的/openFeignTest接口测试

curl http://localhost:9001/openFeignTest
==>OpenFeignTestController#openFeignProviderTest748

代码优化一下:

在@FeignClient注解中,value属性填写的是服务提供者的服务名称,这么把值直接写死是不合适的,假如服务提供者名称变了,那么这里写的就需要修改,而且如果用的地方比较多的情况下,需要到处修改。如何解决呢?

  • 把服务名用一个单独的类,定义静态常量
  • 使用配置文件方式,使用表达式获取即可

定义静态常量类就不再演示,使用配置文件方式:

provider:name: provider

在FeignClient客户端使用表达式获取

@FeignClient(value = "${provider.name}", fallback = OpenFeignTestServiceFallback.class)

结合sentinel规则使用

不管是RestTemplate+Ribbon还是OpenFeign的远程调用,都是支持Sentinel的,到sentinel面板中配置资源流控规则

注意:sentinel是懒加载方式,需要先去调用一次接口,才能在控制台添加规则

在sentinel面板,新增openFeignProviderTest流控规则,阈值类型QPS,单机阈值1

在这里插入图片描述

欧克,我们对服务端的,/openFeignProviderTest做了限流,那么试试多次连续访问客户端接口试试。

在这里插入图片描述

可以看到,有请求会进入到fallback降级中。

那么对于异常该怎么处理呢?

修改服务端接口代码,设置一个异常,进行测试接口

在这里插入图片描述

欧克,发现,服务端如果是出现了异常,仍然会进入客户端的fallback处理中,是不是非常奈斯。

那么同样的,假如服务器进入宕机状态,会如何?关掉服务端试试。

在这里插入图片描述

行的,一样可以进入到fallback处理中。

实现负载均衡

OpenFeign也具有负载均衡的功能,多个服务端时,采用对应的算法寻找一个服务端进行请求。

下面,服务端将输出当前项目的端口号,并且再新建一个服务端的项目

@RestController
public class OpenFeignProviderTest {@Value("${server.port}")private Integer port;@RequestMapping("/openFeignProviderTest")public String openFeignProviderTest() {return "OpenFeignTestController#openFeignProviderTest" + port;}}

再新建一个项目,端口为8003即可。

server:port: 8002
...多余部分省略server:port: 8003
...多余部分省略

项目启动,nacos中可以发现,服务端两个实例

在这里插入图片描述

多次调用客户端接口,看结果

在这里插入图片描述

依次轮询方式请求服务。

OpenFeign的超时配置

2020版本以前的OpenFeign的默认等待接口返回数据的时间是1s,超过1秒就报错,如果有fallback,那么执行fallback的处理。

2020版本后,源码如下:

public Options() {//10L: connectTimeout//60L: readTimeoutthis(10L, TimeUnit.SECONDS, 60L, TimeUnit.SECONDS, true);
}

connectTimeout是10s,readTimeout是60s

普通接口是没有问题的,但是如果是一些耗时业务,执行过程中一定是大于1s的,不太合理。

那么OpenFeign提供了超时的配置。消费者bootstrap.yml文件中增加超时配置:

  • feign.client.config.default.connectTimeout:建立连接的超时时间
  • feign.client.config.default.readTimeout:建立连接后从服务器读取资源所用时间的超时时间配置
server:port: 9001
spring:application:name: consumer # 应用名cloud:nacos:discovery:server-addr: localhost:8848 # nacos服务地址sentinel:transport:port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描dashboard: 127.0.0.1:8080 # 仪表版访问地址
feign:sentinel:enabled: trueclient:config:default:connectTimeout: 2000 # 建立连接超时时间readTimeout: 2000   # 读取资源超时时间
@RequestMapping("/openFeignProviderTest")
public String openFeignProviderTest() throws InterruptedException {Thread.sleep(5000);return "OpenFeignTestController#openFeignProviderTest" + port;
}

在这里插入图片描述

这里故意睡眠5s,超时时间是2s那么,一定是超时了,会进入fallback.

时间调长点试试

..
feign:sentinel:enabled: trueclient:config:default:connectTimeout: 7000 # 建立连接超时时间readTimeout: 7000   # 读取资源超时时间

在这里插入图片描述

没问题

OpenFeign的日志

为方便查找异常,一般在本地开发环境中,把OpenFeign远程调用接口的日志详情打印出来。

服务消费者bootstrap.yml文件新增日志级别的配置,新增配置项logging.level.声明接口的包名,完整配置如下:

server:port: 9001
spring:application:name: consumer # 应用名cloud:nacos:discovery:server-addr: localhost:8848 # nacos服务地址sentinel:transport:port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描dashboard: 127.0.0.1:8080 # 仪表版访问地址
feign:sentinel:enabled: trueclient:config:default:connectTimeout: 5000 # 建立连接超时时间readTimeout: 5000   # 读取资源超时时间logging:level:com.alibaba.provider.feigns: debug # 打印自己项目中com.alibaba.provider.feigns包的日志,级别是debug级别

然后在java中创建一个配置类

@Configuration
public class OpenFeignLoggerConfiguration {@Beanpublic Logger.Level openFeignLoggerLevel() {return Logger.Level.FULL;   // FULL日志级别}}

OpenFeign日志有以下几个级别

  • NONE:无记录,默认的
  • BASIC:只记录请求方法和url及响应状态代码和执行时间
  • HEADERS:只记录基本信息及请求和响应头
  • FULL:记录请求和响应的头文件,正文和元数据,信息最全

配置后日之后,如下:

在这里插入图片描述

信息非常完整,方便排错。

请求和响应压缩

OpenFeign支持通过简单配置实现请求和响应进行gzip压缩,提高数据传输的效率。

开启压缩可以有效节约网络资源,但是在压缩和解压过程中会增加CPU的压力,最好把最小请求长度参数调大一些。

bootstrap.yml文件中,增加参数配置(服务消费者端):

server:port: 9001
spring:application:name: consumer # 应用名cloud:nacos:discovery:server-addr: localhost:8848 # nacos服务地址sentinel:transport:port: 8719 # 启动http server,并且该服务与Sentinel仪表板进行交互,使sentinel可以控制应用,若端口占用则8719+1依次扫描dashboard: 127.0.0.1:8080 # 仪表版访问地址
feign:sentinel:enabled: trueclient:config:default:connectTimeout: 5000 # 建立连接超时时间readTimeout: 5000   # 读取资源超时时间compression:request:enabled: true # 请求压缩启用mime-types: text/xml, application/xml, application/json # 要压缩的类型min-request-size: 2048 # 最小请求长度 单位:字节response:enabled: true # 响应压缩启用logging:level:com.alibaba.provider.feigns: debug # 打印com.alibaba.provider.feigns包的日志,级别是debug级别

压缩后,可以看下日志情况:

在这里插入图片描述

OpenFeign的参数传递

简单参数传递

服务端接口

@PostMapping("/sampleParamsProviderTest")
public String sampleParamsProviderTest(@RequestParam("name") String name, @RequestParam("id") Integer id) {return "OpenFeignProviderTest# sampleParamsProviderTest#" + port + "id=" + id + ",name=" + name;
}

消费者OpenFeign

@FeignClient(value = "${provider.name}", fallback = OpenFeignTestServiceFallback.class)
public interface OpenFeignTestService {@PostMapping("/sampleParamsProviderTest")public String sampleParamsProviderTest(@RequestParam("name") String name, @RequestParam("id") Integer id);}

消费者fallback

@Component
public class OpenFeignTestServiceFallback implements OpenFeignTestService {@Overridepublic String sampleParamsProviderTest(String name, Integer id) {return "我是兜底方法" + name + id;}
}

消费者提供一个接口做测试

@GetMapping("/sampleParamsProviderTest")
public String sampleParamsProviderTest() {return openFeignTestService.sampleParamsProviderTest("gangge", 1);
}

在这里插入图片描述

@SpringQueryMap对象传递

那么先创建一个要传递的对象,服务提供者和消费者共用

public class Params {private Integer id;private String name;.../getter、setter方法
}

服务提供者,创建一个给消费者调用的接口

@GetMapping("/springQueryMapProviderTest")
public String springQueryMapProviderTest(Params params) {return "OpenFeignProviderTest# sampleParamsProviderTest#" + port + "id=" + params.getId() + ",name=" + params.getName();
}

消费者OpenFeign

@GetMapping("/springQueryMapProviderTest")
public String springQueryMapProviderTest(@SpringQueryMap Params params);

消费者fallback

@Override
public String springQueryMapProviderTest(Params params) {return "我是兜底方法" + params.getId() + params.getName();
}

消费者接口

@GetMapping("/springQueryMapTest")
public String springQueryMapTest() {Params params = new Params();params.setId(1);params.setName("gangge");return openFeignTestService.springQueryMapProviderTest(params);
}

结果

在这里插入图片描述

复杂对象传递

对象套对象的情况,准备一个ComplexObjectResult对象(提供者和消费者都需要创建)

ComplexObject

public class ComplexObject {private Params params;public Params getParams() {return params;}public void setParams(Params params) {this.params = params;}
}

Result

public class Result {private Integer code;private String describe;public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getDescribe() {return describe;}public void setDescribe(String describe) {this.describe = describe;}
}

在服务提供方编写接口,接受消费者调用,后返回Result对象

@PostMapping("/complexObjectProviderTest")
public Result complexObjectProviderTest(@RequestBody ComplexObject complexObject) {Result result = new Result();result.setCode(200);result.setDescribe("#complexObjectProviderTest" + complexObject.getParams().getName() + complexObject.getParams().getId());return result;
}

消费者声明客户端接口和fallback操作

@PostMapping("/complexObjectProviderTest")
public Result complexObjectProviderTest(@RequestBody ComplexObject complexObject);@Override
public Result complexObjectProviderTest(ComplexObject complexObject) {return null;
}

返回Result对象**

@PostMapping("/complexObjectProviderTest")
public Result complexObjectProviderTest(@RequestBody ComplexObject complexObject) {Result result = new Result();result.setCode(200);result.setDescribe("#complexObjectProviderTest" + complexObject.getParams().getName() + complexObject.getParams().getId());return result;
}

消费者声明客户端接口和fallback操作

@PostMapping("/complexObjectProviderTest")
public Result complexObjectProviderTest(@RequestBody ComplexObject complexObject);@Override
public Result complexObjectProviderTest(ComplexObject complexObject) {return null;
}

复杂对象时@RequestBody注解完全可以,但是只能有一个@RequestBody的参数

相关文章:

SpringCloudAlibaba OpenFeign整合及详解

SpringCloudAlibaba OpenFeign 在前面&#xff0c;我们使用Nacos服务注册发现后&#xff0c;服务远程调用可以使用RestTemplateRibbon或者OpenFeign调用。实际开发中很少使用RestTemplate这种方式进行调用服务&#xff0c;每次调用需要填写地址&#xff0c;还要配置各种的参数&…...

Mysql--技术文档--MVCC(Multi-Version Concurrency Control | 多版本并发控制)

MVCC到底是什么 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;是一种并发控制机制&#xff0c;用于解决并发访问数据库时的数据一致性和隔离性问题。MVCC允许多个事务同时读取数据库的同一数据&#xff0c;而不会相互干扰或导致冲突。 在传统的并发控制机制中…...

全网都在用的nnUNet V2版本改进了啥,怎么安装?(一)

nnUNet&#xff0c;这个医学领域的分割巨无霸!在论文和比赛中随处可见他的身影。大家对于nnUNet v1版本的教程都赞不绝口&#xff0c;因为它简单易懂、详细全面&#xff0c;让很多朋友都轻松掌握了使用方法。 最近&#xff0c;我也抽出时间仔细研究了nnUNet v2&#xff0c;并全…...

iOS开发Swift-4-IBAction,group,音乐播放器-木琴App

1.使用素材创建木琴App的UI。 2.连接IBAction。 其余按钮直接拖拽到play里边。 当鼠标置于1处时2处显示如图&#xff0c;表示成功。当用户按下任一按钮都会触发play中的内容。 3.将7个按钮的View中的Tag值分别调为1、2、3、4、5、6、7. 4.将音频文件拖入项目文件中。 Create gr…...

【linux】pid 文件的作用ing

文章目录 一. pid文件简介1. pid 文件是什么2. 作用 二. pid文件的使用 一. pid文件简介 1. pid 文件是什么 打开系统(Linux) 的 “/var/run/” 目录可以看到有很多已 “.pid” 为结尾的文件&#xff0c;只有一行&#xff0c;它记录的是相应进程的 pid&#xff0c;即进程号。…...

K8s简介之什么是K8s

目录 1.概述 2.什么是容器引擎&#xff1f; 3.什么是容器 4.什么是容器编排&#xff1f; 5.容器编排工具 6.到底什么是K8s? 7.为什么市场推荐K8s 8.K8s架构 9.K8s组件 Pods API 服务器 调度器 控制器管理器 Etcd 节点 Kubelet Kube代理 Kubectl 1.概述 Kub…...

说说Flink双流join

分析&回答 Flink双流JOIN主要分为两大类 一类是基于原生State的Connect算子操作另一类是基于窗口的JOIN操作。其中基于窗口的JOIN可细分为window join和interval join两种。 基于原生State的Connect算子操作 实现原理&#xff1a;底层原理依赖Flink的State状态存储&…...

I2C与I3C的对比

I2C与I3C的对比 电气特性 I2C 1.半双工 2.串行数据线(SDA)和串行时钟线(SCL) 3.数据线漏极开路&#xff0c;即I2C接口接上拉电阻 4.I2C总线运行速度&#xff1a;**标准模式100kbit/s&#xff0c;快速模式400kbit/s&#xff0c;快速模式plus 1Mbit/s&#xff0c;**高速模式…...

睿趣科技:抖音开小店大概多久可以做起来

随着移动互联网的快速发展&#xff0c;社交媒体平台成为了人们分享生活、交流信息的主要渠道之一。在众多社交平台中&#xff0c;抖音以其独特的短视频形式和强大的用户粘性受到了广泛关注。近年来&#xff0c;越来越多的人通过在抖音上开设小店来实现创业梦想&#xff0c;这种…...

CCF-CSP 26次 第三题【角色授权】

计算机软件能力认证考试系统 20分&#xff1a; #include<bits/stdc.h> using namespace std; const int N440; int n,m,q,nv,no,nn,ns,ng; struct Node {string name;map<string,int>op;map<string,int>res_kind;map<string,int>res_name; }role[N];…...

Ansible学习笔记11

Command和Shell模块&#xff1a; 两个模块都是用于执行Linux命令的&#xff0c;这个对于命令熟悉的工程师来说&#xff0c;用起来非常high。 Shell模块跟Command模块差不多&#xff08;Command模块不能执行一类$HOME、> 、<、| 等符号&#xff0c;但是Shell是可以的。&…...

Vue中如何为Echarts统计图设置数据

在前端界面接收后端数据后&#xff0c;将数据赋值给ECharts中的data时出现了&#xff0c;数据读取失败的问题&#xff08;可能是由于数据渲染的前后顺序问题&#xff09;。后通过如下方式进行了解决&#xff1a; 1、接下来将介绍UserController中的countUsers方法&#xff0c;…...

力扣141. 环形链表

141. 环形链表 简单 2K 相关企业 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链…...

4.1 链式栈StackT

C关键词&#xff1a;内部类/模板类/头插 C自学精简教程 目录(必读) C数据结构与算法实现&#xff08;目录&#xff09; 栈的内存结构 空栈&#xff1a; 有一个元素的栈&#xff1a; 多个元素的栈&#xff1a; 成员函数说明 0 clear 清空栈 clear 函数负责将栈的对内存释放…...

算法练习(10):牛客在线编程10 贪心算法

package jz.bm;import java.util.ArrayList; import java.util.Arrays;public class bm10 {/*** BM95 分糖果问题*/public int candy (int[] arr) {int res 0;int n arr.length;int[] nums new int[n];//每个人都分配一个糖果for (int i 0; i < n; i) {nums[i] 1;}//从…...

Java8新特性1——函数式接口lambda表达式

Java8新特性1——函数式接口&lambda表达式 注&#xff1a;以下内容基于Java 8&#xff0c;所有代码都已在Java 8环境下测试通过 目录&#xff1a; Java8新特性1——函数式接口&lambda表达式方法引用Stream 1. 函数式接口 如果在一个接口中&#xff0c;有且只有一个抽…...

文本标注技术方案(NLP标注工具)

Doccano doccano 是一个面向人类的开源文本注释工具。它为文本分类、序列标记和序列到序列任务提供注释功能。您可以创建用于情感分析、命名实体识别、文本摘要等的标记数据。只需创建一个项目&#xff0c;上传数据&#xff0c;然后开始注释。您可以在数小时内构建数据集。 支持…...

03-使用一个不可变对象作为key,红黑树怎么比较大小?

使用一个不可变对象作为key&#xff0c;红黑树怎么比较大小&#xff1f; 答&#xff1a;Java 中的红黑树是通过左旋、右旋的方式来维护树的平衡性&#xff0c;而左旋、右旋又依赖于节点大小的比较。对于使用不可变对象作为key实际上是可以的&#xff0c;因为比较key的大小本身…...

2021江苏省赛热身赛 C Magic Rabbit(数形结合)

2021江苏省赛热身赛 C Magic Rabbit(数形结合) Magic Rabbit 非常好且巧妙地一道题。 大意&#xff1a;给出三种溶液 &#xff0c; 三种溶液分别含有不同浓度的 x &#xff0c;y 两种物质。 溶液x (mg/ml)y (mg/ml)溶液1x1y1溶液2x2y2溶液3x3y3 给出 Q 组询问 &#xff0c…...

AES加密(2):AES代码实现解析

在我的上一篇文章AES基础知识和计算过程中&#xff0c;大概介绍了AES(Rijndael)加密的整个过程。那么在这一篇文章中&#xff0c;就来看一下AES在代码中是如何实现的&#xff0c;也有助于我们理解其中的一些细节。 本篇文章所用的AES代码来源于Szymon Stefanek的开源C代码 文章…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...