前端实现一键复制及阻止用户复制功能

一、前端实现复制 1. document.execCommand(‘copy’) 已弃用: 不再推荐使用该特性。虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留。请尽量不要使用该特性,并更新现有的代码。请注意,该特性随时可能无法正常工作。 这里是借用 input 或 textarea 来实现。 实现一个复制的方法 // src/hooks/useCopy.ts import {ElMessage} from 'element-plus'; /** * 实现文字复制 * @param copyValue 将要复制的文字 */ export const useCopy = (copyValue: string) => { // 创建输入框 let inputDom = document.createElement('input'); // 给输入框value赋值 inputDom.value = copyValue; // 把input框添加到body上 document.body.appendChild(inputDom); // 选中输入框中的内容 inputDom.select(); // 复制文字到剪切板 const hasCopy = document.execCommand('Copy'); ElMessage({ type: hasCopy ? 'success' : 'error', message: hasCopy ? '复制成功' : '复制失败' }); // 删除创建的dom节点 document.

ERROR: KeeperErrorCode = NoNode for /hbase/master

前言: 今天使用hbase查看数据库的时候,出现了以下报错: 这个错误信息表示在 ZooKeeper 中找不到名为 "/hbase/master" 的节点。这通常意味着 HBase 的元数据没有正确地存储在 ZooKeeper 中,或者 ZooKeeper 的配置有误。 解决方案: 1.先关闭hbase、hadoop和zk服务 2.再配置一下hbase/conf路径下的hbase-site.xml文件,在末尾添加如下内容 <property> <name>zookeeper.znode.parent</name> <value>/hbase/master</value> </property> 3.再将zk数据目录下生成的version-2删除 (zk下的数据目录路径是通过hbase-site.xml设定的) 4.重启zk、hadoop和hbase服务后,再进入hbase即可正常查看数据库了 希望我的方案能帮助到大家。

Unity 接入海康摄像头(WebGL,PC),避坑专用

Unity 接入海康摄像头(WebGL,PC),避坑专用 介绍:项目需要,接入海康威视摄像头云台。应用场景:Unity开发某个物流园区的数字孪生系统,在3D场景中点击监控摄像头图标,弹框播放现场的摄像头画面。 准备:Unity2023.3.0a14、海康威视设备、OpenAPI安全认证库(C#) V1.0.1、AVProVideo、Postman等 说明: Unity版本:用WebGPU提升场景和整体渲染效果,至于Unity2023设置WebGPU相关内容可去官网查看,在Unity6.0版本将推出该设置选项 OpenAPI 安全认证库:海康接口都需要进行安全认证才可正常访问,可在海康开放平台下载(有坑,后续介绍) AVProVideo:视频流播放插件(PC的话也可用UMP替换,但UMP发布WebGL有报错) 正文: 1.线下园区安装好海康威视设备会给每台设备一个唯一的设备标(CameraIndexCode)Unity端会用到这个ID去请求接口,保持设备正常运行,在内网部署设备管理后台,负责与前端进行交互请求,这个海康那边会安排专业人员协助。 2.Unity端事项: 1)导入OpenAPI认证库(C#),该库海康已经封装了基于HTTP的POST和GET请求。以及设置平台信息的接口SetPlatformInfo接口。在HttpUtil脚本内,该类还提供了AK和SK生成签名的相关接口。 SetPlatformInfo: InitHttpRequest: Get: Post: **注意!!!**以上接口由海康提供,可支持非WebGL端项目开发(坑1)。楼主当时也是完全用该接口完成接入,验证编辑器下和发布PC端应用都可以正常使用。在发布WebGL时,*点击事件直接卡死!!!*吐槽:Unity发布WebGL的坑太多,开发要走的路远远不止当下。后续解读源码发现该问题其实在另一个地方就遇到了! 原因(重点):WebGL不支持IO操作,注意System.IO相关接口。 通常读取StreamingAssets文件夹下文件会用File.ReadAllTxt()等接口,在WebGL该接口不可用需要用WWW或UnityWebRequest下载读取。 解决办法: 分析海康Get接口和Post接口,代码块用到Stream和StreamReader两个API,这就导致在WebGL端Http请求时,直接卡死的原因,咱们找到原因得想法解决,在深层次分析原因是HttpWebRequest这个API导致得,这里咱们可以用UnityWebRequest这个API去重写Post和Get方法。相关核心代码如下: InitRequest: Get: Post: 获取监控设备推流地址(POST_GetCameraUrl):camCode:设备编码,唯一标识 跨域请求(坑2): 到此我们发布WebGL测试,点击事件不再出现卡死现象。但接着F12查看日志,发现又一个问题,WebGL上Http请求跨域的问题,这个问题导致的原因是由于发布部署到本地nginx服务上。而Http请求的接口地址是在另一个域名下,查看网上各种解决跨域问题办法,楼主最后没解决,也是困扰了很多天。有的文章说需要服务器端配置;有的是需要nginx配置;有点百家讲坛了。我最后是直接把WebGL部署到服务器一个域名下的。这样就可以正常请求获取推流地址并在Unity端用AVProVideo进行播放实实监控画面了。 AVProVideo在WebGL平台设置: Unity: 总结:每一份耕耘都有一定收获,WebGL的坑源源不止。希望Unity数字孪生系统希望未来有一套成熟的解决方案,兼容各个平台。本项目在WebGL端场景渲染这块也砍了很多刀才能流畅的运行(FPS>60),最后上个项目截图: 资源分享:WebGL平台基于AVProVideo播放海康设备监控实实画面demo源码。 以上内容会分享在以下Demo中。源码下载地址

oracle数据库慢查询SQL

目录 场景: 环境: 慢SQL查询一: 问题一:办件列表查询慢 分析: 解决方法: 问题二:系统性卡顿 分析: 解决方法: 慢SQL查询二 扩展: 场景: 线上环境出现办件列表查询非常慢大概要1分钟才刷出来,及很多功能都出现系统性卡顿。 环境: oracle数据库,工作表历史表act_hi_proinst单表数据量一百多万 慢SQL查询一: select * from (select v.sql_id, v.sql_text, v.sql_fulltext, v.FIRST_LOAD_TIME, v.last_load_time, v.elapsed_time, v.cpu_time, v.disk_reads, v.EXECUTIONS, v.LOADS, v.cpu_time / v.executions / 1000 / 1000 ave_cpu_time, v.ELAPSED_TIME / v.executions / 1000 / 1000 ave_time from v$sql v) a where a.last_LOAD_TIME > '2024-01-01/00:00:00' and ave_time > 5 and a.executions > 0 order by ave_time desc; 其中各字段含义如下: v.sql_text: 包含SQL语句的文本内容

MySQL中如何将字符串替换

在MySQL中,你可以使用REPLACE函数来进行字符串替换操作。REPLACE函数接受三个参数:源字符串,要替换的子字符串,以及替换后的字符串。以下是REPLACE函数的基本语法: REPLACE(str, search_str, replace_str) str: 要进行替换操作的源字符串。search_str: 要替换的子字符串。replace_str: 替换后的字符串。 以下是一个简单的示例,演示如何在MySQL中使用REPLACE函数: SELECT REPLACE('Hello, World!', 'World', 'MySQL') AS replaced_string; 在上面的例子中,REPLACE函数将字符串 'Hello, World!' 中的 'World' 替换为 'MySQL'。执行上述查询将返回结果: +-------------------+ | replaced_string | +-------------------+ | Hello, MySQL! | +-------------------+ 如果你想要更新表中的数据进行替换,可以使用UPDATE语句。例如,假设有一个名为 your_table 的表,其中有一个名为 your_column 的列,你可以执行以下操作: UPDATE your_table SET your_column = REPLACE(your_column, 'old_value', 'new_value') WHERE your_column LIKE '%old_value%'; 在上面的例子中,REPLACE函数将替换 your_column 列中包含 'old_value' 的所有字符串,并将其替换为 'new_value'。确保使用适当的条件(WHERE子句)来限制替换的范围,以避免对整个表进行不必要的操作。 将REPLACE和CONCAT函数结合使用,以在MySQL中实现更复杂的字符串替换和连接操作。以下是一个示例,演示如何使用这两个函数: 假设有一个表 your_table,其中包含两列 column1 和 column2,你想在 column1 的值中替换特定字符串,并将结果连接到 column2 的值。你可以使用以下 SQL 查询: SELECT CONCAT(REPLACE(column1, 'old_value', 'new_value'), column2) AS concatenated_result FROM your_table; 在上述查询中,REPLACE(column1, 'old_value', 'new_value')用于替换column1中的 'old_value' 为 'new_value',而CONCAT函数将替换后的column1与column2连接起来。你可以根据需要调整替换的字符串和列名。

SpringBoot2.7升级项目到Springboot3.1踩坑指南(jdk17/jdk21)

文章目录 概要国内顶级开源项目升级情况适配SpringBoot3指南SpringBoot3升级要点1、jdk17变动(如javax)2、redis修改spring.redis.host ===> spring.data.redis.host3、SpringCloudApplication注解被删除4、不兼容升级import java.servlet====>import jakarta.servlet5、swagger集成 弃用springfox--->springdoc不兼容升级6、动态数据源baomidou的dynamic-datasource依赖变动7、Spring Framework 6.0 中删除了对 Apache HttpClient 支持(RestTemplate受影响)8、SpringBoot3.0整合RocketMQ时出现未能加载bean文件9、springboot3默认依赖 elasticsearch从7.x升级到8.x10、springboot 3.2 openFeign加载失败暂未解决 (3.1没问题)11、hutool5.8-->hutool6.0升级要要点12、Centos7使用jdk21报错13、@Async注解报错Invalid return type for async method (only Future and void 概要 由于SpringBoot3.x全面拥抱JDK17,兼容jdk21,jdk17乃是大势所趋。这里是从SpringBoot2.7-->SpringBoot3.1踩坑指南。 提前阅读:jdk8升级JDK17避坑指南(适用于SpringBoot2.3—SpringBoot2.7升级) 国内顶级开源项目升级情况 国内顶级开源项目升级到springBoot3情况,可以作为升级SpringBoot3的风向标。仅对比国内规模使用,落地过万企业的开源项目 参考:国内顶级开源项目:芋道、ruoyi、JeecgBoot、pig、SpringBlade功能对比 评价项/项目名yudao-cloudRuoyi-CloudRuoYi-Cloud-PlusDante CloudpigbladexJeecgBoot官网芋道yudao-cloud 开发指南若依plus-doc.dromara.orgDante Cloudpig4cloudbladex.cn、看云-SpringBlade开发手册JeecgBoot源码收费免费免费免费免费免费 + 收费(3999)免费 + 收费(5000)免费 + 收费(100000)文档收费文档收费免费、视频收费文档免费、视频收费免费免费、授权收费文档收费文档免费、授权收费githubyudao-cloudRuoYiRuoYi-Vue-PlusDante CloudpigSpringBladejeecg-bootgiteeyudao-cloudRuoYiRuoYi-Vue-PlusDante Cloud暂无SpringBladejeecg-bootjdk17分支master-jdk21RuoYi-Cloud-Plus 2.Xdante-cloud 3.1.Xpig jdk17jeecg-boot/springboot3 适配SpringBoot3指南 参考1-微信公众号-这可能是最全的SpringBoot3新版本变化了!、参考2-SpringBoot官网-Spring Boot 3.0 Release Notes、参考3-微信公众号-Swagger升级指南:Swagger2与Swagger3注解差异揭秘、参考4-微信公众号-Dante Cloud 3.2.0.0 发布,首个适配 Spring Boot 3.2版本及经验分享参考5-JeecgBoot 文档中心-升级SpringBoot3 SpringBoot3升级要点 前提说明,建议先完成springboot2.x—>springBoot2.7.x+jdk17的适配,这里升级难度会小很多。参考:文章最前面的文章。 1、jdk17变动(如javax) 详见: jdk8升级JDK17避坑指南(适用于SpringBoot2.3—SpringBoot2.7升级) 模块化对反射的影响==>对系统类的反射增加了限制,需要打开限制增加jvm启动参数add-opens,自己写的类,可以正常使用反射。删除sun.misc 下的包,如sun.misc.BASE64Encoder==>java.util.Base64替换删除JAXB、soup相关==>maven仓库上面有新的maven坐标,引入新依赖即可删除javax.annotation==>maven仓库上面有新的maven坐标,引入依赖即可 2、redis修改spring.redis.host ===> spring.

十分钟掌握前端获取实时数据的三种主流方式

前端获取实时数据的三种主流方式 本文聊聊前端获取实时数据的三种主要方式。想象一下,我们在网上购物时,经常能看到最新的优惠信息弹出,或者在社交媒体上看到朋友的最新动态更新。这些都是因为后端在默默地向我们的页面推送了最新的消息。那么,这背后到底使用了什么样的技术呢?主要有三种方式:轮询(Polling)、网页套接字(WebSocket) 和服务器发送事件(Server-Sent Events, SSE)。下面,我们就来近距离接触一下它们。 轮询(Polling) 原理 轮询的工作方式很像是孩子不断地问父母“我们到了吗?”。在这个比喻中,前端(孩子)定时向后端(父母)发送请求来检查是否有新数据(是否到目的地了)。轮询又分为短轮询和长轮询两种。 短轮询:前端每隔一定时间就发送一个请求,无论数据是否更新,后端都立即返回响应。长轮询:前端发出请求后,后端会挂起这个请求,直到有数据更新或者超时,才返回响应。 优缺点 总体上说,轮询的优点在于它简单易实现,几乎所有的服务器和客户端技术都能支持。但缺点也很明显,因为它需要不断地发送请求,这会导致大量的网络流量,而且实时性不高,数据更新有延迟。 具体到短轮询和长轮询,可以对它俩再做一个对比: 短轮询 优点: 实现简单,兼容性好。 缺点: 频繁的请求会增加服务器负担,实时性不够,资源浪费较多。 长轮询 优点: 相比短轮询,减少了请求次数,提高了实时性。 缺点: 实现相对复杂,服务器端需要维护挂起的请求,可能会导致资源占用。 适用场景 轮询通常用在对实时性要求不是特别高的场景,比如一些后台管理系统的消息通知、网页上的非实时统计信息展示。下面是使用轮询的一些真实案例: 微信扫码登录:微信的扫码登录功能使用的是轮询机制。当你扫描二维码时,你的手机上的微信客户端会向服务器发送信息,然后你的网页客户端会周期性地询问服务器,用户是否已经通过手机确认。这里使用轮询是因为登录操作并不频繁,且对实时性的要求不需要毫秒级,而且轮询是一种简单且兼容性好的实现方式。Facebook的实时通知:在Facebook早期,他们使用长轮询来实现实时通知。用户的浏览器会开启一个到服务器的长连接,这样一旦有新通知,服务器就能立即推送数据。这种方式对于当时的技术来说是一个很好的折中方案,因为它在不牺牲太多实时性的情况下,减少了请求次数。 代码示例 这里演示一个短轮询。下面我们将要使用Node.js编写一段后端程序,在这段代码中我们提供两个接口,一个接口用于接受轮询、返回最新的消息,另一个接口则用于更新消息。 后端 poll-server.js 的代码如下: const express = require('express'); const app = express(); let message = "No new message"; // 指定public文件夹是静态资源的目录 app.use(express.static("public")); // 前端要轮询访问这个接口,这个接口会返回最新的message app.get('/poll', (req, res) => { res.send(message); message = "No new message"; }); // 在其他地方调用这个接口,更新message app.post('/update', (req, res) => { message = "

网页与串口通信:Web Serial API 使用记录

文章目录 前言1、打开串口 提示用户选择一个串口(因为浏览器安全策略原因,用户必须选择一次)2.读取数据3、解析函数值得注意的点: 1、如果不想每次都让用户选择串口 可以使用公共变量将用户选择的串口 存储下来(cookie和localstorage不行。)。这样就可以在不同的页面 打开或者关闭同一个串口。重复使用 总结 前言 一:Web Serial API 是什么 串口是一个双向通信接口,允许字节发送和接收数据。 Web Serial API为网站提供了一种使用JavaScript对串行设备进行读写的方法。串行设备可以通过用户系统上的串行端口连接,也可以通过模拟串行端口的可移动USB和蓝牙设备连接。 换句话说,Web Serial API通过允许网站与串行设备(如微控制器和3D打印机)通信来连接网络和物理世界。 该API是JS本身navigator对象上就独有的,所以与任何框架开发都没有太大的关系,不管你是用Vue还是React开发。 要使用该API需要服务器使用https协议,同时呢,本地开发建议使用http://localhost:端口号。 二、使用步骤 大致使用的步骤如下: 1、请求用户授权访问串行端口 2、设置串行端口的参数,例如波特率、数据位、停止位、奇偶校验等。 2、打开和关闭串行端口 3、读取和写入串行数据 4、监听来自串行设备的数据 三:具体代码 1、打开串口 提示用户选择一个串口(因为浏览器安全策略原因,用户必须选择一次) async test() { // 打开串口 // 浏览器支持serial if ('serial' in navigator) { // 获取用户之前授予该网站访问权限的所有串口 if (this.port==null) { console.log("有串口::::",this.globalVariable) if (this.globalVariable) { this.port= this.globalVariable console.log("00000000000::",this.globalVariable) this.open() return } // 提示用户选择一个串口 this.port = await navigator.serial.requestPort() this.globalVariable = this.port console.log("11111111111::",this.globalVariable) this.

适用在Windows、Linux和macOS环境下打包Go应用程序的详细步骤和命令

在Go语言中,跨平台是一项强大的特性,使得开发者可以轻松地在不同操作系统上构建应用程序。然而,当我们需要分享或部署我们的Go应用时,通常需要将其打包成可执行文件,并确保在不同的操作系统上能够顺利运行。接下来将详细介绍如何在Windows、Linux和macOS环境下打包Go应用程序,并提供每个步骤和命令的详细说明。 1. Windows平台 1.1 安装Go编译器 首先,确保在Windows上安装了Go编译器。 1.2 编写Go应用 创建一个简单的Go应用程序,例如 hello.go: package main import "fmt" func main() { fmt.Println("Hello, Windows!") } 1.3 构建可执行文件 在命令行中执行以下命令,将Go应用程序构建为可执行文件: go build -o hello.exe hello.go 或 go build -o hello.exe . 1.4 运行应用程序 执行生成的可执行文件: hello.exe 2. Linux平台 2.1 安装Go编译器 同样,确保在Linux上安装了Go编译器。 2.2 编写Go应用 创建一个简单的Go应用程序,例如 hello.go: package main import "fmt" func main() { fmt.Println("Hello, Linux!") } 2.3 构建可执行文件 在命令行中执行以下命令,将Go应用程序构建为可执行文件: go build -o hello.exe hello.go 或 go build -o hello.

EndNote21 for Mac:科研文献管理神器的保姆级教程

最近写论文要看上百篇英语文献,新手刚开始,真正是一顿操作猛如虎,手动下载、查看abstract、手动分类归档······(未来的诺贝尔获奖者正在练成😎) 然而,上述操作重复几天后:疑,这篇文献怎么在这?啊,我之前看过这篇文献吗?·······总之,一阵凌乱😭😭所以是时候需要一个管理文献、阅读文献的工具——EndNote!! EndNote是由Clarivate Analytics(科睿唯安)公司开发的文献管理软件,已发布多个版本,从古至今依次是EndNote X7、EndNote X8 、​​​​​​​EndNote X9 ​​​​​​​、EndNote 20,以及2023年新发布的EndNote 21。EndNote 21 for Mac具有强大的文献搜索和导入功能。用户可以通过内置的在线文献数据库搜索和浏览数百万篇学术论文、期刊文章和图书。一键导入功能允许用户将所需的文献直接导入到EndNote库中,方便管理和引用。 一、下载 有三种下载安装方式: 1、官网下载安装。可以免费试用1个月,但要付费购买激活码才能永久使用,费用大概是100刀~250刀间。当然,咱可以万能淘宝,正版骨折价买到激活码~ 2、网络下载各种破解的、补丁的古早版本。免费是免费,但漏洞可能有点多,还容易宕······· 3、高校校园网免费下载。有些高校买了EndNote版权,能免费直达下载。比如国内的中科大,就是如此壕。再次感叹,高校的图书馆资源,真正是价值连城!! 二、安装EndNote 21 下面就以EndNote 21的安装为例,分享一下操作详情: 1. 打开EndNote的官网下载页面,选择心仪版本的Mac版下载。其实个人感觉21版和20版大差不不差,看个人需要。 2. 下载好安装包后,根据MacOS的常规操作安装就行。 3. 安装完成后,会生成2个app。如下图所示: 点击“EndNote 21"打开。 三、使用EndNote 21 (一)新建library 打开EndNote后,会发现桌面毫无变化,没显示任何相关窗口,只是左上角变成EndNote 21的导航条。 莫慌,这是需要你自建一个 EndNote Library窗口。依次点击左上角导航条file--new,新建一个library。library最好以自己当前在做论文的主题命名,做不同的论文建不同的library,管理起来比较方便。注意!!!library保存路径一定要选存在本地硬盘的文件夹,千万不要选iCloud中的文件夹,否则EndNote会宕,这是来自EndNote的官方警告!! library建好后的页面如下图所示: (二)写论文时,从EndNote中引用参考文献 好多帖子都在教,用Word写论文时怎么从EndNote中引用参考文献,但问题是咱们macOS没有自带Office全家桶啊。有些需要用Office全家桶应用的,大都是下载WPS操作一下。莫慌,咱可以用page写论文啊!!有专门为page开发的EndNote插件,下载安装教程可参考Apple官网 Add citations to your Pages document with the EndNote plug-in - Apple Support (三)搜索论文时,从网页将文献一键归档EndNote 有时候用搜索引擎搜论文、看论文时,找到论文后,可通过Chrome插件EndNote Click,将当前网页论文一键归档至EndNote中。 具体地,安装EndNote Click插件后,注册一个EndNote Click帐号,同时用自己的EndNote帐号登录EndNote online。注意,这三个帐号(EndNote Click帐号、EndNote帐号、EndNote online)一定用同一个邮箱,设置相同的密码,便于文档同步。 此时随意在EndNote支持的以下数据库中找文献: 比如,我们以在PubMed 中找到的文献添加为例: 找到目标文献网页打开后,会出现一个EndNote Click的控件浮窗,如红框所示,这表明当前文献支持EndNote管理。这时候点击Chrome的控件按钮,如下图所示:

解决Linux Shell脚本错误:“/bin/bash^M: bad interpreter: No such file or directory”

在Linux系统中运行Shell脚本时,你可能会遇到一个常见的错误,错误信息如下: -bash: ./xxx.sh: /bin/bash^M: bad interpreter: No such file or directory 这个错误通常是由于Shell脚本文件中存在不兼容的换行符引起的。在Windows系统中,文本文件的行尾通常以回车符(CR)和换行符(LF)的组合表示(称为CRLF),而在Linux和Unix系统中,行尾仅以换行符(LF)表示。当你在Windows环境下编写或编辑Shell脚本,然后尝试在Linux系统上运行时,就可能会遇到这个问题。 解决方法 解决这个问题的一种简单方法是使用sed命令删除脚本中的回车符。你可以运行以下命令: sed -i 's/\r$//' xxx.sh 这条命令的作用是在原地(-i)修改文件,查找每一行末尾的回车符(\r$)并将其删除。这样,文件就会被转换为仅包含换行符(LF)的Unix风格的行尾格式,从而避免了上述错误。 注意 在运行sed命令之前,最好备份原始的Shell脚本,以防万一出现问题。如果你经常需要在Windows和Linux环境之间编辑和运行Shell脚本,考虑使用支持“Unix/Linux行尾格式”选项的文本编辑器,如Visual Studio Code、Notepad++等,这样可以在保存文件时自动使用正确的行尾格式。

【Kafka】 幂等和事务详解

目录 幂等性为什么需要幂等性如何实现幂等性使用幂等幂等性的限制条件幂等性的实现原理 事务为什么需要事务开启事务事务保证事务恢复的保证事务原子性的保证事务中 Offset 的提交保证用于事务特性的控制型消息 事务流程事务原理FindCoordinatorRequestInitProducerIdRequest开启事务回话流的处理与转发阶段提交或回滚事务超时事务中止 拒绝僵尸实例与分布式事务机制对比事务操作 相关配置总结 幂等性 保证在消息重发的时候,消费者不会重复处理。即使在消费者收到重复消息的时候,重复处理,也要保证最终结果的一致性。 所谓幂等性,数学概念就是: f(f(x)) = f(x) 。f函数表示对消息的处理。 比如,银行转账,如果失败,需要重试。不管重试多少次,都要保证最终结果一定是一致的。 Exactly-Once 即精准一次,来保证幂等性。Exactly once是Kafka从版本0.11之后提供的高级特性。 为什么需要幂等性 在使用Kafka时,需要确保Exactly-Once语义。分布式系统中,一些不可控因素有很多,比如网络、OOM、FullGC等。在Kafka Broker确认Ack前,有可能出现网络异常、FullGC、OOM等问题时导致Ack超时,Producer会进行重复发送。注,在未达到最大重试次数前,会自动重试(非应用程序代码写的重试)。 Kafka在引入幂等性之前,Producer向Broker发送消息,然后Broker将消息追加到消息流中后给Producer返回Ack信号值。实现流程如下: 生产中,会出现各种不确定的因素,比如在Producer在发送给Broker的时候出现网络异常。比如以下这种异常情况的出现: 上图这种情况,当Producer第一次发送消息给Broker时,Broker将消息(x2,y2)追加到了消息流中,但是在返回Ack信号给Producer时失败了(比如网络异常) 。此时,Producer端触发重试机制,将消息(x2,y2)重新发送给Broker,Broker接收到消息后,再次将该消息追加到消息流中,然后成功返回Ack信号给Producer。这样下来,消息流中就被重复追加了两条相同的(x2,y2)的消息。 因此需要保证幂等性保证即使多次发送也要让最终的结果一样。 如何实现幂等性 Kafka在0.11.0.0之后加入的幂等性。他是通过添加唯一ID,类似于数据库的主键,用于唯一标记一个消息。它在底层设计架构中引入了ProducerID和SequenceNumber。那这两个概念的用途是什么呢? PID:ProducerID,每个生产者启动时,Kafka 都会给它分配一个 ID,ProducerID 是生产者的唯一标识,需要注意的是,Kafka 重启也会重新分配 PIDSequenceNumber :对于每个ProducerID,Producer发送数据的每个Topic和Partition都对应一个从0开始单调递增的SequenceNumber值。 同样,下图一种理想状态下的发送流程。实际情况下,会有很多不确定的因素,比如Broker在发送Ack信号给Producer时出现网络异常,导致发送失败。异常情况如下图所示: 当Producer发送消息(x2,y2)给Broker时,Broker接收到消息并将其追加到消息流中。此时,Broker返回Ack信号给Producer时,发生异常导致Producer接收Ack信号失败。对于Producer来说,会触发重试机制,将消息(x2,y2)再次发送,但是,由于引入了幂等性,在每条消息中附带了PID(ProducerID)和SequenceNumber。相同的PID和SequenceNumber发送给Broker,而之前Broker缓存过之前发送的相同的消息,那么在消息流中的消息就只有一条(x2,y2),不会出现重复发送的情况。 使用幂等 通过如下配置使用幂: enable.idempotence=true。enable.idempotence配置项表示是否使用幂等性。当enable.idempotence配置为true时,acks必须配置为all。并且建议max.in.flight.requests.per.connection的值小于5。acks=all。 幂等性的限制条件 单独只使用Producer的幂等性是存在一些限制条件的: 只能保证 Producer 在单个会话内不丟不重 ,如果 Producer 出现意外挂掉再重启是无法保证的(幂等性情况下,是无法获取之前的状态信息,因此是无法做到跨会话级别的不丢不重);幂等性不能跨多个 Topic-Partition,只能保证单个 partition 内的幂等性 ,当涉及多个 Topic-Partition 时,这中间的状态并没有同步。 如果需要跨会话、跨多个 topic-partition 的情况,需要使用 Kafka 的事务性来实现。这种幂等性只是保证了再生产端实现了幂等性,在实际场景中往往需要在消息者端实现幂等性,可以最大程度避免重复消费。 幂等性的实现原理 每个新的Producer在初始化的时候会被分配一个唯一的PID(凡是开启幂等性都是需要生成PID,只不过未开启事务的PID可以在任意broker生成,而开启事务只能在TransactionCoordinator节点生成),该PID对用户完全透明而不会暴露给用户。Broker端也会为每个<PID, Topic, Partition>维护一个序号,并且每次Commit一条消息时将其对应序号递增。对于接收的每条消息,如果其消息序号比Broker维护的序号(即最后一次Commit的消息的序号)大一,则Broker会接受它,否则将其丢弃: 如果消息序号比Broker维护的序号大于1以上,说明中间有数据尚未写入,也即乱序,此时Broker拒绝该消息,Producer抛出InvalidSequenceNumber如果消息序号小于等于Broker维护的序号,说明该消息已被保存,即为重复消息,Broker直接丢弃该消息,Producer抛出DuplicateSequenceNumber 上述设计解决了 0.11.0 之前版本中的两个问题: Broker 保存消息后,发送 ACK 前宕机,Producer 认为消息未发送成功并重试,造成数据重复前一条消息发送失败,后一条消息发送成功,前一条消息重试后成功,造成数据乱序 producer_id是从Kafka服务端请求获取的(通过 ProducerIdManager 的 generateProducerId() 方法产生,维护在zk中的 /latest_producer_id_block 节点),消息序列号是Producer端生成的,初始值为0,之后自增加1,每个分区都有独立的序列号。。这里需要说明下,Kafka发送消息都是以batch的格式发送,batch包含了多条消息。所以Producer发送消息batch的时候,只会设置该batch的第一个消息的序列号,后面消息的序列号可以根据第一个消息的序列号计算出来。

windows的python怎么降版本,anaconda的python降版本

本篇文章给大家谈谈python降级要重新配置环境吗,以及windows的python怎么降版本,希望对各位有所帮助,不要忘了收藏本站喔。 写在前面:相信很多人安装pytorch或者tensorflow都是冲着机器学习或者深度学习来的。有一个问题是,有很多文献的模型是基于python3.6版本的环境,但是很多人在初次安装python时往往是安装最新版本如3.8,3.9等等(包括我)python如何画九朵花。所以需要降低python版本以适应不同的需求。 1. 电脑硬件配置 此贴不适合电脑配有独立显卡的人。CPU版本运行速度较慢,建议在个人条件允许的情况下升级硬件。但只有CPU版本也可以。(可自行上网查找如何查看电脑显卡,桌面任务栏最左边右键找到设备管理器,然后是显示适配器) 2. 查看自身python版本 打开anaconda prompt 或者cmd 输入 python -V 两者是一样的。若直接输入python,则会输出相应版本号但同时会进入python编辑环境。 3. 降低python版本 此时,如果想从python3.8降低到python3.6(其实是安装多一个py3.6的环境),可进行以下操作。首先,没有conda镜像环境的需要设置一下, conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --set show_channel_urls yes 然后在cmd 或者 anaconda prompt中输入以下命令 conda create -n py36 python=3.6 anaconda 成功后会提示你激活py3.6环境或者退回原本的版本, 按照提示激活即可。 参考:https://blog.csdn.net/qq_38463737/article/details/109492394?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-109492394-blog-85851587.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-109492394-blog-85851587.pc_relevant_vip_default&utm_relevant_index=3 完成以上命令后,如果没有在开始窗口找到关于py36的命令,则需要自行继续下载,查看标题4,若有py36的命令,可跳过标题4。 4. 下载 jupyter notebook和prompt(py36) 打开Anaconda Navigator,在home页面的上方有applications on选择项,选择刚刚下载的py36。 然后在py36环境下选择你要下载的功能即可。或者可以在prompt(py36环境下)输入以下命令 conda install jupyter notebook 5. 安装pytorch(CPU版本) 1.在官网找到适合自己的PyTorch,复制Run this commend那里的命令。 进入cmd或者上面下载后的prompt(py36) ,输入复制后的命令。 安装完成后可查看是否安装成功,在prompt命令行中输入 pip list ## 在列出的已安装包中找到torch,或者进入python输入以下内容 import torch print(torch.

【go】一、go语言vscode开发环境

一、下载安装go和vscode go编译环境下载地址 vscode下载地址 二、安装vscode插件: 1、安装vscode go插件 2、替换源(这里用的阿里云) 如果有外网环境可以忽略 如下点开vscode终端(或系统cmd) 依次输入: go env -w GO111MODULE=on go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/ 3、安装go插件依赖 vscode中按下ctrl+shift+p 搜索go:install/update tools,之后全选,点击ok 安装成功会显示: 三、新建文件夹,并配置go.mod 1、创建工程文件夹 如go_test,其下新建src文件夹,src文件夹下新建main.go文件: 2、配置go.mod 打开vscode终端,输入go mod init 【工程文件夹名】,如: go mod init go_test 文件夹下会生成一个go.mod文件: 四、运行、编译代码 1、编辑main.go 输入以下代码: // 当前包名,和文件名相同 package main // 导入go的输入输出库 import "fmt" // 程序入口main函数 func main() { // 命令行打印并换行 fmt.Println("Hello, World!") } 2、运行代码 方式1:vscode调试运行 点击F5,或vscode的run and debug: 方式2:用命令行运行 终端cd src,进入src文件夹,之后输入go run main.go: 五、编译 命令说明go run 编译并直接运行go文件

创建Firebase项目并接入Firebase推送: Firebase Cloud Messaging (FCM)

1.FCM简介: Firebase Cloud Messaging (FCM) 是一种跨平台消息传递解决方案,可供您可靠地传递消息,而且还是免费的服务。支持 Android,IOS,Web,Flutter,Unity. 消息类型 可以使用 FCM 向客户端发送两种类型的消息: 通知消息,有时被称为“显示消息”。此类消息由 FCM SDK 自动处理。 数据消息,由客户端应用处理。 通知消息包含一组用户可见的预定义键。与其相对,数据消息只包含用户定义的自定义键值对。通知消息可以包含可选的数据载荷。两种消息类型的载荷上限均为 4000 个字节,但从 Firebase 控制台发送消息时会强制执行 1024 个字符的限制。 使用情景 如何发送 通知消息 当客户端应用在后台运行时,FCM SDK 会代表客户端应用向最终用户设备显示消息。如果应用在收到通知时正在前台运行,应用的代码会决定行为。通知消息包含一组预定义的用户可见的键和一个由自定义键值对组成的可选的数据载荷。 在可信环境(例如 Cloud Functions 或应用服务器)中,使用 Admin SDK 或者 FCM 服务器协议:设置 notification 键。可能包含可选的数据载荷。 一律可折叠。 请参阅一些显示通知示例并发送请求载荷。 使用 Notifications Composer:输入消息文本、标题等,然后发送。通过提供自定义数据添加可选的数据载荷。 数据消息 客户端应用负责处理数据消息。数据消息仅包含自定义键值对,没有保留键名(请参阅下文)。 在可信环境(例如 Cloud Functions 或应用服务器中),使用 Admin SDK 或者 FCM 服务器协议:仅设置 data 键。 通知消息 如果要进行测试,或者要开展营销、重新吸引用户,可以使用 Firebase 控制台发送通知消息。Firebase 控制台提供基于分析的 A/B 测试,可帮助优化和改进营销消息。 如需使用 Admin SDK 或 FCM 协议以编程方式发送通知消息,可使用通知消息中用户可见部分所必需的预定义键值对选项集来设置 notification 键。例如,以下是即时通讯应用中的 JSON 格式的通知消息。用户可能会在设备上看到标题为“Portugal vs.

Spring boot整合sse(使用详解)

一、简介 SSE是一种基于HTTP长连接技术,允许服务器向客户端浏览器实时推送更新。客户端通过创建一个EventSource对象并指向服务器上的一个URL来发起请求,这个请求保持打开状态,服务器可以在这个单一的TCP连接上不断发送新的数据块。这些数据块被称为“事件”,每个事件包含类型(可选)、数据和一些元数据(如事件ID,重新连接时间间隔等)。服务器端以简单的文本格式(通常为UTF-8编码的纯文本)发送数据。 二、SSE有什么用 理论上, SSE 和 WebSocket 做的是同一件事情。当你需要用新数据局部实时更新网络应用时,SSE 可以做到不需要用户执行任何操作,便可以完成。如统计数据的实时情况。类似这种更新频繁、 低延迟的场景,SSE 可以完全满足。 SSE 是单向通道,只能服务器向客户端发送消息,当客户端发送一个 HTTP 请求,和服务器进行了一次握手,SSE便可以一直向客户端发送消息。相对于 WebSocket 的双工通道来说,开销会更小一些。 三、SSE发送的数据类型 在服务器端,需要使用text/event-stream作为响应的Content-Type。发送的数据中: 1. event字段是可选的,用于指定事件的名称; 2. data字段是必须的,用于指定数据的内容; 3. id字段是可选的,用于指定事件的标识符; 4. retry字段是可选的,用于指定客户端在连接断开后重新连接的时间间隔(以毫秒为单位)。 每个字段都必须以换行符(\n)结尾,并且每个消息都必须以两个换行符(\n\n)结尾。 四、集成SSE的使用 1.pom依赖引入 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 2.编写创建长链接接口 这里展示创建SseEmitter的service的代码,controller中仅调用该接口即可 public SseEmitter createSseConnect() { // 设置超时时间,0表示不过期。默认30秒,超过时间未完成会抛出异常:AsyncRequestTimeoutException SseEmitter sseEmitter = new SseEmitter(0L); String clientId = String.valueOf(UUID.randomUUID()); sseCache.put(clientId, sseEmitter); // 连接断开回调 sseEmitter.onCompletion(() -> { sseCache.get(clientId).complete(); sseCache.remove(clientId); }); // 连接超时 sseEmitter.onTimeout(()-> { sseCache.get(clientId).complete(); sseCache.remove(clientId); }); // 连接报错 sseEmitter.

Python—协程(Coroutine)

文档结构 1、概念简介2、使用场景3、实现方式4、代码案例5、注意事项 参考手册:https://docs.python.org/zh-cn/3.10/library/asyncio-task.html 1、概念简介 协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行),是一种用户状态内的上下文切换技术,其实就是通过一个线程实现代码块相互切换执行,因此也称为轻量级的线程。 协程的切换完全由程序控制,而非通过操作系统内核来实现,因此对资源的开销更小; 2、使用场景 通过 async & awiat 实现异步编程,是Python实现异步操作的主流技术; 如果一个对象可以在 await 语句中使用,那么它就是 可等待 对象。许多 asyncio API 都被设计为接受可等待对象。 可等待 对象有三种主要类型: Coroutine(协程),task(任务) 和 Future; 3、实现方式 1)greenlet:一个第三方模块,需要提前安装 pip3 install greenlet才能使用; 2)yield生成器:借助生成器的特点亦可以实现协程代码; 3)asyncio:在python3.4 种引入的模块,用于编写协程代码; 说明:主要通过装饰器 @asyncio.coroutine 来实现协程函数定义;Python3.8之后 @asyncio.coroutine 装饰器会被移除,推荐使用async & awit 关键字实现协程代码。 4)async & awiat:在python3.5中引入的两个关键字,结合asyncio模块使用; 4、代码案例 场景:目前解析一个 xml文件,需要解析的节点处理为一个列表,然后希望并发解析列表里的节点数据; 实现方式1:多线程方式 1)创建函数 parseNode(node, delay); 2)循环该节点列表,每个节点分配一个线程去执行 parseNode(node, delay),同时将该线程加入线程列表 thread_list; 3)循环线程列表,执行 th.join(),使主线程等待每个线程执行完成; 4)执行主线程后续步骤; 实现方式2:协程方式 代码1:直接执行协程对象 # -*- coding= utf-8 -*- """ @DevTool : PyCharm @Author : xxx @DateTime : 2024/1/29 15:36 @FileName : coroutineDemo.

MySQL中的`longtext`与`longblob`:深度剖析与应用场景

前言 在数据库设计的过程中,选择恰当的数据类型对于优化存储效率和提升查询性能至关重要。MySQL作为广泛应用的关系型数据库管理系统,提供了丰富的数据类型以满足各种数据存储需求。其中,当涉及到大容量文本字符串或二进制文件的存储时,longtext和longblob两种数据类型便发挥着重要的作用。尽管它们都能处理大规模的数据,但两者之间存在显著的区别,适用场景也有所不同。本文将深入探讨MySQL中longtext和longblob的特性、区别以及在实际项目中的应用场景。 1. longtext:海量文本数据的承载者 longtext 是MySQL提供的用于存储长文本数据的数据类型,其最大可容纳4GB(即4294967295字节)的文本信息。考虑到字符集编码的影响,实际能存储的字符数量会因所选字符集的不同而有所变化。longtext字段广泛应用于存储长篇文章、详尽的日志记录、JSON或XML格式的非结构化数据等纯文本内容。 2. longblob:二进制大对象的安放地 longblob 则是一种用于存储大型二进制数据的类型,同样具有高达4GB的存储容量。它主要用于保存图像、音频、视频、文档等非文本、非结构化的二进制文件。在构建需要直接将用户上传的原始文件存入数据库的应用程序时,longblob成为不可或缺的选择。 区别与总结 数据本质:longtext适用于存储文本信息,而longblob则专注于承载二进制数据。处理机制:文本数据按照特定字符集进行编码和解码;二进制数据则不做任何转换,原样存储和检索。应用场景:当需要存储篇幅较长的文章、日志或其他文本资源时,选用longtext;若要存放用户上传的各种二进制格式文件,则应使用longblob。 实际应用考量 性能影响因素:尽管这两种类型均能支持大容量数据存储,但在数据库层面直接存放大文件可能对系统性能产生消极影响,包括增加磁盘I/O负担、拖慢查询速度,甚至影响数据库备份恢复效率。因此,在某些情况下,采用文件系统存储大文件并仅在数据库中保留文件路径链接或许更为明智。索引问题挑战:MySQL对text和blob列创建全文索引具有特定限制,且此类字段建立索引可能导致索引过大,降低数据库性能。通常来说,对于这类字段不建议常规索引策略。 通过以上解析,我们不仅了解了longtext与longblob之间的核心差异,而且明晰了如何根据实际业务场景灵活运用这两种数据类型。在面对大数据存储的实际需求时,请务必结合具体业务逻辑、存储成本、性能要求等因素,作出最适合您的数据库设计方案。

SQL中Limit的用法详解

SQL中的LIMIT关键字是一个非常有用的工具,它可以用来限制查询结果返回的记录数量。文章将详细解析LIMIT关键字的使用方法,包括它的基本用法,以及在查询数据时如何配合使用LIMIT与OFFSET。我会通过示例代码演示LIMIT在单行结果集和多行结果集情况下的不同应用,并讨论LIMIT在排序和分组查询中的作用。此外,我还会阐述LIMIT与查询结果集相关性,以及它在实际应用中的一些常见错误用法和注意事项。 一、基本用法 LIMIT关键字的基本语法有两种形式: 1、LIMIT n: 返回查询结果的前n条记录。 SELECT * FROM table_name LIMIT 5; 这条语句将返回table_name表中的前5条记录。 2、LIMIT offset, n: 返回从第offset条记录开始的n条记录。 SELECT * FROM table_name LIMIT 2, 5; 这条语句将返回table_name表中从第3条记录开始的5条记录。 二、单行结果集 当查询结果集只有一行时,LIMIT关键字可以用来确保只返回一行记录。 SELECT * FROM table_name LIMIT 1; 这条语句将返回table_name表中的第一行记录。 三、多行结果集 当查询结果集有多行时,LIMIT关键字可以用来限制返回的记录数量。 SELECT * FROM table_name LIMIT 5; 这条语句将返回table_name表中的前5行记录。 四、使用OFFSET LIMIT关键字还可以与OFFSET一起使用,以从查询结果集中的特定行开始返回记录。 SELECT * FROM table_name LIMIT 5 OFFSET 2; 这条语句将返回table_name表中从第3行记录开始的5行记录。 五、在排序和分组查询中的作用 在使用ORDER BY进行排序或使用GROUP BY进行分组时,LIMIT关键字可以用来限制返回的记录数量。 -- 按年龄升序排序,并返回前5名 SELECT name, age FROM table_name ORDER BY age ASC LIMIT 5; -- 按年龄升序排序,并返回年龄最大的10名 SELECT name, age FROM table_name ORDER BY age ASC LIMIT 10; -- 按省份分组,并返回每个省份人数最多的5个地区 SELECT province, COUNT(*) as population FROM table_name GROUP BY province LIMIT 5; 六、高级用法 1、配合子查询使用:

python GUI tkinter 一样做出非常美观的界面,简单易学,不输QT

说起python 语言的GUI模块,python自身的tkinter库和PyQt库相信是很多人都绕不开的。tkinter是python的标准库,不需要安装,简单易学,代码量少,这是它最大的优点,但是它有个致命的弱点,就是界面外观实在太难看,而且网上深层次的资料很少,基本上都是一些基础用法。而PyQt呢,是个非常专业的GUI工具,可以做出非常漂亮的界面,但是它学习起来比较复杂,代码量大,开发难道高。由于本人并非专业开发者,自从学python以来一直用tkinter,所以我想能不能用tkinter也做出比较美观漂亮的界面呢?于是开发了这个xtkinter库,希望能开发方便一些。不过这个xtkinter还有一些缺点未解决,仍然需要改进,一是主题目前都是图片化的,这一点已经想到一个解决办法,日后有时间会在新的版本中更新; 二是在windows系统下圆角有锯齿的问题,这个问题目前本人没有好的解决办法,希望有懂的开源爱好者,能一起想办法解决一下。不多说了,看下面的重点: xtkinter 介绍 xtkinter是基于tkinter的python Ui窗口设计模块,是tkinter库的扩展,添加了更灵活的自定义窗口设计以及主题样式的可视化修改 安装教程 可使用pip install xtkinter 下载安装最新该模块在gitee平台上下载源代码git clone https://gitee.com/yuhypython/xtkinter.git 案例 用xtkinter的自定义窗口功能开发的窗口,该案例模仿网络上一个用PyQt设计的UI框架,用xtkinter模块也可以轻松实现比较美观的界面,而且代码量很少,非常简单易用。 该案例是xtkinter基于本身开发的主题创建器themeCreator, 可以使用以下代码打开,并对现有主题修改或创建新的主题,详见使用说明 from xtkinter.xtkthemes import themeCreator as thc thc.themeCreator() 调用themeCreator()方法就会打开如下的界面,该界面也基于xtkinter模块自身开发的 使用说明 介绍: xtkinter主要分为两部分,一部分是更加灵活的自定义窗口; 另一部分就是主题创建器themeCreator. 第一章:xtkinter 的自定义窗口 1. 主窗口的自定义设计 xtk_tk 首先是导入模块 from xtkinter.windows import xtk_tk as xtk 说明: 对于窗口的设计,因为原有的tkinter窗口的标题栏及窗口外形无法更多的修改,所以在xtkinter中去掉了原有的tkinter标题 栏,然后重新创建标题栏,可以随意设置。所以在使用中如果需要传统的tkinter标题栏,可以直接使用tkinter.Tk() 或 使用封装后xtk.Tk(),都是在调用原tkinter的窗口;如果想自定义窗口则使用xtk下的三个窗口对象。 在该模块下有三个窗口对象: CanvasRoundedWindow :自定义圆角形窗口 使用 root = xtk.CanvasRoundedWindow() root.mainloop() 就可以调用一个简单的圆角形窗口 而对窗口的设置是通过对象的属性来调整的, 以下是CanvasRoundedWindow对象的属性 icon : 标题的图标,是str类型,为图片的地址, title: 标题的内容,str类型, title_height : 标题栏的高度 int, title_frame_bg:标题栏的背景色, main_frame_bg:窗口主框架的背景色, inner_bd: 窗口内边框的宽度, win_width:窗口的宽度, win_height:窗口的高度, win_transparent_color: 窗体的透明色,即tkinter中-transparentcolor的属性 win_bg: 窗体的背景色, 一般和title_frame_bg的值相同, win_outline_color: 窗体的外边框的颜色, win_outline_width: 窗体的外边框的宽度, radii:窗体圆角的大小, 此属性值为0时,窗体为方角,和CornerWindow一样都能做成方角窗口, 举例: root = xtk.