【系统设计【4】】设计一个限流器:从理论到实践的完整解决方案

文章目录

  • 第一步:理解问题并确定设计范围
    • 1、为什么需要限流器
    • 2、需求澄清的艺术
    • 3、需求总结与优先级
  • 第二步:提出高层次设计并获得认同
    • 1. 限流器的部署位置选择
    • 2. 限流算法的选择与权衡
    • 3. 高层架构设计
  • 第三步:深入设计
    • 1、限流规则的设计与管理
    • 2、分布式环境下的挑战与解决方案
    • 3、性能优化的深度实践
    • 4、监控与告警体系
  • 第四步:总结与优化
    • 1、系统瓶颈分析与解决方案
      • 1.1. 存储层瓶颈
      • 1.2. 网络延迟优化
    • 2、容错与降级策略
    • 3、未来扩展考虑
    • 4、设计总结与最佳实践

在现代分布式系统中,限流器是保护系统稳定性的重要组件。当我们面对"设计一个限流器"这样的系统设计问题时,很多人可能会立即想到某个具体的算法或技术实现。然而,一个优秀的限流器设计需要考虑的远不止算法本身,它涉及业务需求分析、架构设计、性能优化、监控告警等多个层面

 

第一步:理解问题并确定设计范围

1、为什么需要限流器

在深入设计之前,我们需要理解限流器在系统中的价值。限流器不仅仅是一个技术组件,更是业务连续性的保障。

防止系统过载

  • 想象一个电商网站在双十一期间突然涌入大量用户,如果没有限流保护,系统可能因为无法处理过量请求而崩溃,导致所有用户都无法正常使用服务。限流器通过控制请求速率,确保系统在可承受范围内稳定运行。

成本控制

  • 对于使用第三方API的企业来说,限流器直接关系到成本控制。比如,一个金融应用需要调用征信API进行用户信用检查,每次调用都需要付费。如果没有限流控制,恶意攻击或程序错误可能导致API调用次数激增,造成巨大的经济损失。

安全防护

  • 限流器是抵御DDoS攻击的第一道防线。通过限制单个IP或用户的请求频率,可以有效阻止恶意用户通过大量请求攻击系统。

 

2、需求澄清的艺术

在系统设计面试中,需求澄清是展示你思考深度的重要环节。当面试官提出"设计一个限流器"时,你需要通过一系列问题来明确具体需求:

功能性需求的深入探讨

  1. "我们设计的限流器主要应用场景是什么?是保护API服务器,还是防止爬虫,或者是控制用户行为?"这个问题帮助确定限流器的核心目标
  2. "限流的维度是什么?是基于IP地址、用户ID、API端点,还是需要支持多维度组合限流?"不同的限流维度会影响数据模型和存储策略的设计。
  3. "限流规则的复杂度如何?是简单的固定速率限制,还是需要支持动态调整、分级限流等高级功能?"这决定了规则引擎的复杂程度

 

非功能性需求的量化

  1. "系统需要支持多大的请求量?每秒处理多少请求?"这个问题帮助确定系统的性能目标。
  2. "对延迟的要求是什么?限流器的处理时间不能超过多少毫秒?"延迟要求直接影响技术选型和架构设计。
  3. "系统的可用性要求是什么?限流器故障时系统应该如何表现?"这涉及到容错设计和降级策略。

 
部署环境的了解

  1. "系统是部署在单机环境还是分布式环境?如果是分布式,有多少个节点?"这决定了数据同步和一致性策略
  2. "现有的技术栈是什么?有哪些可以复用的基础设施?"了解现有环境有助于做出合适的技术选择。

 

3、需求总结与优先级

通过充分的需求澄清,我们可以总结出限流器的核心要求:

核心功能要求

  • 准确限制超出阈值的请求
  • 支持多种限流维度(IP、用户、API等)
  • 支持灵活的限流规则配置
  • 提供清晰的限流反馈信息

性能要求

  • 低延迟:限流判断时间不超过1ms
  • 高吞吐:支持每秒百万级请求处理
  • 内存高效:单个限流规则占用内存不超过1KB

可靠性要求

  • 高可用:99.9%的服务可用性
  • 容错性:单点故障不影响整体服务
  • 数据一致性:分布式环境下的计数准确性

 

第二步:提出高层次设计并获得认同

1. 限流器的部署位置选择

限流器的部署位置是一个关键的架构决策,不同的选择会带来不同的优缺点。

  1. 客户端限流的局限性
    虽然在客户端实现限流看起来简单直接,但这种方案存在明显的安全隐患。恶意用户可以轻易绕过客户端限制(直接使用curl调用API),直接向服务器发送大量请求。此外,我们无法控制所有客户端的实现,特别是第三方开发的客户端应用。

  2. 服务端限流的优势
    将限流器部署在服务端可以确保所有请求都经过限流检查,无法被绕过。这种方案的安全性更高,但会增加服务器的处理负担。

  3. 中间件限流的平衡
    在API网关或负载均衡器层面实现限流是一个很好的折中方案。这种部署方式既保证了安全性,又避免了对业务服务器的直接影响。现代的API网关如Kong、Zuul等都提供了内置的限流功能。

 

2. 限流算法的选择与权衡

不同的限流算法适用于不同的场景,选择合适的算法是设计成功的关键。

  1. 令牌桶算法:应对突发流量
  • 令牌桶算法是最常用的限流算法之一,其核心思想是通过令牌的生成和消耗来控制请求速率。

  • 算法的工作机制可以这样理解:想象一个水桶,以固定速率往桶里放入令牌,每个请求需要消耗一个令牌才能通过。如果桶满了,多余的令牌会溢出;如果桶空了,请求就会被拒绝。

  • 这种算法的优势在于能够处理突发流量。比如,一个API限制每秒10个请求,但允许短时间内处理20个请求(如果之前有令牌积累)。这种特性使得令牌桶算法特别适合处理不均匀的流量模式。

 

  1. 滑动窗口算法的精确性
  • 滑动窗口算法通过维护一个时间窗口内的请求记录来实现精确的限流控制。与固定窗口算法相比,它避免了窗口边界的突发流量问题。

  • 例如,如果限制每分钟100个请求,固定窗口算法可能在第59秒和第61秒之间的2秒内允许200个请求通过。而滑动窗口算法会确保任意连续60秒内的请求数不超过100个

 

算法选择的实际考虑

在实际应用中,算法的选择需要考虑多个因素:

  • 如果业务场景需要严格的速率控制,滑动窗口算法是更好的选择
  • 如果需要处理突发流量,令牌桶算法更合适
  • 如果对内存使用有严格要求,固定窗口计数器算法是最经济的选择
  • 如果需要在精确性和性能之间平衡,滑动窗口计数器算法是一个好的折中方案

 

3. 高层架构设计

基于需求分析和算法选择,我们可以设计出限流器的高层架构。

核心组件识别
一个完整的限流器系统包含以下核心组件:

  • 限流中间件:这是系统的入口点,负责拦截所有请求并进行限流判断。它需要具备高性能和低延迟的特点,因为每个请求都要经过这里。

  • 规则引擎:负责管理和解析限流规则。规则引擎需要支持复杂的规则表达式,如"每个用户每分钟最多10个请求,但VIP用户可以每分钟20个请求"。

  • 计数存储:用于存储各种维度的请求计数。由于需要高频读写和快速过期,通常选择Redis等内存数据库。

  • 配置管理:负责限流规则的配置、更新和分发。支持热更新功能,避免因规则变更而重启服务。

 
数据流设计
当一个请求到达系统时,处理流程如下:

  1. 请求首先到达限流中间件
  2. 中间件根据请求特征(IP、用户ID等)确定适用的限流规则
  3. 从计数存储中获取当前计数值
  4. 根据选定的算法判断是否允许请求通过
  5. 更新计数值并设置过期时间
  6. 如果允许通过,将请求转发给后端服务;否则返回限流错误

 

容量估算与验证

假设我们的系统需要支持每秒100万个请求,其中10%需要进行限流检查。那么限流器需要处理每秒10万次限流判断。

每次限流判断包括: 1次Redis读操作(获取计数)、 1次Redis写操作(更新计数)、少量CPU计算(算法逻辑)

基于Redis的性能特点(单实例每秒可处理10万次操作),我们可能需要部署多个Redis实例来满足性能要求。

 

第三步:深入设计

1、限流规则的设计与管理

限流规则是整个系统的核心,其设计的灵活性直接影响系统的适用性。

规则表达式的设计
一个好的限流规则应该能够清晰地表达复杂的业务逻辑。以下是一些典型的规则示例:

# 基础限流规则
- name: "api_rate_limit"dimension: "api_endpoint"key: "/api/users"limit: 1000window: "1m"algorithm: "sliding_window"# 多维度限流规则
- name: "user_post_limit"dimensions:- type: "user_id"key: "{user_id}"- type: "action"key: "post"limit: 10window: "1h"algorithm: "token_bucket"burst: 5# 分级限流规则
- name: "tiered_api_limit"conditions:- if: "user.tier == 'premium'"limit: 10000- if: "user.tier == 'standard'"limit: 1000- default: 100window: "1m"

 
规则优先级与冲突处理
当多个规则同时适用于一个请求时,需要明确的优先级机制:

  1. 具体规则优先于通用规则
  2. 用户级规则优先于IP级规则
  3. 严格限制优先于宽松限制

 

动态规则更新
在生产环境中,限流规则需要支持动态更新而不影响服务可用性。这可以通过以下机制实现:

  • 配置中心:使用Consul、Etcd等配置中心存储规则
  • 热更新:通过配置变更通知机制实现规则的实时更新
  • 灰度发布:新规则先在小部分流量上验证,确认无误后全量发布

 

2、分布式环境下的挑战与解决方案

当限流器部署在分布式环境中时,面临的主要挑战是如何在多个节点间保持计数的一致性

竞争条件分析
在高并发场景下,多个请求可能同时读取同一个计数器的值,导致计数不准确。考虑这样一个场景:当前计数器值为99,限制为100。两个请求同时到达不同的限流器节点:

  1. 节点A读取计数器值:99
  2. 节点B读取计数器值:99
  3. 节点A判断99+1=100,允许通过,将计数器更新为100
  4. 节点B判断99+1=100,允许通过,将计数器更新为100

结果是两个请求都通过了,但实际计数器应该是101,超出了限制。

 

解决方案的技术实现
Lua脚本方案
Redis支持Lua脚本的原子执行,可以将读取、判断、更新操作封装在一个脚本中:

local key = KEYS[1]
local limit = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local current = redis.call('GET', key)if current == false thencurrent = 0
elsecurrent = tonumber(current)
endif current < limit thenredis.call('INCR', key)redis.call('EXPIRE', key, window)return 1
elsereturn 0
end

分布式锁方案
使用Redis的分布式锁来保证操作的原子性:

def rate_limit_with_lock(key, limit, window):lock_key = f"lock:{key}"with redis_lock(lock_key, timeout=0.1):current = redis.get(key) or 0if int(current) < limit:redis.incr(key)redis.expire(key, window)return Truereturn False

 

数据同步策略(ing)
在多数据中心部署的场景下,完全的强一致性可能会影响性能。可以采用最终一致性模型

  • 本地计数:每个数据中心维护本地计数器
  • 定期同步:定期将本地计数同步到全局计数器
  • 动态调整:根据全局计数动态调整本地限制

 

3、性能优化的深度实践

缓存策略优化
多级缓存

  • L1缓存:进程内缓存,存储最热门的限流规则
  • L2缓存:本地Redis,存储当前节点的计数数据
  • L3缓存:集群Redis,存储全局计数数据

缓存预热
在系统启动时,预先加载常用的限流规则和计数数据,避免冷启动时的性能问题。

 

算法优化
近似算法
对于不需要严格精确的场景,可以使用近似算法来提高性能:

class ApproximateCounter:def __init__(self, error_rate=0.01):self.counters = [0] * int(1 / error_rate)self.hash_functions = self._generate_hash_functions()def increment(self, key):for hash_func in self.hash_functions:index = hash_func(key) % len(self.counters)self.counters[index] += 1def estimate(self, key):estimates = []for hash_func in self.hash_functions:index = hash_func(key) % len(self.counters)estimates.append(self.counters[index])return min(estimates)

 

批量处理
将多个限流检查批量处理,减少网络往返次数:

def batch_rate_limit(requests):pipeline = redis.pipeline()for req in requests:key = generate_key(req)pipeline.get(key)current_values = pipeline.execute()pipeline = redis.pipeline()results = []for i, req in enumerate(requests):current = current_values[i] or 0if int(current) < req.limit:key = generate_key(req)pipeline.incr(key)pipeline.expire(key, req.window)results.append(True)else:results.append(False)pipeline.execute()return results

 

4、监控与告警体系

关键指标的定义

业务指标

  • 限流触发率:被限流的请求占总请求的比例
  • 误限率:不应该被限流但被限流的请求比例
  • 漏限率:应该被限流但未被限流的请求比例

性能指标

  • 限流判断延迟:从请求到达到限流判断完成的时间
  • 吞吐量:每秒处理的限流判断次数
  • 资源使用率:CPU、内存、网络的使用情况

系统指标

  • 可用性:限流服务的可用时间比例
  • 错误率:限流判断过程中的错误比例
  • 恢复时间:故障后系统恢复正常的时间

 

实时监控系统

class RateLimiterMonitor:def __init__(self):self.metrics = {'total_requests': 0,'limited_requests': 0,'processing_time': [],'error_count': 0}def record_request(self, limited, processing_time, error=False):self.metrics['total_requests'] += 1if limited:self.metrics['limited_requests'] += 1self.metrics['processing_time'].append(processing_time)if error:self.metrics['error_count'] += 1def get_statistics(self):total = self.metrics['total_requests']limited = self.metrics['limited_requests']times = self.metrics['processing_time']errors = self.metrics['error_count']return {'limit_rate': limited / total if total > 0 else 0,'avg_processing_time': sum(times) / len(times) if times else 0,'error_rate': errors / total if total > 0 else 0,'p99_processing_time': self._percentile(times, 99)}

 

第四步:总结与优化

1、系统瓶颈分析与解决方案

1.1. 存储层瓶颈

当请求量达到一定规模时,Redis可能成为性能瓶颈。解决方案包括:

分片策略
根据限流键的哈希值将数据分布到多个Redis实例:

def get_redis_instance(key):hash_value = hash(key)shard_index = hash_value % len(redis_instances)return redis_instances[shard_index]

 

读写分离
使用Redis主从复制,将读操作分发到从节点:

def rate_limit_check(key, limit):# 读操作使用从节点current = redis_slave.get(key) or 0if int(current) >= limit:return False# 写操作使用主节点redis_master.incr(key)return True

 

1.2. 网络延迟优化

就近访问
在多个地理位置部署限流器,请求自动路由到最近的节点。

 

连接池优化
使用连接池减少连接建立的开销:

redis_pool = redis.ConnectionPool(host='localhost',port=6379,max_connections=100,socket_keepalive=True,socket_keepalive_options={}
)

 

2、容错与降级策略

故障检测机制

class HealthChecker:def __init__(self, redis_client):self.redis = redis_clientself.failure_count = 0self.last_check = time.time()def is_healthy(self):try:self.redis.ping()self.failure_count = 0return Trueexcept Exception:self.failure_count += 1return self.failure_count < 3

降级策略
当限流器出现故障时,系统应该有明确的降级策略:

快速失败模式:直接拒绝所有请求,保护后端服务
快速通过模式:允许所有请求通过,避免影响用户体验
本地限流模式:使用本地缓存进行简单的限流控制

 

3、未来扩展考虑

机器学习集成
利用机器学习算法动态调整限流参数:

class AdaptiveRateLimiter:def __init__(self):self.model = self._load_ml_model()self.historical_data = []def predict_optimal_limit(self, current_metrics):features = self._extract_features(current_metrics)predicted_limit = self.model.predict([features])[0]return max(predicted_limit, self.min_limit)def update_model(self, feedback):self.historical_data.append(feedback)if len(self.historical_data) > 1000:self._retrain_model()

多租户支持
为不同的租户提供隔离的限流服务:

class MultiTenantRateLimiter:def __init__(self):self.tenant_configs = {}self.tenant_counters = {}def rate_limit(self, tenant_id, key, request):config = self.tenant_configs.get(tenant_id)if not config:return True  # 默认允许通过tenant_key = f"{tenant_id}:{key}"return self._check_limit(tenant_key, config)

实时规则引擎
支持基于实时事件的动态限流:

class EventDrivenRateLimiter:def __init__(self):self.event_handlers = {}self.dynamic_rules = {}def on_event(self, event_type, handler):self.event_handlers[event_type] = handlerdef process_event(self, event):handler = self.event_handlers.get(event.type)if handler:new_rules = handler(event)self.dynamic_rules.update(new_rules)

 

4、设计总结与最佳实践

通过这个完整的设计过程,我们构建了一个功能完善、性能优异的限流器系统。这个设计的核心优势包括:

架构优势

  • 模块化设计,各组件职责清晰
  • 支持多种限流算法,可根据场景选择
  • 分布式架构,支持水平扩展
  • 完善的监控和告警机制

性能优势

  • 低延迟的限流判断(<1ms)
  • 高吞吐量支持(>100万QPS)
  • 内存使用优化
  • 网络开销最小化

可靠性优势

  • 多级容错机制
  • 优雅的降级策略
  • 数据一致性保证
  • 故障快速恢复

这个限流器设计不仅解决了当前的业务需求,还为未来的扩展留下了充足的空间。在实际实施过程中,可以根据具体的业务场景和技术约束进行适当的调整和优化。

最重要的是,这个设计过程展示了系统设计的完整思路:从需求分析到架构设计,从核心功能到性能优化,从单机实现到分布式部署。 这种系统性的思考方式不仅适用于限流器的设计,也适用于其他复杂系统的设计工作。

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

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

相关文章

基于DETR目标检测项目

DETR见解 DETR&#xff08;Detection Transformer&#xff09;是一种端到端的目标检测模型&#xff0c;由Facebook AI Research&#xff08;FAIR&#xff09;于2020年提出。DETR采用了Transformer架构&#xff0c;与传统的基于区域的目标检测方法有所不同&#xff0c;它通过全…

ZooKeeper 集群部署

ZooKeeper 集群部署 前言安装部署资源下载JDK 部署Zookeeper 部署 前言 在 Linux 服务器上部署 Zookeeper 之前&#xff0c;需要先安装 JDK。以下是相关版本及环境信息&#xff1a; JDK 版本 jdk-17_linux-x64_bin.tar.gz Zookeeper 部署的版本 3.5.7 操作系统版本 Red Hat E…

8.TCP Server端实现

1.C/S模型 2.Server 端功能分析 tcp_server.c #include "tcp_server.h" #include "lwip/sockets.h" #include <stdio.h>char ReadBuff[BUFF_SIZE]; /* TCP服务器任务函数 */ void vTcpserver_Task(void) {int sfd, cfd, n, i;struct sockaddr_in…

课设作业图书管理系统

用户注册&#xff0c;登录 播放地址 课设作业图书管理系统_哔哩哔哩_bilibili 对图书进行增删改查 package com.xwr.controller; import com.xwr.entity.Book; import com.xwr.entity.Category; import com.xwr.service.BookService; import com.xwr.service.CategoryServ…

springboot 配置加密

springboot 配置加密 [TOC](springboot 配置加密) 前言一、在配置类赋值之前解密二、修改赋值后加密的配置类 前言 在一些国家项目中经常会要求不能暴露数据库链接和密码, 所以需要对配置文件里面的一些配置进行加密处理。 解决方法有两种&#xff1a;一种是在配置加载后还没给…

【操作系统】macOS软件提示“已损坏,打不开”的解决方案

macOS软件提示“已损坏&#xff0c;打不开”的解决方案 在使用 macOS 系统时&#xff0c;不少用户都遇到过这样的情况&#xff1a;当尝试打开某个应用程序时&#xff0c;系统弹出提示“xxx 已损坏&#xff0c;打不开。您应该将它移到废纸篓”&#xff0c;或者显示“无法打开‘…

数据库系统概论(二十)数据库恢复技术

数据库系统概论&#xff08;二十&#xff09;数据库恢复技术 前言一、事务的基本概念1. 什么是事务&#xff1f;2. 事务的两种"打开方式"2.1 隐式事务2.2 显式事务&#xff1a;自己动手打包操作 3. 事务的四大"铁律3.1 原子性3.2 一致性3.3 隔离性3.4 持久性 4.…

java将pdf文件转换为图片工具类

一、相关依赖 <!-- PDFBox for PDF processing --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version></dependency>二、工具类 import org.apache.pdfbox.p…

零门槛探索国产数据库硬核实力 —— 金仓数据库在线体验平台体验记

1、 金仓数据库在线体验平台 最近&#xff0c;我发现了一个超棒的数据库宝藏 —— 金仓数据库在线体验平台。它在金仓社区上线后&#xff0c;凭借 “零门槛体验 多场景交互” 的特点&#xff0c;迅速吸引了众多数据库爱好者的目光&#xff0c;我也忍不住去体验了一番。 2、 …

Linux基本操作指令和vim编译器

基本指令 查看日期与日历 data 指令 显示日期 用法1&#xff1a;data CST&#xff1a;China Standard Time 时区&#xff0c;中国标准时间 用法2&#xff1a; data 指定格式 常用格式&#xff1a; “%Y-%m-%d”(%F): 2025-06-16“%H:%M:%S”(%T): 20:19:45“%F%T”用法3&am…

“从HTTP到TCP/IP的旅程“-----深入浅出Java Web通信

先放结构图&#xff1a; 一、引言&#xff1a;网络通信就像寄快递 想象一下我们在网上买了一本书&#xff0c;整个配送过程是这样的&#xff1a; 应用层&#xff1a;你在购物网站填好收货地址&#xff08;HTTP请求&#xff09;传输层&#xff1a;快递公司把包裹打包&#xf…

docker build使用代理以实现构建过程中下载Github源码等操作

在通过Dockerfile构建docker容器的过程中&#xff0c;经常会需要在构建过程中拉取Github上的代码。当宿主机配好代理&#xff0c;但容器内是一个隔离的环境&#xff0c;若想在容器内访问&#xff0c;则需再打通容器和宿主机之间的代理配置。 方法一&#xff1a; 若宿主机上的…

Docker 快速搭建一个基于 GPT-Vis 组件的统计图表生成服务

以下是对工具简单介绍&#xff1a; 可以在服务端使用 GPT-Vis 统计图表组件直接渲染成图片支持Docker一键部署&#xff0c;提供统计图表渲染生成API接口支持多种GPT-Vis支持的组件&#xff0c;包括折线图、柱形图、饼图、面积图、条形图、直方图、散点图、词云图、雷达图、思维…

hal库练习1

要求&#xff1a;一个按键实现呼吸灯的控制&#xff0c;一个按键控制LED灯的闪烁&#xff0c;串口发送数据控制灯的开关 定时器配置 1.选择需要的定时器2.配置基础参数&#xff08;根据时钟树给定时器输入的时钟&#xff09;3.打开中断4.在主函数里打开中断 定时器扫描按键 …

java线程(4)

程序(program) 是为完成制定任务,用某种语言编写的一组指令的集合.简单的话说:就是我们写的代码. 进程 1.进程是指进行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间,当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间. 2、…

02《F8Framework》核心入口 FF8.cs

FF8.cs类是 F8Framework的核心入口 采用单例模式 提供对各个功能模块的全局访问 【特点】通过静态类FF8统一访问所有功能 1.模块化设计&#xff1a; 每个功能独立 通过 ModuleCenter 统一管理 2.懒加载机制&#xff1a; …

【硬件】相机的硬件测试

相机测试 author: Alla Imatest 提供超过 30 种测试项目&#xff0c;主要包括&#xff1a; 1&#xff09;图像基础参数‌&#xff1a;MTF&#xff08;调制传递函数&#xff09;、畸变、均匀性、动态范围 2&#xff09;色彩与光学特性‌&#xff1a;白平衡误差、饱和度、gamma …

Profinet与Modbus TCP协议转换技术:西门子S7-1500(主站)和欧姆龙NJ PLC的高效数据交换

一、项目背景 某大型现代化智慧农业养殖场致力于打造全方位智能化的养殖环境。其养殖系统中&#xff0c;环境监测与调控部分选用了西门子S7-1500PLC作为Profinet协议主站。该PLC凭借强大的运算能力和丰富的功能模块&#xff0c;能够精准地采集和处理养殖场内的温度、湿度、空气…

希尔伯特变换,实信号转复信号的FPGA实现思路

希尔伯特变换将实信号转复信号的原理 将实信号的相位推迟90度后作为复信号的虚部。 错误实现方式 实信号经过希尔伯特滤波后得到复信号的虚部&#xff0c;之后直接与实信号组成复信号。而由于滤波器本身会对信号延时&#xff0c;故I路与Q路并不是相差90度&#xff0c;所以此方…

多模态大语言模型演进:从视觉理解到具身智能的技术突破

多模态大语言模型演进:从视觉理解到具身智能的技术突破 多模态大语言模型(MLLMs)正在重塑人工智能的边界,实现从"看见"到"理解"再到"行动"的全链条智能。本文将深入解析苹果最新多模态研究进展,揭示视觉-语言模型十年演进的技术脉络,剖析…