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

python botos s3 aws

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html

AWS是亚马逊的云服务,其提供了非常丰富的套件,以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK(boto3)的使用进行介绍。

关键词:AWS,S3,Python,boto3,endpoint,client

背景

AWS是一整套亚马逊云服务套件(云存储及其上的基础设施和服务),包括云存储(主要是对象存储)、微服务、数据库等,其中S3对象存储受到众多国内开发者的欢迎。AWS提供了包括console、client、sdk等多种方式进行连接使用,并支持包括python在内的许多语言。为了便捷地在Python程序内使用S3对象存储,我们考虑两种途径:

  • 在子进程中召唤aws client命令行程序;
  • 在python中调用boto3模块的api调用服务

其中boto3途径由于和python语言(和其他语言)有较好的适配,因此更适合开发者使用。此外,处于安全考虑,开发者可能只能获得AWS的有限访问权限,比如endpoint,这使得aws官方教程中的一些范例不可用。比如,访问对象存储至少存在三种方式:Resource、Session、Client,而借助endpoint我们只能访问client,这限制了开发者权限、无法使用高级功能的同时,也提高了数据操作的安全性。

本文将针对如何调用boto3和endpoint来实现aws S3服务的功能进行介绍。

相关信息

在正式介绍之前,有必要对aws及boto3的相关组件和功能进行介绍。

从AWS到S3

从AWS到其中的S3服务的关系链可以简单地描述为:AWS -> VPC -> S3 -> Endppoint -> EC2

意思是AWS到私有云(VPC)到S3存储到EC2服务实例,Endpoint则是S3到EC2的桥梁。如下图所示:

“Amazon Virtual Private Cloud (Amazon VPC),简单理解,就是在云上建个大楼,大楼里面的网络、门禁,安检等都一应俱全,我们根据需要在大楼里选择房间(创建ec2)办公,这个房间自己也有相应的门禁系统”

参考:https://www.bioaws.com/blogs/2020-02-02-vpc-endpoint-s3/

AWS的命令行client

aws提供了一个便捷的命令行程序以供使用,其需要先去官网下载一个zip安装包,然后解压安装即可:

安装aws cli:How to Install AWS CLI on Ubuntu 20.04

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

配置awscli

aws configure
# 输入access key和security key:后两项可以忽略(假如只需要使用S3的话)

连接S3存储桶

# view folder
aws [option] --endpoint-url [endpoint_url] s3 [action] s3://[bucket]
# download single file
aws [option] --endpoint-url [endpoint_url] s3 cp s3://[bucket]/[file_path] [local_path]
# download folder
aws [option] --endpoint-url [endpoint_url] s3 sync s3://[bucket]/[folder_path] [local_path]

参考:通过 AWS CLI 使用高级别 (s3) 命令

boto3: python sdk

SimpleQueueService(SQS)
Amazon Simple Queue Service (Amazon SQS) 是一种完全托管的消息队列服务,可以轻松解耦和扩展微服务、分布式系统和无服务器应用程序。 Amazon SQS 在分布式应用程序组件之间移动数据并帮助您解耦这些组件。

import boto3'''send messages'''
# Get the service resource
sqs = boto3.resource('sqs')
# Get the queue
queue = sqs.get_queue_by_name(QueueName='test')
# Create a new message
response = queue.send_message(MessageBody='world')
# The response is NOT a resource, but gives you a message ID and MD5
print(response.get('MessageId'))
print(response.get('MD5OfMessageBody'))'''process messages'''
# Process messages by printing out body and optional author name
for message in queue.receive_messages(MessageAttributeNames=['Author']):# Get the custom author message attribute if it was setauthor_text = ''if message.message_attributes is not None:author_name = message.message_attributes.get('Author').get('StringValue')if author_name:author_text = ' ({0})'.format(author_name)# Print out the body and author (if set)print('Hello, {0}!{1}'.format(message.body, author_text))# Let the queue know that the message is processedmessage.delete()

Resource

资源表示 Amazon Web Services (AWS) 的面向对象的接口。 它们提供了比服务客户端进行的原始低级调用更高级别的抽象。

每个资源实例都有许多属性和方法。 这些在概念上可以分为标识符、属性、操作、引用、子资源和集合。资源本身也可以在概念上分为服务资源(如 sqs、s3、ec2 等)和单个资源(如 sqs.Queue 或 s3.Bucket)。 服务资源没有标识符或属性。 否则,两者共享相同的组件。

# Get resources from the default session
sqs = boto3.resource('sqs')
s3 = boto3.resource('s3')'''example'''
# S3 Object (bucket_name and key are identifiers)
obj = s3.Object(bucket_name='boto3', key='test.py')
print(obj.bucket_name)print(obj.key)# S3 Object attributes
obj.last_modifie
dobj.e_tag# S3 Object actions
obj = s3.Object(bucket_name='boto3', key='test.py')
response = obj.get()
data = response['Body'].read()# S3 sub-resources
obj = bucket.Object(key='new_file.txt')
print(obj.bucket_name)
print(obj.key)# S3: Wait for a bucket to exist.
bucket.wait_until_exists()

资源实例不是线程安全的,不应跨线程或进程共享。 这些特殊类包含无法共享的附加元数据。 建议在多线程或多处理中为每个线程或进程创建一个新资源。

Collections

集合为一组资源提供了一个可迭代的接口。

Session

会话管理有关特定配置的状态。 会话通常存储以下内容:

  • 证书
  • AWS 区域
  • 与您的个人资料相关的其他配置
'''Using the default session'''
sqs = boto3.client('sqs')
s3 = boto3.resource('s3')'''Create your own session'''
my_session = boto3.session.Session()
# Now we can create low-level clients or resource clients from our custom session
sqs = my_session.client('sqs')
s3 = my_session.resource('s3')

与 Resource 对象类似,Session 对象不是线程安全的,不应在线程和进程之间共享。 建议在多线程或多处理中为每个线程或进程创建一个新的 Session 对象。

Client

客户端为 AWS 提供了一个低级接口,其方法与服务 API 的映射接近 1:1。 所有服务操作均由客户端支持。

import boto3
sqs = boto3.client('sqs')# It is also possible to access the low-level client from an existing resource:
# Create the resource
sqs_resource = boto3.resource('sqs')
# Get the client from the resource
sqs = sqs_resource.meta.client# send messages
response = sqs.send_message(QueueUrl='...', MessageBody='...')
# handling messages
response = sqs.list_queues()
for url in response.get('QueueUrls', []):print(url)
# waiters
sqs.waiter_names

多处理:虽然客户端是线程安全的,但由于它们的网络实现,它们不能跨进程共享。 这样做可能会导致调用服务时响应顺序不正确。

共享元数据:客户端通过一些属性(即元、异常和服务员名称)向最终用户公开元数据。 这些是可以安全阅读的,但任何突变都不应该被认为是线程安全的

自定义 Botocore 事件:Botocore(构建 Boto3 库)允许高级用户提供他们自己的自定义事件挂钩,这些挂钩可以与 boto3 的客户端交互。 大多数用户不需要使用这些接口,但是那些不需要仔细审查的用户不应再考虑他们的客户端线程安全。

参考:Botocore Events - botocore 1.27.25 documentation

import boto3.session
from concurrent.futures import ThreadPoolExecutordef do_s3_task(client, task_definition):# Put your thread-safe code heredef my_workflow():# Create a session and use it to make our clientsession = boto3.session.Session()s3_client = session.client('s3')# Define some work to be done, this can be anythingmy_tasks = [ ... ]# Dispatch work tasks with our s3_clientwith ThreadPoolExecutor(max_workers=8) as executor:futures = [executor.submit(do_s3_task, s3_client, task) for task in my_tasks]

Endpoint (AWS PrivateLink for S3)

在将 S3 客户端配置为使用接口 VPC 终端节点时,请务必注意,只有终端节点中指定的资源类型才能使用该客户端进行寻址( only the resource type specified in the endpoint can be addressed)。 访问存储桶和访问点需要实例化两个客户端,每个资源类型一个。

import boto3
s3_client = boto3.client(service_name='s3',endpoint_url='https://bucket.vpce-abc123-abcdefgh.s3.us-east-1.vpce.amazonaws.com')

Paginators

一些 AWS 操作返回的结果不完整,需要后续请求才能获得整个结果集。 发送后续请求以在前一个请求中断的地方继续的过程称为分页。

Error handling

Boto3 提供了许多功能来帮助导航您在与 AWS 服务交互时可能遇到的错误和异常。

1. 确定要捕获的异常

  • Botocore 异常
  • AWS 服务异常:AWS 服务异常被底层的 botocore 异常 ClientError 捕获。有关您正在使用的服务的错误响应的完整列表,请参阅各个服务的 AWS 文档。

2. 使用低级客户端时捕获异常

3. 解析错误响应并从 AWS 服务中捕获异常

4. 从错误响应中辨别有用信息

try:client.some_api_call(SomeParam='some_param')except botocore.exceptions.ClientError as error:# Put your error handling logic hereraise errorexcept botocore.exceptions.ParamValidationError as error:raise ValueError('The parameters you provided are incorrect: {}'.format(error))'''Error message structure
{'Error': {'Code': 'SomeServiceException','Message': 'Details/context around the exception or error'},'ResponseMetadata': {'RequestId': '1234567890ABCDEF','HostId': 'host ID data will appear here as a hash','HTTPStatusCode': 400,'HTTPHeaders': {'header metadata key/values will appear here'},'RetryAttempts': 0}
}except botocore.exceptions.ClientError as err:if err.response['Error']['Code'] == 'InternalError': # Generic errorprint('Error Message: {}'.format(err.response['Error']['Message']))
'''

使用boto3操作S3

准备工作

考虑以下问题:

1. 你有什么访问权限? 在使用low-level client处理存储桶时,必须使用具有访问 ID/密钥的端点(Endpoint with access id / key)。 如果您想在 AWS 中尝试其他高级服务,请检查您的授权。 所拥有的 AWS 权限决定使用什么链接方式

2. 您处理的文件的大小。 请参考file-size limitation和File transfer configuration。 操作文件的大小

  • 本地-> AWS:多部分
  • AWS -> 本地:分页器

3.错误处理策略。 异常处理

  • 单文件进程中断:同名再次上传并重写
  • 文件夹进程中断:检查数据库,上传和重写
  • 重复处理:检查数据库,上传和重写
  • 线程安全:创建单个客户端来处理所有文件

4. 快速api参考。 API查询

  • S3 — Boto3 Docs 1.24.24 文档
  • 代码样例:Amazon S3 examples
  • 会话参考 ‒ Boto3 Docs 1.24.24 文档

查询/上传/下载/删除 操作step-by-step

本节介绍了如何利用endpoint连接存储并操作。

  1. Configure aws
aws configure
# -> input aws_access_key_id & aws_secret_access_key

然后你会在 ~/.aws/credentials 找到你的配置文件。也可以忽略这一步,在python程序中设置。

2. Create an s3 client & explore buckects(查询)

s3_client = boto3.client(service_name='s3', endpoint_url=aws_s3_endpoint_url)
response = s3_client.list_buckets()
buckets = [bucket['Name'] for bucket in response['Buckets']]
print(buckets)

3. Upload files(上传,覆盖写)

s3默认采用覆盖写模式,如果希望避免这一问题,可以认为设置version属性进行控制。

response = s3_client.upload_file(local_file_path, bucket_name, target_path_in_bucket)

4. Upload large files(上传大文件)

在上传、下载或复制文件或 S3 对象时,适用于 Python 的 AWS 开发工具包会自动管理重试以及multipart 和非multipart 传输。 通过使用非常适合大多数场景的合理默认设置来执行管理操作。 为了处理特殊情况,可以配置默认设置以满足要求。

# using simple upload
self.client.upload_file(local_file_path, bucket_name, target_path_in_bucket)# using multi-part upload to extend size limitation
GB = 1024 ** 3
config = TransferConfig(multipart_threshold=5*GB)
self.client.upload_file(local_file_path, bucket_name, target_path_in_bucket, Config=config)

速度对比:

Test fileDefault uploadSpecified multi-part upload
2GB221MB/s150~212MB/s
13GB232MB/s224~240MB/s

总体而言,自行配置的速度不一定比默认自适应的速度高,而高也高不到哪里去。

5. Download files(下载)

# download single file
self.client.download_file(bucket_name, target_path_in_bucket, local_file_path)# download single file as object
with open('FILE_NAME', 'wb') as f: # binary mode onlys3.download_fileobj('BUCKET_NAME', 'OBJECT_NAME', f)# download folder
list_objects_v2() -> download_file()

6. Delete files in buckets(删除)

self.client.delete_object(Bucket=bucket_name, Key=target_path_in_bucket)

7. Using Calback as ProgressBar(监控进度条)

使用进度条来监控操作状态。

示例来自 Uploading files ‒ Boto3 Docs 1.24.25 documentation 和 How can I increase my AWS s3 upload speed when using boto3?

方法一:官方示例,速度程序运行降速80%!

import threadingclass ProgressPercentage(object):def __init__(self, filename):self._filename = filenameself._size = float(os.path.getsize(filename))self._seen_so_far = 0self._lock = threading.Lock()def __call__(self, bytes_amount):# To simplify, assume this is hooked up to a single filenamewith self._lock:self._seen_so_far += bytes_amountpercentage = (self._seen_so_far / self._size) * 100sys.stdout.write("\r%s  %s / %s  (%.2f%%)" % (self._filename, self._seen_so_far, self._size,percentage))sys.stdout.flush()s3.upload_file('FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME',Callback=ProgressPercentage('FILE_NAME'))

方法二:民间示例,程序运行降速10%

from tqdm import tqdm
import boto3.s3.transfer as s3transferclass Tool():def __init__():passdef client_upload_files(self, bucket, local_path, aws_path, progress_func):transfer_config = s3transfer.TransferConfig(use_threads=True,max_concurrency=10,)s3t = s3transfer.create_transfer_manager(self.client, transfer_config)s3t.upload(local_path, bucket, aws_path, subscribers=[s3transfer.ProgressCallbackInvoker(progress_func),])s3t.shutdown()with tqdm(desc='upload', ncols=60,total=totalsize, unit='B', unit_scale=1) as pbar:tool.client_upload_files(bucket_name, large_file, large_target_file, pbar.update)

实验(坑)

aws的操作其实是非常繁琐的,因为它基本上很多事情都存在多种实现,而作为初学者难以判断这些实现有哪些坑,以下列举几个基本问题:

  • 为什么我无法使用session/resource/queue/DynamicDB等服务?
    • 因为没有权限或没有购买相关服务
  • 使用endpoint可以做什么事情?
    • endpoint用于创建low-level client,是aws服务最基础的api之一,基本上client和服务是一对一的关系,所以endpoint的权限是非常基本的,这取决于创建endpoint的时候所指定的权限。
  • 在实践中,client应该被call多次还是reuse?
    • 事实上,这取决于aws的收费政策!目前aws仅对服务类型和条件收费,对client的call次数不收费,因此原则上recall和reuse是等价的。然而,从程序规范而言,应该reuse。
  • 上传和下载有哪些关注点?
    • S3对不同层次的资源调用存在速度限制,对于low-level调用存在5GB/单个文件的限制,除非通过multi-part模式处理。然而,在boto3中对此进行了优化和封装,可以自动根据处理文件的大小选择合适的模式进行上传,最多支持5TB。
    • 文件的上传默认采用覆盖写。
    • client处理数据的时候是线程安全的,但无法处理突变的数据,因此不应该同时对S3中的单个数据同时读写。
  • 线程安全:
    • 最佳策略是,认为所有类型的连接都不是线程安全的!以免出现意外的错误。
    • 由于不是线程安全的,因此最好不要使用多线程,至少不要使用互相沟通的多线程,除非你对boto3的属性非常熟悉。
  • 查询数据:
    • 尽管S3采用了桶存储策略,但创建了一张数据表来存储所有的meta信息,因此可以使用SQL语句进行检索。

相关文章:

python botos s3 aws

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html AWS是亚马逊的云服务,其提供了非常丰富的套件,以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK(boto3)的使用进行介绍。 …...

python画神经网络图

代码1(画神经网络连接图) from math import cos, sin, atan import matplotlib.pyplot as plt # 注意这里并没有用到这个networkx这个库,完全是根据matploblib这个库来画的。 class Neuron():def __init__(self, x, y,radius,nameNone):self.x xself.y …...

Bash 编程精粹:从新手到高手的全面指南之逻辑控制

在 Unix 和 Linux 系统中,Bash(Bourne-Again Shell)是一种广泛使用的 shell,提供了强大的脚本编程能力。本文将详细介绍 Bash 脚本中的逻辑控制结构,包括条件判断、分支选择、循环控制以及退出控制等内容。 条件判断&…...

自动化运维(三十)Ansible 实战之自定义插件

Ansible 自定义插件允许你扩展其功能,以满足特定的自动化需求。Ansible 支持多种类型的插件开发,如动态库存、查找、回调、过滤器、变量等。这里我们将通过实例,介绍如何开发、部署和使用一个自定义插件。 开发自定义查找插件 查找插件用于在 Ansible 任务中动态获取数据。…...

实习僧网站的实习岗位信息分析

目录 背景描述数据说明数据集来源问题描述分析目标以及导入模块1. 数据导入2. 数据基本信息和基本处理3. 数据处理3.1 新建data_clean数据框3.2 数值型数据处理3.2.1 “auth_capital”(注册资本)3.2.2 “day_per_week”(每周工作天数&#xf…...

C语言中局部变量和全局变量是否可以重名?为什么?

可以重名 在C语言中, 局部变量指的是定义在函数内的变量, 全局变量指的是定义在函数外的变量 他们在程序中的使用方法是不同的, 当重名时, 局部变量在其所在的作用域内具有更高的优先级, 会覆盖或者说隐藏同名的全局变量 具体来说: 局部变量的生命周期只在函数内部,如果出了…...

小程序中配置scss

找到:project.config.json 文件 setting 模块下添加: "useCompilerPlugins": ["sass","其他的样式类型"] 配置完成后,重启开发工具,并新建文件 结果:...

ZYNQ-Vitis(SDK)裸机开发之(四)PS端MIO和EMIO的使用

目录 一、ZYNQ中MIO和EMIO简介 二、Vivado中搭建block design 1.配置PS端MIO: 2.配置PS端EMIO: 三、Vitis中新建工程进行GPIO控制 1. GPIO操作头文件gpio_hdl.h: 2.GPIO操作源文件gpio_hdl.c: 3.main函数进行调用 例程开发…...

聊聊jvm中内存模型的坑

jvm线程的内存模型 看图,简单来说线程中操作的变量是副本。在并发情况下,如果数据发生变更,副本的数据就变为脏数据。这个时候就会有并发问题。 参考:https://www.cnblogs.com/yeyang/p/12580682.html 怎么解决并发问题 解决的…...

DevOps已死?2024年的DevOps将如何发展

随着我们进入2024年,DevOps也发生了变化。新兴的技术、变化的需求和发展的方法正在重新定义有效实施DevOps实践。 IDC预测显示,未来五年,支持DevOps实践的产品市场继续保持健康且快速增长,2022年-2027年的复合年增长率&#xff0…...

appium控制手机一直从下往上滑动

用于使用Appium和Selenium WebDriver在Android设备上滚动设置应用程序的界面。具体来说,它通过WebDriverWait和expected_conditions等待元素出现,然后使用ActionChains移动到该元素并执行滚动动作。在setUp中,它初始化了Appium的WebDriver和c…...

为什么光伏探勘测绘需要无人机?

随着全球对可再生能源需求的不断增长,光伏产业也迎来了快速发展的机遇。光伏电站作为太阳能发电的主要形式之一,其建设前期的探勘测绘工作至关重要。在这一过程中,无人机技术的应用正逐渐展现出其独特的优势。那么,为什么光伏探勘…...

day10 | 栈与队列 part-2 (Go) | 20 有效的括号、1047 删除字符串中的所有相邻重复项、150 逆波兰表达式求值

今日任务 20 有效的括号 (题目: . - 力扣(LeetCode))1047 删除字符串中的所有相邻重复项 (题目: . - 力扣(LeetCode))150 逆波兰表达式求值 (题目: . - 力扣(LeetCode)) 20 有效的括号 题目: . - 力扣&…...

深入解析Tomcat的工作流程

tomcat解析 Tomcat是一个广泛使用的开源Servlet容器,用于托管Java Web应用程序。理解Tomcat的工作流程对于开发人员和系统管理员来说是非常重要的。本文将深入探讨Tomcat的工作原理,包括请求处理、线程池管理、类加载、以及与Web服务器之间的通信。 ###…...

【web网页制作】html+css旅游家乡山西主题网页制作(3页面)【附源码】

山西旅游网页目录 涉及知识写在前面一、网页主题二、网页效果Page1、景点介绍Page2、酒店精选|出行攻略Page3、景色欣赏 三、网页架构与技术3.1 脑海构思3.2 整体布局3.3 技术说明书 四、网页源码4.1 主页模块源码4.2 源码获取方式 作者寄语 涉及知识 山西旅游主题网页制作&am…...

系统参数指标:QPS、TPS、PV、UV等

QPS QPS:Queries Per Second 是每秒查询率,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,即每秒的响应请求数,也即是最大吞吐能力。 TPS TPS:Tra…...

一入鸿蒙深似海,从此Spring是路人:鸿蒙开发面试题

详细内容请参考最新的官方鸿蒙文档,不保证时效性 写得不对的地方请多多指点,本文仅代表个人所学知识范围 联系方式QQ 1219723557,可一同交流学习 欢迎补充,希望能做一个汇总版本出来 1. 网络编程基本知识(较为简单&…...

【Python】使用OPC UA创建数据服务器

目录 准备工作服务器设置创建或获取节点设置节点值启动服务器查看服务器客户端总结 在工业自动化和物联网(IoT)领域,OPC UA(开放平台通信统一架构)已经成为一种广泛采用的数据交换标准。它提供了一种安全、可靠且独立于…...

JavaScript(六)-高级篇

文章目录 作用域局部作用域全局作用域作用域链JS垃圾回收机制闭包变量提升 函数进阶函数提升函数参数动态参数多余参数 箭头函数 解构赋值数组解构对象解构 遍历数组forEach方法(重点)构造函数深入对象创建对象的三种方式构造函数实例成员 & 静态成员…...

速盾:游戏cdn什么意思

CDN(Content Delivery Network)是指内容分发网络,它是由一组位于世界各地的服务器组成的网络,用于将内容有效地传输给用户。游戏CDN,顾名思义,就是用于游戏内容分发的网络。 在传统的网络传输模式中&#…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...