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

【最后203篇系列】004 -Smarklink

说明

这个用来替代nginx。

最初是希望用nginx进行故障检测和负载均衡,花了很多时间,大致的结论是:nginx可以实现,但是是在商业版里。非得要找替代肯定可以搞出来,但是太麻烦了(即使是nginx本身的配置也很烦)。更重要的是,我突然意识到其实我对这方面的需求大幅提升了,nginx无法实现我最核心的功能。

于是我打算自己做一个网关。以下是两者的差别:
在这里插入图片描述

我并不是要做一个新的产品来替代nginx,只是需要对我的应用服务进行非常精细的控制,然后我问了下大模型,是否可行:

使用 Tornado 构建自定义应用网关 是一个非常有挑战性但也非常灵活的选择。通过 Tornado 的异步特性和强大的编程能力,你可以实现非常精细的控制,满足特定的业务需求。以下是实现这一目标的思路和建议:


1. Tornado 作为应用网关的核心功能

你可以利用 Tornado 实现以下网关功能:

反向代理
  • 使用 Tornado 的 AsyncHTTPClienthttpclient 模块,将客户端请求转发到后端服务。
  • 示例:
    from tornado.httpclient import AsyncHTTPClientclass ProxyHandler(tornado.web.RequestHandler):async def get(self):http_client = AsyncHTTPClient()response = await http_client.fetch("http://backend-service" + self.request.uri)self.write(response.body)
    
负载均衡
  • 实现自定义的负载均衡算法(如轮询、加权轮询、最小连接数等)。
  • 示例:
    backend_servers = ["http://backend1", "http://backend2", "http://backend3"]
    current_server = 0class LoadBalancerHandler(tornado.web.RequestHandler):async def get(self):global current_serverbackend_url = backend_servers[current_server]current_server = (current_server + 1) % len(backend_servers)http_client = AsyncHTTPClient()response = await http_client.fetch(backend_url + self.request.uri)self.write(response.body)
    
动态路由
  • 根据请求的路径、头部或其他条件,将请求路由到不同的后端服务。
  • 示例:
    class RouterHandler(tornado.web.RequestHandler):async def get(self):if self.request.path.startswith("/api/v1"):backend_url = "http://api-v1-service"elif self.request.path.startswith("/api/v2"):backend_url = "http://api-v2-service"else:backend_url = "http://default-service"http_client = AsyncHTTPClient()response = await http_client.fetch(backend_url + self.request.uri)self.write(response.body)
    
限流和限速
  • 使用 Tornado 的异步特性实现请求速率限制。
  • 示例:
    from tornado.ioloop import IOLoop
    from tornado.web import RequestHandler
    from tornado.queues import Queuerequest_queue = Queue(maxsize=100)  # 限制并发请求数class RateLimitHandler(RequestHandler):async def get(self):await request_queue.put(None)try:# 处理请求self.write("Hello, world!")finally:request_queue.get_nowait()
    
身份验证和授权
  • 在网关层实现统一的身份验证(如 JWT 验证、OAuth 等)。
  • 示例:
    import jwtclass AuthHandler(tornado.web.RequestHandler):def prepare(self):token = self.request.headers.get("Authorization")if not token:self.set_status(401)self.finish("Unauthorized")try:payload = jwt.decode(token, "secret_key", algorithms=["HS256"])self.current_user = payload["user"]except jwt.InvalidTokenError:self.set_status(401)self.finish("Invalid token")
    
日志和监控
  • 在网关层记录请求日志,并集成监控工具(如 Prometheus)。
  • 示例:
    class LoggingHandler(tornado.web.RequestHandler):def on_finish(self):print(f"Request: {self.request.method} {self.request.uri} - Status: {self.get_status()}")
    

2. Tornado 网关的优势

  • 高度定制化:你可以完全控制网关的行为,实现特定的业务逻辑。
  • 灵活性:Tornado 的异步特性使其能够高效处理高并发请求。
  • 与 Python 生态无缝集成:可以轻松集成其他 Python 库(如数据库驱动、消息队列等)。

3. Tornado 网关的挑战

  • 开发成本高:需要从头实现许多功能(如负载均衡、健康检查、限流等)。
  • 性能瓶颈:Tornado 是 Python 编写的,性能可能不如 Nginx 这样的 C 语言实现。
  • 维护复杂性:自定义网关需要更多的测试和维护工作。

4. 建议的架构

如果你决定使用 Tornado 构建网关,建议采用以下架构:

  1. Nginx 作为前置网关

    • 处理 SSL/TLS 终止、静态文件缓存、DDoS 防护等。
    • 将动态请求转发到 Tornado 网关。
  2. Tornado 作为应用网关

    • 实现精细的流量控制、动态路由、身份验证等功能。
    • 将请求转发到后端的微服务或应用服务器。
  3. 监控和日志

    • 集成 Prometheus、Grafana 等工具,实时监控网关性能。
    • 使用 ELK(Elasticsearch、Logstash、Kibana)堆栈进行日志分析。

5. 示例代码

以下是一个简单的 Tornado 网关示例:

import tornado.ioloop
import tornado.web
from tornado.httpclient import AsyncHTTPClientclass ProxyHandler(tornado.web.RequestHandler):async def get(self):backend_url = "http://backend-service" + self.request.urihttp_client = AsyncHTTPClient()response = await http_client.fetch(backend_url)self.write(response.body)def make_app():return tornado.web.Application([(r"/.*", ProxyHandler),])if __name__ == "__main__":app = make_app()app.listen(8888)tornado.ioloop.IOLoop.current().start()

总结

使用 Tornado 构建自定义应用网关是可行的,尤其适合需要高度定制化的场景。你可以实现反向代理、负载均衡、动态路由、限流、身份验证等功能,但需要注意开发成本和性能瓶颈。如果可能,建议将 Nginx 作为前置网关,Tornado 作为应用网关,结合两者的优势,构建高性能、高可用的系统。

看看性能是不是ok:
在这里插入图片描述

在这里插入图片描述

所以,总体上tornado在性能上可能会比nginx低一个量级:

  • 1 简单的基础服务可以继续走nginx,或者直连,这部分假设无问题。
  • 2 复杂的、核心的服务走smartlink。这部分的处理本身就非常“昂贵”,比如用大模型处理数据,天然的TPS就比较低,smartlink额外的开销比起来不算啥,是可行的(或者说现在的计算资源太多了,费点没啥)。即使是较低配的生产机也应该有8个核,花1个核做网关在我看来是值得的。

smartlink 可以带来什么:

  • 1 权限控制。过去我一般不去设置权限,这样开发和使用比较方便,但这一步肯定是要做的。通过smartlink,仅开放一个对外端口,访问其他服务时必须提供对应口令,在smartlink完成鉴权。
  • 2 流量及质量。现在有一类服务要求比较高,按照固定周期统计可能会有些滞后。通过smartlink(结合redis), 可以实时的对流量进行控制,获取请求的响应头,将成功(2xx)、失败(5xx)等不同类型的错误进行实时统计和通知。另外可以统计实时的影响速度,由别的算法应用读取,来进行分发优化。
  • 3 优化与强化。这个问题是最为核心且重要的,当我们花费成千上万的人民币在进行数据的处理时,我们知道做的不够好。通常来说,算法很难在第一版达到完美。然而当服务进入生产状态时,我们又很难去停下来再次改进;即使我们离线改好了新版算法,又担心上线时出bug。这样的最终结果是:不出问题不改进。smartlink在增加cpu开销时,也给了足够强大的控制逻辑,可以解决这些问题。 这里不讨论细节,只看机制上的可行性。当请求到达时,smarklink会按照实时加载的策略(通过redis)决定请求是否可以多发。比如除了将请求实时转向对应的稳定版服务,也发到kafka。收到请求的处理结果后,除了返回用户,也发一份到kafka。这个过程会增加2次写kafka的操作,对于秒级级的请求来说是可以接受的(假设请求30秒超时)。数据到了kafka之后,可以有多个消费者准实时的执行新版本服务的请求,然后和当前服务的结果一并进行效果评估与比对。首先会排除的问题是bug引起的请求失败,然后新版本服务可以准实时的进行评估、打标(RLHF)。评估结束后,可以采用手动/自动的方法,修改redis中的数据,从而使请求平滑切换到新的服务。这个服务是经过了效果评估和上线测试的,不会有低级错误。

内容

本次的目标先实现几个基本功能

功能:

  • 1 转发
  • 2 health-check
  • 3 负载均衡

1 测试样例

  • 1 转发

在一台主机上,启动一个微服务(实体识别),通过smartlink转发服务到此位置

  • 2 health-check

当请求报连接错误时,smartlink会将对应服务记为不可用;当服务恢复时,会将其标记为可用。

  • 3 负载均衡(least time)

再启动一个服务,加入并在服务中进行时间扰动。要求smartlink在将服务转发时会依据其响应时间动态分配。

2 实验

我发现今天可能写不完全部了,内容有点多,我先把完成的有部分整理上。

2.1 基础配置部分 base_config.py

这里先手动配置了一个测试服务。假设每个服务的可用资源是一个字典, 并且认为一定有一个默认的服务版本(base)

...
base_config.server_dict = {}
base_config.server_dict['test_server'] = {}
base_config.server_dict['test_server']['base'] = "http://IP:PORT/get_lng_lat/" 

2.2 数据模型 data_model.py

约定(建议性质)了模型的输入和输出。本来是想强制的,但那样难度太高了,而且作为一个网关,目前的主要任务还是能够进行有效转发。未来可以尽量往这个标准靠。

# 服务输入
class StandardInput(BaseModel):server_name : str  # 要请求的服务名params : dict = {} #  请求参数data : list = []# 请求数据 - 一般以lod的方式输入# 服务输出
class StandardOutput(BaseModel):server_name: str = 'default'status : bool  = Truemsg : str  = 'ok'data : list = [] # 返回数据 - 以lod的方式返回duration : int = 0 # ms 

2.3 服务 server.py

2.3.1 基本部分导入部分

import tornado.httpserver  # http服务器
import tornado.ioloop  # ?
import tornado.options  # 指定服务端口和路径解析
import tornado.web  # web模块
from tornado.options import define, options
import os.path  # 获取和生成template文件路径
import tornado.httpclient  
from Basefuncs import * 
from base_config import base_config
from data_model import * 
# 配置日志
logger = get_base_logger()import json
from json import JSONEncoder
class MyEncoder(JSONEncoder):def default(self, obj):if isinstance(obj, np.integer):return int(obj)elif isinstance(obj, np.floating):return float(obj)elif isinstance(obj, np.ndarray):return obj.tolist()if isinstance(obj, datetime):return obj.__str__()if isinstance(obj, dd.timedelta):return obj.__str__()else:return super(MyEncoder, self).default(obj)

2.3.2 基础转发

# 基础转发处理器
class BaseForwardHandler(tornado.web.RequestHandler):def set_default_headers(self):self.set_header("Access-Control-Allow-Origin", "*")self.set_header("Access-Control-Allow-Headers", "Content-Type")self.set_header("Access-Control-Allow-Methods", "POST, OPTIONS")def options(self):self.set_status(204)self.finish()# 被转发的请求async def forward_request(self, target_url, body=None, headers=None):# 获取原始请求的 body 和 headers# 如果没有传递 body 和 headers,则使用原始请求的 body 和 headersif body is None:body = self.request.bodyif headers is None:headers = self.request.headers# 使用 Tornado 的异步 HTTP 客户端转发请求http_client = tornado.httpclient.AsyncHTTPClient()try:logger.info(f"Forwarding request to {target_url}")response = await http_client.fetch(target_url,method="POST",headers=headers,body=body)self.write(response.body)except tornado.httpclient.HTTPError as e:logger.error(f"HTTP Error: {e.code} - {str(e)}")self.set_status(e.code)self.write(json.dumps({"error": str(e)}))# 触发告警通知await self.trigger_alert(e)except Exception as e:logger.error(f"Unexpected error: {str(e)}")self.set_status(500)self.write(json.dumps({"error": "Internal Server Error"}))# 触发告警通知await self.trigger_alert(e)async def trigger_alert(self, error):"""触发告警通知的逻辑"""alert_message = f"Service Error: {str(error)}"logger.error(f"Sending alert: {alert_message}")# 示例:发送告警到内部系统(如邮件、Slack、Webhook 等)try:# 假设我们有一个发送告警的函数await self.send_alert_to_internal_system(alert_message)except Exception as e:logger.error(f"Failed to send alert: {str(e)}")async def send_alert_to_internal_system(self, message):"""发送告警到内部系统的逻辑"""# 示例:使用 HTTP 客户端发送告警到 Webhookhttp_client = tornado.httpclient.AsyncHTTPClient()alert_url = "http://internal-alert-system/endpoint"body = json.dumps({"message": message})try:await http_client.fetch(alert_url,method="POST",headers={"Content-Type": "application/json"},body=body)logger.info("Alert sent successfully")except Exception as e:logger.error(f"Failed to send alert: {str(e)}")raise e

2.3.3 应用的转发逻辑

import time 
class AIServer(BaseForwardHandler):print('AIServer Working ', get_time_str1())async def post(self):standard_output = StandardOutput()print('解析请求体')# 1. 解析请求体try:request_data = json.loads(self.request.body)print("Parsed request data:", request_data)except json.JSONDecodeError:self.set_status(400)standard_output.status = False standard_output.msg  = "Invalid JSON format"self.write(json.dumps(standard_output.dict()))return# 2. 验证请求格式try:standard_input = StandardInput(**request_data)except (TypeError, ValueError) as e:# 如果 request_data 不符合 StandardInput 的要求,捕获 TypeError 或 ValueErrorself.set_status(400)standard_output.status = False standard_output.msg  = f"Invalid input data: {str(e)}"self.write(json.dumps(standard_output.dict()))return# 3.转发请求target_server_dict =  base_config.server_dict.get(standard_input.server_name)if target_server_dict is None:self.set_status(400)standard_output.status = False standard_output.msg  = f"Invalid input data: No Such Service {standard_input.server_name}"self.write(json.dumps(standard_output.dict()))return# 这里控制版本await self.forward_request(target_server_dict['base'])

然后进行调用

请求端:

import httpx
data_dict =   {'server_name':'test_server', 'address': '上海九六广场'}
resp = httpx.post('http://localhost:9001/ai_server/' ,json = data_dict)
In [31]: resp.json()
Out[31]:
{'name': 'get_lng_lat','status': True,'msg': 'ok','duration': 86,'data': {'status': 0,'lng': 121.5312514401146,'lat': 31.23340608690243,'precise': 1,'confidence': 75,'comprehension': 100,'level': '购物'}}

服务端:

...
解析请求体
Parsed request data: {'server_name': 'test_server', 'address': '上海九六广场'}
2025-02-02 01:09:04 - my_logger - INFO - Forwarding request to http://IP/get_lng_lat/
2025-02-02 01:09:04 - tornado.access - INFO - 200 POST /ai_server/ (127.0.0.1) 158.67ms
...

可以看到转发成功了,原始的请求大约80ms,因为转发带来的额外延时大约也是80ms。所以如果对于实时性要求特别高的可能还需要注意。后续再加上其他的额外处理,单个请求最终的延时可能到达200ms,甚至500ms。对于类似大模型之类的调用来说,一般会花费数秒到数十秒来处理一个请求,这种开销就可以接受。

相关文章:

【最后203篇系列】004 -Smarklink

说明 这个用来替代nginx。 最初是希望用nginx进行故障检测和负载均衡,花了很多时间,大致的结论是:nginx可以实现,但是是在商业版里。非得要找替代肯定可以搞出来,但是太麻烦了(即使是nginx本身的配置也很烦…...

二分法模板

数组具有二段性,可以分为左右两边合法区和不合法区 如果选择左端点,右边区域不合法,选择 left mid ,right mid - 1; 如果选择右端点,左边区域不合法,选择 left mid 1 ,right mid ; 1.x 的平方根 LCR 072. x 的…...

基于SpringBoot的智慧康老疗养院管理系统的设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...

LabVIEW无人机航线控制系统

介绍了一种无人机航线控制系统,该系统利用LabVIEW软件与MPU6050九轴传感器相结合,实现无人机飞行高度、速度、俯仰角和滚动角的实时监控。系统通过虚拟仪器技术,有效实现了数据的采集、处理及回放,极大提高了无人机航线的控制精度…...

STM32CUBEIDE编译的hex使用flymcu下载后不能运行

测试后确认,不论是1.10版本还是1.16版本,编译生成的hex下载后不能运行,需要更改boot 设置才能开始运行,flymcu下载后已经告知一切正常,跳转到8000 0000处开始运行,实际没有反应,而使用mdk编译生…...

final-关键字

一、final修饰的类不能被继承 当final修饰一个类时,表明这个类不能被其他类继承。例如,在 Java 中,String类就是被final修饰的,这保证了String类的不可变性和安全性,防止其他类通过继承来改变String类的行为。 final…...

在RHEL 8.10上安装开源工业物联网解决方案Thingsboard 3.9

在RHEL/CentOS/Rocky/AlmaLinux/Oracle Linux 8单节点上安装 备注: 适用于单节点 是否支持欧拉??? 前提条件 本指南描述了如何在RHEL/CentOS 7/8上安装ThingsBoard。硬件要求取决于所选的数据库和连接到系统的设备数量。要在单…...

deepseek+vscode自动化测试脚本生成

近几日Deepseek大火,我这里也尝试了一下,确实很强。而目前vscode的AI toolkit插件也已经集成了deepseek R1,这里就介绍下在vscode中利用deepseek帮助我们完成自动化测试脚本的实践分享 安装AI ToolKit并启用Deepseek 微软官方提供了一个针对AI辅助的插件,也就是 AI Toolk…...

k8s支持自定义field-selector spec.hostNetwork过滤

好久没写博客啦,年前写一个博客就算混过去啦😂 写一个小功能,对于 Pod,在没有 label 的情况下,支持 --field-selector spec.hostNetwork 查询 Pod 是否为 hostNetwork 类型,只为了熟悉 APIServer 是如何构…...

图像噪声处理技术:让图像更清晰的艺术

在这个数字化时代,图像作为信息传递的重要载体,其质量直接影响着我们的视觉体验和信息解读。然而,在图像采集、传输或处理过程中,难免会遇到各种噪声干扰,如高斯噪声、椒盐噪声等,这些噪声会降低图像的清晰…...

w186格障碍诊断系统spring boot设计与实现

🙊作者简介:多年一线开发工作经验,原创团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹赠送计算机毕业设计600个选题excel文…...

【自学笔记】Java的重点知识点-持续更新

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Java知识点概览一、Java简介二、Java基本语法三、面向对象编程(OOP)四、异常处理五、常用类库六、多线程编程七、网络编程 注意事项 总结 Ja…...

031.关于后续更新和指纹浏览器成品

关于后续更新 后续决定不再更新了,我低估了各种检测站的更新速度,我开源的一些源码修改方法,已经被个别检测网站加入了针对性检测。只要开源了,一段时间后就会有针对性反检测。这种东西根本就不能开源,开源了大家就一…...

013-51单片机红外遥控器模拟控制空调,自动制冷制热定时开关

主要功能是通过红外遥控器模拟控制空调,可以实现根据环境温度制冷和制热,能够通过遥控器设定温度,可以定时开关空调。 1.硬件介绍 硬件是我自己设计的一个通用的51单片机开发平台,可以根据需要自行焊接模块,这是用立创…...

UE5 蓝图学习计划 - Day 10:UI 系统(HUD 与 Widget)

在游戏开发中,UI(用户界面) 是玩家获取游戏信息、与游戏进行交互的重要部分。Unreal Engine 5 提供了 HUD(Head-Up Display) 和 Widget Blueprint(小部件蓝图) 来帮助开发者创建 血量条、得分系…...

QT简单实现验证码(字符)

0) 运行结果 1) 生成随机字符串 Qt主要通过QRandomGenerator类来生成随机数。在此之前的版本中,qrand()函数也常被使用,但从Qt 5.10起,推荐使用更现代化的QRandomGenerator类。 在头文件添加void generateRandomNumb…...

代码随想录刷题笔记

数组 二分查找 ● 704.二分查找 tips:两种方法,左闭右开和左闭右闭,要注意区间不变性,在判断mid的值时要看mid当前是否使用过 ● 35.搜索插入位置 ● 34.在排序数组中查找元素的第一个和最后一个位置 tips:寻找左右边…...

VSCode 中的 Git Graph扩展使用详解

VSCode 中的 Git Graph 详解 1. 什么是 Git Graph? Git Graph 是 VSCode 中的一款 Git 可视化扩展,它提供了一种 图形化方式 来查看 Git 提交历史、分支、合并记录等信息,使得 Git 版本管理更加直观和高效。 通过 Git Graph,你…...

Day07:缓存-数据淘汰策略

Redis的数据淘汰策略有哪些 ? (key过期导致的) 在redis中提供了两种数据过期删除策略 第一种是惰性删除,在设置该key过期时间后,我们不去管它,当需要该key时,我们再检查其是否过期,如果过期&…...

【自学嵌入式(8)天气时钟:天气模块开发、主函数编写】

天气时钟:天气模块开发、主函数编写 I2C协议和SPI协议I2C(Inter-Integrated Circuit)SPI(Serial Peripheral Interface) 天气模块心知天气预报使用HTTPClient类介绍主要功能常用函数注意事项 JSON介绍deserializeJson函…...

简单的SQL语句的快速复习

语法的执行顺序 select 4 字段列表 from 1 表名列表 where 2 条件列表 group by 3 分组前过滤 having 分组后过滤 order by 5 排序字段列表 limit 6 分页参数 聚合函数 count 统计数量 max 最大值 min 最小值 avg 平均 sum 总和 分组查询使…...

跟李沐学AI:视频生成类论文精读(Movie Gen、HunyuanVideo)

Movie Gen:A Cast of Media Foundation Models 简介 Movie Gen是Meta公司提出的一系列内容生成模型,包含了 3.2.1 预训练数据 Movie Gen采用大约 100M 的视频-文本对和 1B 的图片-文本对进行预训练。 图片-文本对的预训练流程与Meta提出的 Emu: Enh…...

Rust 所有权特性详解

Rust 所有权特性详解 Rust 的所有权系统是其内存安全的核心机制之一。通过所有权规则,Rust 在编译时避免了常见的内存错误(如空指针、数据竞争等)。本文将从堆内存与栈内存、所有权规则、变量作用域、String 类型、内存分配、所有权移动、Cl…...

基于人脸识别的课堂考勤系统

该项目是一个基于人脸识别的课堂考勤系统,使用Python开发,结合了多种技术实现考勤功能。要开发类似的基于人脸识别的考勤系统,可参考以下步骤: 环境搭建:利用Anaconda创建虚拟环境,指定Python版本为3.8&am…...

Deepseek R1 本地化部署指南:跨平台实战

引言 Deepseek R1 作为一款强大的本地化人工智能工具,支持在多种操作系统上部署,满足开发者和企业私有化运行的需求。本文将手把手教你如何在 Windows、Linux 和 macOS 系统上完成 Deepseek R1 的本地化部署,并附赠常见问题解决技巧! © ivwdcwso (ID: u012172506) 1…...

Nginx 运维开发高频面试题详解

一、基础核心问题 原文链接:https://blog.csdn.net/weixin_51146329/article/details/142963853 1、什么是Nginx? Nginx 是一个高性能的 HTTP 和反向代理服务器,它以轻量级和高并发处理能力而闻名。Nginx 的反向代理功能允许它作为前端服务…...

JVM运行时数据区域-附面试题

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域 有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是 依赖用户线程的启动和结束而建立和销毁。 1. 程序计…...

DeepSeek本地部署详细指南

DeepSeek本地部署详细指南 随着人工智能技术的飞速发展,本地部署大模型的需求也日益增加。DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私。以下是…...

Debian 10 中 Linux 4.19 内核在 x86_64 架构上对中断嵌套的支持情况

一、中断嵌套的定义与原理 中断嵌套是指在一个中断处理程序(ISR)正在执行的过程中,另一个更高优先级的中断请求到来,系统暂停当前中断处理程序,转而处理新的高优先级中断。处理完高优先级中断后,系统返回到原来的中断处理程序继续执行。这种机制允许系统更高效地响应紧急…...

C语言:深入了解指针1

内存和地址 1. 酒店房间类比内存和地址 场景描述 把计算机的内存想象成一家酒店,每个房间就是一个内存单元,每个房间都有一个唯一的房间号,这个房间号就相当于内存地址。房间里可以存放客人的行李等物品,这些物品就好比存储在内…...

【AI】探索自然语言处理(NLP):从基础到前沿技术及代码实践

Hi ! 云边有个稻草人-CSDN博客 必须有为成功付出代价的决心,然后想办法付出这个代价。 目录 引言 1. 什么是自然语言处理(NLP)? 2. NLP的基础技术 2.1 词袋模型(Bag-of-Words,BoW&#xff…...

游戏引擎 Unity - Unity 下载与安装

Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…...

文本复制兼容方案最佳实现落地。

文章目录 一、navigator.clipboard.writeText二、方案落地总结 一、navigator.clipboard.writeText navigator.clipboard.writeText 是一个Web API,它允许网页脚本将文本数据写入用户的系统剪贴板。这个API是异步的,并且设计用于提高安全性和用户体验&a…...

LabVIEW如何高频采集温度数据?

在LabVIEW中进行高频温度数据采集时,选择合适的传感器(如热电偶或热电阻)和采集硬件是关键。下面是一些建议,帮助实现高效的温度数据采集: 1. 传感器选择: 热电偶(Thermocouple)&am…...

AI智慧社区--人脸识别

前端 人脸的采集按钮&#xff1a; 首先对于选中未认证的居民记录&#xff0c;进行人脸采集 前端的按钮 <el-form-item><el-button v-has"sys:person:info" type"info" icon"el-icon-camera" :disabled"ids.length < 0" …...

C++11—右值引用

目录 简介 左值和右值 左值 右值 右值引用 生命周期 引用折叠 实际应用 移动语义 移动构造函数 移动赋值运算符 完美转发 简介 之前我们曾学习过引用叫左值引用&#xff0c;但那是C98的&#xff0c;在C11中新增了一种引用叫右值引用。右值引用主要用于支持移动语…...

Workbench 中的热源仿真

探索使用自定义工具对移动热源进行建模及其在不同行业中的应用。 了解热源动力学 对移动热源进行建模为各种工业过程和应用提供了有价值的见解。激光加热和材料加工使用许多激光束来加热、焊接或切割材料。尽管在某些情况下&#xff0c;热源 &#xff08;q&#xff09; 不是通…...

Windows11 不依赖docker搭建 deepseek-R1 1.5B版本(附 Open WebUi搭建方式)

零、前言 过年这几天发现 DeepSeek 非常火&#xff0c;试用了一下发现确实不错。与豆包、kimi、perplexity 这些相比完全不是一个次元的存在&#xff0c;特别是用ta写文章的时候体验非常好。所以试着自己搭一个环境。 一、安装 Ollama和DeepSeek-R1 我的安装方式很简单&#xf…...

Error: Expected a mutable image

你的函数用了不支持的图片格式比如我的人脸检测&#xff0c;本来要RGB565我却用JPEG所以报错...

【4Day创客实践入门教程】Day2 探秘微控制器——单片机与MicroPython初步

Day2 探秘微控制器——单片机与MicroPython初步 目录 Day2 探秘微控制器——单片机与MicroPython初步MicroPython语言基础开始基础语法注释与输出变量模块与函数 单片机基础后记 Day0 创想启程——课程与项目预览Day1 工具箱构建——开发环境的构建Day2 探秘微控制器——单片机…...

代码随想录算法训练营Day51 | 101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿

文章目录 101.孤岛的总面积思路与重点 102.沉没孤岛思路与重点 103.水流问题思路与重点 104.建造最大岛屿思路与重点 101.孤岛的总面积 题目链接&#xff1a;101.孤岛的总面积讲解链接&#xff1a;代码随想录状态&#xff1a;直接看题解了。 思路与重点 nextx或者nexty越界了…...

网络基础

协议 协议就是约定 网络协议是协议中的一种 协议分层 协议本身也是软件&#xff0c;在设计上为了更好的模块化&#xff0c;解耦合&#xff0c;也是设计成为层状结构的 两个视角&#xff1a; 小白&#xff1a;同层协议&#xff0c;直接通信 工程师&#xff1a;同层协议&…...

利用Spring Batch简化企业级批处理应用开发

1. 引言 1.1 批处理的重要性 在现代企业系统中,批处理任务用于处理大量数据,如报表生成、数据迁移、日终结算等。这些任务通常不需要实时响应,但需要高效、可靠地完成。批处理可以显著提高系统性能,减少实时系统的负载,并确保数据的完整性和一致性。 1.2 Spring Batch简…...

Python - pyautogui库 模拟鼠标和键盘执行GUI任务

安装库&#xff1a; pip install pyautogui 导入库&#xff1a;import pyautogui 获取屏幕尺寸&#xff1a; s_width, s_height pyautogui.size() 获取鼠标当前位置&#xff1a; x, y pyautogui.position() 移动鼠标到指定位置&#xff08;可以先使用用上一个函数调试获取当…...

UE求职Demo开发日志#19 给物品找图标,实现装备增加属性,背包栏UI显示装备

1 将用到的图标找好&#xff0c;放一起 DataTable里对应好图标 测试一下能正确获取&#xff1a; 2 装备增强属性思路 给FMyItemInfo添加一个枚举变量记录类型&#xff08;物品&#xff0c;道具&#xff0c;装备&#xff0c;饰品&#xff0c;武器&#xff09;--> 扩展DataT…...

【PyQt】lambda函数,实现动态传递参数

为什么需要 lambda&#xff1f; 在 PyQt5 中&#xff0c;clicked 信号默认会传递一个布尔值&#xff08;表示按钮是否被选中&#xff09;。如果我们希望将按钮的文本内容传递给槽函数&#xff0c;需要通过 lambda 函数显式传递参数。 这样可以实现将按钮内容传递给槽函数&…...

Unity 2D实战小游戏开发跳跳鸟 - 跳跳鸟碰撞障碍物逻辑

在有了之前创建的可移动障碍物之后,就可以开始进行跳跳鸟碰撞到障碍物后死亡的逻辑,死亡后会产生一个对应的效果。 跳跳鸟碰撞逻辑 创建Obstacle Tag 首先跳跳鸟在碰撞到障碍物时,我们需要判定碰撞到的是障碍物,可以给障碍物的Prefab预制体添加一个Tag为Obstacle,添加步…...

LeetCode:121.买卖股票的最佳时机1

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;121.买卖股票的最佳时机1 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票…...

DeepSeek-R1 论文. Reinforcement Learning 通过强化学习激励大型语言模型的推理能力

论文链接&#xff1a; [2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 实在太长&#xff0c;自行扔到 Model 里&#xff0c;去翻译去提问吧。 工作原理&#xff1a; 主要技术&#xff0c;就是训练出一些专有用途小模型&…...

SQL索引优化_提高系统响应速度的秘诀

1. 引言 1.1 索引的重要性 在数据库管理系统中,索引是提升查询性能的关键工具。合理的索引设计可以显著减少查询时间,提高系统的响应速度,从而改善用户体验。然而,不恰当的索引使用可能会适得其反,增加写操作的开销并导致性能下降。 1.2 文章目标与结构 本文旨在介绍如…...