浅尝Apache Mesos
文章目录
- 1. Mesos是什么
- 2. 共享集群
- 3. Apache Mesos
- 3.1 Mesos主节点
- 3.2 Mesos代理
- 3.3 Mesos框架
- 4. 资源管理
- 4.1 资源提供
- 4.2 资源角色
- 4.3 资源预留
- 4.4 资源权重与配额
- 5. 实现框架
- 5.1 框架主类
- 5.3 实现执行器
- 6. 小结
- 参考
1. Mesos是什么
Mesos是什么,Mesos是一个分布式的系统内核。
Mesos的构建原理与Linux内核相同,只是抽象级别不同。Mesos的内核在每台机器上运行并为应用程序(例如Hadoop、Spark、Kafka、ElasticSearch)提供API跨整个数据中心和云环境的资源管理和调度。
Mesos主要有以下特性:
- 线性可扩展
- 经过业界验证,可以轻松扩展到数万个节点
- 高可用性
- 使用Zookeeper实现主服务器和代理服务器容错副本,无中断升级
- 容器化
- 原生支持使用Docker和AppC镜像启动容器
- 可插拔隔离
- 对CPU、内存、磁盘、端口、GPU和自定义资源隔离模块的一流隔离支持
- 两级调度
- 支持使用可插入的调度策略在同一集群中运行云原生和遗留应用程序
- 接口
- 用于开发新的分布式应用程序、操作集群和监控的HTTP API
- Web UI
- 内置Web UI,用于查看集群状态和容器沙箱导航
- 跨平台
- 可在Linux、OSX和Windows上运行,与云服务商无关
我们通常会将各种应用程序部署在同一台机器集群上。而Apache Mesos是一个允许此类程序之间共享资源的平台。
2. 共享集群
许多应用程序需要共享集群,总的来说有两种常见的方法:
- 对集群静态分区并在每个分区上运行一个应用程序
- 为应用程序分配一组机器
上述方法虽然允许应用程序彼此独立运行,但并不能实现较高的资源利用率:比如某个应用程序只运行了一小段时间,之后处于非活动状态,由于我们为该应用程序分配了静态机器或分区,因此在非活动状态期间,存在未使用的资源。
我们可以通过将非活动状态期间的共享资源重新分配给其他应用程序来优化资源利用率,而Apache Mesos则可以帮助应用程序之间的资源动态分配。
3. Apache Mesos
基于我们上面讨论的两种共享集群的方法,应用程序只知道他们正在运行的特定分区或机器的资源,然而Apache Mesos为应用程序提供了集群中所有资源的抽象视图。
Mesos会充当机器与应用程序之间的接口,为应用程序提供集群中所有机器上的可使用资源,它会经常更新此信息从而获取完成状态的应用程序释放的资源。它允许应用程序做出关于哪台机器上执行哪个任务的最佳决定。
为了理解Mesos的工作原理,我们来看下它的架构:
上图展示了Mesos的主要组件,Mesos由一个管理运行在每个集群节点上的代理守护进程和主守护进程以及在这些代理上运行任务的Mesos框架组成。
主节点通过提供资源实现跨框架的细粒度资源共享(CPU、RAM等)。每个提供的资源包含一个列表<agent ID, resource1: amount1, resource2: amount2, ...>
,主节点根据给定的组织策略(例如公平共享和严格优先级)决定向每个框架提供多少资源。为了支持多样化的策略集,主节点才用模块化架构,可通过插件机制来轻松添加新的分配模块。
在Mesos上运行的框架由两个组件组成:
- 向主节点注册以获取资源的调度程序
- 在代理节点上启动以运行框架任务的执行程序进程
主节点确定向每个框架提供多少资源,而框架的调度程序则选择使用提供资源中的哪些资源。当框架接受提供的资源时,它会将要在这些资源上运行的任务的描述传递给Mesos,反过来,Mesos会在相应的代理上启动任务。
3.1 Mesos主节点
Master是Mesos中的核心组件,用于存储集群中资源的当前状态,此外,它还通过传递有关资源和任务等信息,从而充当代理和应用程序之间的协调器。
由于主服务器发生任何故障都会导致资源和任务状态丢失,因此我们将其部署在高可用性配置中。如上图所示,Mesos部署了主服务器守护进程和一个Master,这些守护进程依靠Zookeeper在发生故障时恢复状态。
3.2 Mesos代理
Mesos集群必须在每台机器上运行代理,这些代理定期向主节点报告其资源,并依次接收应用程序已经安排运行的任务。在计划任务完成或者丢失后,次循环将重复。
3.3 Mesos框架
Mesos允许应用程序实现一个抽象组件,该组件与Master交互以接收集群中的可用资源,并根据这些资源做出调度决策,这些组件成为框架。
Mesos的框架由两个子组件组成:
- 调度程序:使应用程序能够根据所有代理上的可用资源来调度任务
- 执行器:在所有代理上运行,并包含该代理上执行任务计划任务所需的所有信息
框架安排任务运行的示例图:
- 代理1向主服务器报告其有4个CPU和4GB的可用内存,主服务器随后调度分配策略模块,告知其应该为框架1提供所有可用资源。
- 主服务器向框架1发送资源邀约,描述代理1有哪些可用资源
- 框架的调度程序向主服务器回复在代理上运行的两个任务的信息,第一个任务使用<2CPU,1GB RAM>,第二个任务使用<1CPU,2GB RAM>
- 最后主服务器将任务发送给代理,代理将适当的额资源分配给框架的执行器,执行器则启动这两个任务(图中虚线所示),由于仍然存在1CPU和1GB RAM未分配,因此分配模块现在可以将它提供给框架2.
此外,当任务完成且新资源变为空闲时,此资源提供过程会重复。
Mesos允许应用程序使用各种编程语言实现自定义调度程序和执行程序。按照Mesos-go中的Scheduler接口的定义如下,具体可参考:Mesos Scheduler interface
// Scheduler a type with callback attributes to be provided by frameworks
// schedulers.
//
// Each callback includes a reference to the scheduler driver that was
// used to run this scheduler. The pointer will not change for the
// duration of a scheduler (i.e., from the point you do
// SchedulerDriver.Start() to the point that SchedulerDriver.Stop()
// returns). This is intended for convenience so that a scheduler
// doesn't need to store a reference to the driver itself.
type Scheduler interface {Registered(SchedulerDriver, *mesos.FrameworkID, *mesos.MasterInfo)Reregistered(SchedulerDriver, *mesos.MasterInfo)Disconnected(SchedulerDriver)ResourceOffers(SchedulerDriver, []*mesos.Offer)OfferRescinded(SchedulerDriver, *mesos.OfferID)StatusUpdate(SchedulerDriver, *mesos.TaskStatus)FrameworkMessage(SchedulerDriver, *mesos.ExecutorID, *mesos.SlaveID, string)SlaveLost(SchedulerDriver, *mesos.SlaveID)ExecutorLost(SchedulerDriver, *mesos.ExecutorID, *mesos.SlaveID, int)Error(SchedulerDriver, string)
}
从上述接口的定义可以看出,它主要由各种回调方法组成,主要用于与主机通信。
同样,执行器的实现也需要实现Executor接口,具体可参考:Mesos Executor interface
/*** Executor callback interface to be implemented by frameworks' executors. Note* that only one callback will be invoked at a time, so it is not* recommended that you block within a callback because it may cause a* deadlock.** Each callback includes an instance to the executor driver that was* used to run this executor. The driver will not change for the* duration of an executor (i.e., from the point you do* ExecutorDriver.Start() to the point that ExecutorDriver.Join()* returns). This is intended for convenience so that an executor* doesn't need to store a pointer to the driver itself.*/
type Executor interface {Registered(ExecutorDriver, *mesosproto.ExecutorInfo, *mesosproto.FrameworkInfo, *mesosproto.SlaveInfo)Reregistered(ExecutorDriver, *mesosproto.SlaveInfo)Disconnected(ExecutorDriver)LaunchTask(ExecutorDriver, *mesosproto.TaskInfo)KillTask(ExecutorDriver, *mesosproto.TaskID)FrameworkMessage(ExecutorDriver, string)Shutdown(ExecutorDriver)Error(ExecutorDriver, string)
}
4. 资源管理
4.1 资源提供
上面说到代理节点会将其资源信息发布给主服务器,反过来主服务器将这些资源提供给集群中运行的框架,此过程成为资源提供。
资源信息一般由两部分组成:
- 资源
- 资源用于发布代理机器的硬件信息,例如CPU、内存、磁盘等
- 属性
每个代理有五种预定义资源:
- 中央处理器
- 图形处理器
- 内存
- 磁盘
- 端口
这些资源的值可以用以下三种类型之一来定义:
- 标量:用浮点数来表示数值信息,以允许小数值,例如1.5G内存
- 范围:用于表示标量值的范围,例如端口号范围
- 集合:用于表示多个文本值
默认情况下,Mesos代理会尝试从机器检测这些资源。但在某些情况下我们可以在代理上配置自定义资源,此类自定义资源的值,也应为上述任何一种类型。
例如,我们可以使用以下这些资源启动我们的代理:
--resources='cpus:24;gpus:2;mem:2048;disk:40960;ports:[21000-24000];bugs(debug_role):{a,b,c}'
上面我们为代理配置了一些预定义资源和一个名为bugs集合类型的自定义资源。
除了资源之外,代理还可以向主服务器发布键值属性,这些属性充当代理的附加元数据,并帮助框架进行调度决策。
一个有用的例子是将带来添加到不同的机架或者区域,然后在同一个机架或者区域上安排各种任务以实现数据本地化
--attributes='rack:abc;zone:sg;os:centos5;level:10;keys:[1000-1500]'
与资源类似,属性的值可以是标量、范围或者文本类型。
4.2 资源角色
现代操作系统许多都支持多用户,同样,Mesos也支持同一个集群中的多个用户,这些用户被称为角色。我们可以将每个决策视为集群中的资源消费者。
由此,Mesos代理可以基于不同的分配策略对不同角色下的资源进行划分,而框架可以在集群内订阅这些角色,从而实现对不同角色下的资源进行细粒度的控制。
例如,假设有一个集群托管应用程序,为组织中不同用户提供服务,因此,通过将资源划分成角色,每个应用程序都可以彼此独立地工作。
此外,框架可以使用这些角色来实现数据局部性。
例如,假设集群中有两个应用程序,分别为生产者和消费者,其中生产者将数据写入持久卷,消费者随后可以读取该卷,我们可以通过生产者共享该卷来优化消费者应用程序。
由于Mesos允许多个应用程序订阅同一角色,我们可以将持久卷与资源角色关联起来,此外,生产者和消费者的框架都将订阅相同的资源角色,因此消费者应用程序现在可以在与生产者应用程序相同的卷上启动数据读取任务。
4.3 资源预留
Mesos如何将集群资源分配给不同的角色,Mesos通过预留来实现资源分配。
预留类型有两种:
- 静态预留
- 动态预留
静态预留则是在代理启动时的资源分配:
–resources=“cpus:4;mem:2048;cpus(test_abc):8;mem(test_abc):4096”
与静态预留不同,动态预留允许我们重新调整角色内的资源,Mesos允许框架和集群操作员通过框架消息(作为对资源提供的响应)或者通过HTTP API调用动态更改资源分配。
Mesos将所有不具有任何角色的资源分配给名为(*)的默认角色,Master主服务器向所有框架提供此类资源,无论它们是否订阅了该资源。
4.4 资源权重与配额
Mesos主节点一般使用公平策略来提供资源,它使用加权主导资源公平性来识别缺少资源的角色,然后主服务器向已订阅这些角色的框架提供更多资源。
尽管在应用程序之间公平共享资源是Mesos的一个重要特性,但这并非是必要的。假设一个集群托管着资源占用低的应用程序和资源需求高的应用程序。在样的部署中,我们希望根据应用程序的性质分配资源。
Mesos允许框架通过订阅角色并为该角色添加更高的权重来请求更多资源。因此,如果有两个角色,一个权重为1,另一个为2,则Mesos会为第二个角色分配两倍的公平份额资源。
另外,我们还可以通过HTTP接口调用来配置权重,可参考:Mesos Weights Set by HTTP API
除了确保为具有权重的角色公平分配资源之外,Mesos还确保为角色分配最少的资源。
Mesos允许我们为资源角色添加配额,配额可以指定角色保证接收到的最小资源量。
5. 实现框架
Mesos允许应用程序选择任意语言提供框架实现,即实现Scheduler和Executor的接口从而实现框架。
5.1 框架主类
在实现调度程序和执行程序之前,需要先实现框架的入口点:
- 向master注册
- 向代理执行器提供运行时信息
- 启动调度程序
下面程序来自Mesos官方提供的示例,具体可参考:Mesos Framework Python test examples
import os
import sys
import timeimport mesos.interface
from mesos.interface import mesos_pb2
from mesos.scheduler import MesosSchedulerDriverTOTAL_TASKS = 5TASK_CPUS = 1
TASK_MEM = 128class TestScheduler(mesos.interface.Scheduler):def __init__(self, implicitAcknowledgements, executor, framework):self.implicitAcknowledgements = implicitAcknowledgementsself.executor = executorself.framework = frameworkself.taskData = {}self.tasksLaunched = 0self.tasksFinished = 0self.messagesSent = 0self.messagesReceived = 0# 注册def registered(self, driver, frameworkId, masterInfo):print "Registered with framework ID %s" % frameworkId.valueself.framework.id.CopyFrom(frameworkId)driver.updateFramework(framework, [])def resourceOffers(self, driver, offers):# 资源申请for offer in offers:tasks = []offerCpus = 0offerMem = 0for resource in offer.resources:if resource.name == "cpus":offerCpus += resource.scalar.valueelif resource.name == "mem":offerMem += resource.scalar.valueprint "Received offer %s with cpus: %s and mem: %s" \% (offer.id.value, offerCpus, offerMem)remainingCpus = offerCpusremainingMem = offerMemwhile self.tasksLaunched < TOTAL_TASKS and \remainingCpus >= TASK_CPUS and \remainingMem >= TASK_MEM:tid = self.tasksLaunchedself.tasksLaunched += 1print "Launching task %d using offer %s" \% (tid, offer.id.value)task = mesos_pb2.TaskInfo()task.task_id.value = str(tid)task.slave_id.value = offer.slave_id.valuetask.name = "task %d" % tidtask.executor.MergeFrom(self.executor)cpus = task.resources.add()cpus.name = "cpus"cpus.type = mesos_pb2.Value.SCALARcpus.scalar.value = TASK_CPUS # CPU资源mem = task.resources.add()mem.name = "mem"mem.type = mesos_pb2.Value.SCALARmem.scalar.value = TASK_MEM # 内存资源tasks.append(task)self.taskData[task.task_id.value] = (offer.slave_id, task.executor.executor_id)remainingCpus -= TASK_CPUSremainingMem -= TASK_MEMoperation = mesos_pb2.Offer.Operation()operation.type = mesos_pb2.Offer.Operation.LAUNCHoperation.launch.task_infos.extend(tasks)driver.acceptOffers([offer.id], [operation])def statusUpdate(self, driver, update):# 状态更新print "Task %s is in state %s" % \(update.task_id.value, mesos_pb2.TaskState.Name(update.state))# Ensure the binary data came through.if update.data != "data with a \0 byte":print "The update data did not match!"print " Expected: 'data with a \\x00 byte'"print " Actual: ", repr(str(update.data))sys.exit(1)if update.state == mesos_pb2.TASK_FINISHED:self.tasksFinished += 1if self.tasksFinished == TOTAL_TASKS:print "All tasks done, waiting for final framework message"slave_id, executor_id = self.taskData[update.task_id.value]self.messagesSent += 1driver.sendFrameworkMessage(executor_id,slave_id,'data with a \0 byte')if update.state == mesos_pb2.TASK_LOST or \update.state == mesos_pb2.TASK_KILLED or \update.state == mesos_pb2.TASK_FAILED:print "Aborting because task %s is in unexpected state %s with message '%s'" \% (update.task_id.value, mesos_pb2.TaskState.Name(update.state), update.message)driver.abort()# Explicitly acknowledge the update if implicit acknowledgements# are not being used.if not self.implicitAcknowledgements:driver.acknowledgeStatusUpdate(update)# 框架消息处理def frameworkMessage(self, driver, executorId, slaveId, message):self.messagesReceived += 1# The message bounced back as expected.if message != "data with a \0 byte":print "The returned message data did not match!"print " Expected: 'data with a \\x00 byte'"print " Actual: ", repr(str(message))sys.exit(1)print "Received message:", repr(str(message))if self.messagesReceived == TOTAL_TASKS:if self.messagesReceived != self.messagesSent:print "Sent", self.messagesSent,print "but received", self.messagesReceivedsys.exit(1)print "All tasks done, and all messages received, exiting"driver.stop()if __name__ == "__main__":if len(sys.argv) != 2:print "Usage: %s master" % sys.argv[0]sys.exit(1)executor = mesos_pb2.ExecutorInfo()executor.executor_id.value = "default"executor.command.value = os.path.abspath("./test-executor")executor.name = "Test Executor (Python)"executor.source = "python_test"framework = mesos_pb2.FrameworkInfo()framework.user = "" # Have Mesos fill in the current user.framework.name = "Test Framework (Python)"framework.checkpoint = Trueframework.role = "*"implicitAcknowledgements = 1if os.getenv("MESOS_EXPLICIT_ACKNOWLEDGEMENTS"):print "Enabling explicit status update acknowledgements"implicitAcknowledgements = 0if os.getenv("MESOS_EXAMPLE_AUTHENTICATE"):print "Enabling authentication for the framework"if not os.getenv("MESOS_EXAMPLE_PRINCIPAL"):print "Expecting authentication principal in the environment"sys.exit(1);credential = mesos_pb2.Credential()credential.principal = os.getenv("MESOS_EXAMPLE_PRINCIPAL")if os.getenv("MESOS_EXAMPLE_SECRET"):credential.secret = os.getenv("MESOS_EXAMPLE_SECRET")framework.principal = os.getenv("MESOS_EXAMPLE_PRINCIPAL")else:framework.principal = "test-framework-python"credential = None# Subscribe with all roles suppressed to test updateFramework() methoddriver = MesosSchedulerDriver(TestScheduler(implicitAcknowledgements, executor, framework),framework,sys.argv[1],implicitAcknowledgements,credential,[framework.role])status = 0 if driver.run() == mesos_pb2.DRIVER_STOPPED else 1# Ensure that the driver process terminates.driver.stop();sys.exit(status)
调度程序可能会由于缺乏资源而无法再代理上启动任务,则会被拒绝,就是上面的DRIVER_STOPPED。
5.3 实现执行器
框架的执行器组件负责在Mesos代理上执行应用程序服务。
import sys
import threading
import timeimport mesos.interface
from mesos.interface import mesos_pb2
from mesos.executor import MesosExecutorDriverclass MyExecutor(mesos.interface.Executor):def launchTask(self, driver, task):# Create a thread to run the task. Tasks should always be run in new# threads or processes, rather than inside launchTask itself.def run_task():print "Running task %s" % task.task_id.valueupdate = mesos_pb2.TaskStatus()update.task_id.value = task.task_id.valueupdate.state = mesos_pb2.TASK_RUNNINGupdate.data = 'data with a \0 byte'driver.sendStatusUpdate(update)# This is where one would perform the requested task.print "Sending status update..."update = mesos_pb2.TaskStatus()update.task_id.value = task.task_id.valueupdate.state = mesos_pb2.TASK_FINISHEDupdate.data = 'data with a \0 byte'driver.sendStatusUpdate(update)print "Sent status update"thread = threading.Thread(target=run_task)thread.start()def frameworkMessage(self, driver, message):# Send it back to the scheduler.driver.sendFrameworkMessage(message)if __name__ == "__main__":print "Starting executor"driver = MesosExecutorDriver(MyExecutor())sys.exit(0 if driver.run() == mesos_pb2.DRIVER_STOPPED else 1)
执行器的代码比较简单,主要是定义了task执行的逻辑以及对应将数据发回调度器的逻辑。
6. 小结
因为在工作中看到有对应的Mesos字眼,虽然自己不会去直接接触这个东西(大多都是通过包装好的组件间接使用),但了解一下运行原理对自己理解一些组件会有一些帮助。
主要是学习了一下Mesos的基本原理和统一集群中运行的应用程序之间的资源共享,以及Mesos是如何通过集群资源(CPU和内存等)帮助应用程序实现资源最大利用。
里面还有涉及到关于Mesos的资源的公平分配策略以及订阅角色的应用程序之间的资源动态分配,Mesos允许应用程序根据集群中的Mesos代理提供的资源做出调度决策,同时Mesos提供了大量HTTP API可用于接口调用进行资源的权重和配额修改。
另外关于Mesos的具体实践还需要继续学习,这次只是在虚拟机大致跑了一下测试用例,并没有采用手动编写程序的方式来进行具体实践。
参考
- Mesos Architecture
- mesos-go
- Apache Mesos
相关文章:
浅尝Apache Mesos
文章目录 1. Mesos是什么2. 共享集群3. Apache Mesos3.1 Mesos主节点3.2 Mesos代理3.3 Mesos框架 4. 资源管理4.1 资源提供4.2 资源角色4.3 资源预留4.4 资源权重与配额 5. 实现框架5.1 框架主类5.3 实现执行器 6. 小结参考 1. Mesos是什么 Mesos是什么,Mesos是一个…...
buuctf题目讲解-1
一眼就解密 ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30 flag{THEFLAGOFTHISSTRING} base家族 base64 加密原理: 明文:abc 去找ascii码的二进制形式 a-->97-→01100001 (二进制为8位如果不足8位则在最左边补0至8位) b-→…...
软件测试学习之-ADB命令
ADB命令 adb工具即Android Debug Bridge(安卓调试桥) tools。它就是一个命令行窗口,用于通过电脑端与模拟器或者真实设备交互。在某些特殊的情况下进入不了系统,adb就派上用场啦! Android程序的开发通常需要使用到一…...
Redis的入门导读(一)
目录 单机架构 分布式系统 个人总结 一.Redis的介绍 二.Redis特性 三.Redis的快原因 四.Redis的应用场景 五.Redis的总结 由于Redis和分布式系统息息相关,因此我们需要先了解一下,分布式系统! 接下来就是分布式系统的演化过程。 单…...
H5与小程序:两者有何不同?
H5,即HTML5,是构建Web内容的一种语言描述方式,也是互联网的下一代标准,被认为是互联网的核心技术之一。HTML5是在HTML4.01的基础上进行了一定的改进后的规范,用户在使用任何手段进行网页浏览时看到的内容原本都是HTML格…...
计算机视觉、目标检测、视频分析的过去和未来:目标检测从入门到精通 ------ YOLOv8 到 多模态大模型处理视觉基础任务
文章大纲 计算机视觉项目的关键步骤计算机视觉项目核心内容概述步骤1: 确定项目目标步骤2:数据收集和数据标注步骤3:数据增强和拆分数据集步骤4:模型训练步骤5:模型评估和模型微调步骤6:模型测试步骤7:模型部署常见问题目标检测入门什么是目标检测目标检测算法的分类一阶…...
7月10日学习打卡,环形链表+栈OJ
前言 大家好呀,本博客目的在于记录暑假学习打卡,后续会整理成一个专栏,主要打算在暑假学习完数据结构,因此会发一些相关的数据结构实现的博客和一些刷的题,个人学习使用,也希望大家多多支持,有…...
鸿蒙语言基础类库:【@ohos.util.TreeSet (非线性容器TreeSet)】
非线性容器TreeSet 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 T…...
freemarker生成pdf,同时pdf插入页脚,以及数据量大时批量处理
最近公司有个需求,就是想根据一个模板生成一个pdf文档,当即我就想到了freemarker这个远古老东西,毕竟freemarker在模板渲染方面还是非常有优势的。 准备依赖: <dependency><groupId>org.springframework.boot</gr…...
勇攀新高峰|暴雨信息召开2024年中述职工作会议
7月8日至9日,暴雨信息召开2024年中述职工作会议,总结回顾了上半年的成绩和不足,本次会议采用线上线下的方式举行,公司各部门管理人员、前台市场营销人员参加述职,公司领导班子出席会议。 本次述职采取了现场汇报点评的…...
C++:filter2D函数简要概述
OpenCV中的filter2D函数是一个非常强大的工具,用于对图像进行卷积操作,从而应用各种线性滤波器。这个函数能够处理图像中的每个像素,通过将其与指定的卷积核(或称为滤波器)进行卷积运算,来修改图像的特性。…...
Postman使用教程【项目实战】
目录 引言软件下载及安装项目开发流程1. 创建项目2. 创建集合(理解为:功能模块)3. 设置环境变量,4. 创建请求5. 测试脚本6. 响应分析7. 共享与协作 结语 引言 Postman 是一款功能强大的 API 开发工具,它可以帮助开发者测试、开发和调试 API。…...
微软Phi-3:小型而强大的AI模型解析与实战指南
微软Phi-3:小型而强大的AI模型解析与实战指南 引言 随着人工智能技术的飞速发展,小型而高效的AI模型逐渐成为研究与应用的新热点。微软研究院推出的Phi-3系列模型,以其卓越的性能和高效的成本效益,在AI领域引起了广泛关注。本文…...
Python 获取 SQL 指纹和 HASH 值
前言 本文介绍一个提取 SQL 指纹的方法,就是将 SQL 语句的条件转换为 ?可用于脱敏和 SQL 聚类分析的场景。 1. 工具安装 这里用到的工具,就是 pt 工具集中的 pt-fingerprint 含在 Percona Toolkit 中,安装方法可参考 Percona T…...
基于OpenCv的快速图片颜色交换,轻松实现图片背景更换
图片颜色更换 图片颜色转换 当我们有2张图片,很喜欢第一张图片的颜色,第2张图片的前景照片,很多时候我们需要PS进行图片的颜色转换,这当然需要我们有强大的PS功底,当然小编这里不是介绍PS的,我们使用代码完全可以代替PS 进行图片的颜色转换 图片颜色转换步骤: 步骤…...
在Linux下直接修改磁盘镜像文件的内容
背景 嵌入式Linux系统通常在调试稳定后,会对磁盘(SSD、NVME、SD卡、TF卡)做个镜像,通常是.img后缀的文件,以后组装新设备时,就将镜像文件烧录到新磁盘即可,非常简单。 这种方法有个不便之处&a…...
ASP.NET Core----基础学习03----开发者异常页面 MVC工作原理及实现
文章目录 1. 开发者异常页面(1)Startup.cs 页面的基础配置(2)自定义显示报错代码的前后XX行 2. MVC 的原理3. MVC 的实现4.默认路由路径5.返回Json字符串 1. 开发者异常页面 (1)Startup.cs 页面的基础配置 namespace ASP.Net_Blank {public class Startup{private readonly IC…...
jvm 07 GC算法,内存池,对象内存分配
01 垃圾判断算法 1.1引用计数算法 最简单的垃圾判断算法。在对象中添加一个属性用于标记对象被引用的次数,每多一个其他对象引用,计数1, 当引用失效时,计数-1,如果计数0,表示没有其他对象引用,…...
ComfyUI入门教程
本文主要介绍了通过源码运行comfyui,默认例子介绍,节点管理器的使用,以及界面汉化。可多参考开源工作流,多加实践,从而掌握comfyui操作。 1.源码运行comfyui 执行命令python main.py如下: 安装numpy 1.x最…...
Flutter TabBar与TabBarView联动及获取当前点击栏目索引
TabBar还有TabBarView都是谷歌flutter官方组件库——Material组件库提供的组件,其中TabBar用于导航切换,TabBarView则是配合其切换显示的对应的视图,官网参考地址:TabBarView class - material library - Dart API。 实现一体联动…...
【区块链+跨境服务】跨境出口电商溯源 | FISCO BCOS应用案例
当前跨境出口电商已成为带动我国外贸发展的中坚力量,尤其疫情特殊时期,成为推动经济增长的一个重要组成 部分。但是跨境出口电商流程长、环节多,且需辗转于不同的服务商以及国家之间,监管与定位也相对困难,容 易出现诸…...
记录一次mysql死锁问题的分析排查
记录一次死锁问题的分析排查 现象 底层往kafka推送设备上线数据应用层拉取设备上线消息,应用层有多个消费者并发执行将设备上线数据同步数据库表pa_terminal_channel日志报:(Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: …...
【UE5.1 角色练习】16-枪械射击——瞄准
目录 效果 步骤 一、瞄准时拉近摄像机位置 二、瞄准偏移 三、向指定方向射击 四、连发 效果 步骤 一、瞄准时拉近摄像机位置 打开角色蓝图,在事件图表中添加如下节点,当进入射击状态时设置目标臂长度为300,从而拉近视角。 但是这样切…...
04OLED简介和调试方法
OLED简介和调试方法 调试方式串口调试显示屏调试其他调试方法总结: OLED简介硬件电路OLED驱动函数 keil调试模式进入方法keil调试界面窗口简单功能说明更加强大的功能 调试方式 电脑想看什么变量可以直接打印到屏幕,但是单片机很多时候由于成本和电路结构…...
“LNMP环境搭建实战指南:从零开始配置CentOS 7下的Nginx、MySQL与PHP“
目录 1.前言 2.准备工作 2.1.环境信息 2.2.关闭SELinux和firewalld 3.安装Nginx 3.1.运行以下命令,安装Nginx 3.2.运行以下命令,查看Nginx版本 4.安装MySQL 4.1.更新秘钥 4.2.配置MySQL的YUM仓库 4.3.安装MySQL 4.4.查看MySQL版本 4.5.启动…...
院内导航:如何用科技破解就医找路难题
自2019年开始“院内导航”被纳入医院智慧服务评估体系以来,到2023年改善就医服务升级的部署,每一步都见证了我国医疗卫生体系向智能化、人性化迈进的坚实步伐。 面对庞大复杂的医院环境与日益增长的就诊需求,如何让患者在茫茫人海中迅速找到就…...
C++基础篇(1)
目录 前言 1.第一个C程序 2.命名空间 2.1概念理解 2.2namespace 的价值 2.3 namespace的定义 3.命名空间的使用 4.C的输入输出 结束语 前言 本节我们将正式进入C基础的学习,话不多说,直接上货!!! 1.第一个C程…...
云视频监控中的高效视频转码策略:视频汇聚EasyCVR平台H.265自动转码H.264能力解析
随着科技的快速发展,视频监控技术已经广泛应用于各个领域,如公共安全、商业管理、教育医疗等。与此同时,视频转码技术作为视频处理的关键环节,也在不断提高视频的质量和传输效率。 一、视频监控技术的演进 视频监控技术的发展历…...
xcode配置swift使用自定义主题颜色或者使用RGB或者HEX颜色
要想在xcode中使用自定义颜色或者配置主题色,需要在Assets中配置,打开Assets文件,然后点击添加Color Set: 输入颜色的名称,然后选中这个颜色,会出现两个颜色: Any Appearance表示亮色模式下使用…...
相同含义但不同类型字段作为join条件时注意事项
假设表A和表B中都有表示学号的stu_id字段,但该字段在表A和表B中类型分别为bigint和string。当直接通过该字段进行join时,一般情况下可以得到我们预期的结果。 select a.stu_id from a as r join b as l on r.stu_id l.stu_id 但是如果学号长度较长的…...
东营做网站优化的公司/网络营销课程
欢迎来到我的《从源码中学Vue》专题系列文章,更多精彩内容持续更新中,欢迎关注 :)上一章节我们通过源码分析了Vue中的methods对象下的方法是如何挂载到vm下,以及各方法内部的this为何是指向了vm对象。其实在Vue中,还有…...
全包家装原创装修网站/怎么做百度网页
美食节 题解:学习了动态加边,可以说是进一步理解了网络流。具体思路就是考虑每一道菜,如果这是该位厨师最后一次做,那么等待时间就是做这道菜的时间,如果是倒数第二次做,就要两倍时间(目前做了一…...
自应式网站/游戏推广员是违法的吗
//将输入的小写转换为大写 private void txtstockout_id_KeyPress(object sender, KeyPressEventArgs e){//将输入的小写转换为大写if ((int)e.KeyChar > 97 && (int)e.KeyChar < 122){e.KeyChar (char)((int)e.KeyChar - 32);}} ① e.Handled如果处理过事件&am…...
什么是网站挂马/百度信息流广告代理
转载于:https://www.cnblogs.com/Crixus3714/p/9790884.html...
上传网站视频要怎么做才清楚/公司地址怎么弄在百度上显示
在项目中往往将一些配置信息放到配置文件中,这样在不同的运行环境中,只需修改配置文件即可。 以下介绍两种通过第三方包获取配置文件的方式 一.通过gopkg.in/ini.v1 go get gopkg.in/ini.v11. 配置文件test.conf ;[mqtt] mqtt_hostname 12…...
网站开发 外包空心/站长工具同大全站
概述:泛海微AS4120是一款面向5V供电输出高达2A锂离子电池充电芯片。它是采用1.5MHz固定频率的同步降压型转换器,因此具有高达90%以上的充电效率,自身发热量极小。芯片包括完整的充电终止电路、自动再充电和一个精确度达1%的4.2V/4.35V预设充电…...