使用 VueGraggablePlus 实现 el-table 等第三方组件的拖拽排序
使用 VueGraggablePlus 实现 el-table 等第三方组件的拖拽排序引言当我们有一些表格数据需要可以调整顺序时,最直观的做法是拖拽(正如大部分 APP 的做法一样)。 我主要使用 vue3 + element plus 进行开发,当遇到这个需求时网上最常见的解决方案是 vue draggable,可惜这个项目已经 3 年没更新了,而另一个实现了类似功能并且还在积极更新的项目是 vue-draggable-plus,用法非常简单,而且可以很简单地支持第三方组件(例如 el-table)的拖拽排序。 可惜网上对于这个库的介绍非常有限,大多数就是照抄本就简略的官方文档。本文将介绍它在实际开发中的使用方法,帮助有类似需求的朋友节省时间。 演示安装:npm install vue-draggable-plus 以下代码写了一个表格,并将其用VueDraggable包裹起来以实现拖拽排序。并且在下方展示了数据的真实顺序。 1234567891011121314151617181920212223242526272829303132<template> <...
登录验证码发送间隔限制的设计与实现
登录验证码发送间隔限制的设计与实现引言在小项目设计登录模块时,一个常见的思路是账号与邮箱/手机号绑定,通过邮件/短信验证码的方式登录/注册。相比于传统的口令式注册/登录有以下优点: 用户不需要记住密码:只要邮箱/手机号还能用,就可以登录。 系统不需要考虑太多安全问题:数据库不存储敏感信息,安全性由邮箱/电信运营商保障。 登录、注册合一:简化开发。 发送邮件/短信验证码一般都要通过云厂商的服务来实现,如果有人恶意刷接口就会产生大量费用。而且登录验证码本身也是一段时间内有效的,不需要频繁调用。所以我们需要对发送验证码的接口做调用时间间隔的限制。 本文用 vue3 + element plus + springboot 的技术栈举例。重点在分享思路,在使用其他技术栈的情况下也可以套用。 后端目的:对于同一个邮箱来说,一分钟内最多发送一次验证码。 思路:使用 Caffeine 库的 Cache 类,过期策略是写后 1 分钟过期。key 存放邮箱,value 存一个 new Object()(我们可以称之为 time...
马督工自媒体课程学习笔记
马督工自媒体课程学习笔记这篇笔记整理的是我在看马督工自媒体课程时记下的一些方法论。它不只是关于“怎么做内容”,更像是在讨论:一个普通人如果想持续、严肃地观察现实,并把自己的观察讲清楚,应该建立怎样的思维框架。 课程里有些内容偏原则,有些内容偏实操。我先把自己觉得最有价值、也最容易迁移到写作和表达中的部分梳理出来,方便后面反复回看。 学这门课,到底是为了什么?对我来说,核心目的有两个: 更理性、更深刻地理解新闻与现实世界; 提升自己的表达能力,让输出的内容更有逻辑、更有说服力。 如果把“做内容”理解成一种长期训练,那么它训练的不只是写稿能力,更是观察世界、提炼问题和组织观点的能力。 我理解的几个核心原则1. 适度自信:不必是专家,但不能毫无准备媒体人在大多数专业领域里并不是专家,这很正常。关键不在于把自己伪装成无所不知的人,而在于承认自己的边界,同时快速补齐完成一次科普或评论所需的知识。 换句话说,不需要达到学术专家的深度,但至少要达到“足以对普通观众讲明白”的程度。很多时候,这种能力并不神秘,更像是一种高强度、目标明确的短期学习,甚至有点像大学期末突击:带着问题去学,只抓最关...
使用 k8s 搭建一个小巧但健全的 cicd 系统
使用 k8s 搭建一个小巧但健全的 cicd 系统引言本文将以作者的个人小项目“易导游”(e-tour) 为例,介绍作者目前正在使用的 cicd 方案。实现了自动更新部署、自动资源调度、日志系统、告警系统等功能。 总览 架构图如上,我们简单介绍一下图中的关键组件: git 仓库:使用 github 私有仓库,利用 github action 实现 push 后自动构建镜像并更新部署的功能 前端:以静态网页的形式托管在阿里云 oss 上。以节省服务器带宽和流量资源。 镜像仓库:在 infra 服务器自建私有镜像仓库。 k8s:主要目的是充分利用多台低配服务器的内存资源。 后端:以容器的形式运行在 k8s 集群中。 中间件:由于 k8s 并不适合运行有状态应用,所以像数据库、loki 这种中间件我放在一台内存足够大的安装了 docker 的服务器上(下文称之为 infra服务器) 监控告警: 优秀国产开源项目 hertzbeat,当检测到服务下线后通过飞书机器人告警。 日志:loki + promtail + grafana 可以查看 k8s 和 infra 中所有容器的标准输出日...
Docker 健康检查的目的、影响和处理
前言网上关于 Docker 的教程往往只会讲容器、镜像、网络、数据卷。对于健康检查往往只是一笔带过:在 Dockerfile 中写一个 HEALTHCHECK 命令,然后看到容器状态变成了 “healthy” 就万事大吉。而对于不健康的容器会造成什么影响、如何处理不健康的容器则很少提及。 如果想充分发挥容器化的健壮性优势,我们就需要认真审视 Docker 提供的健康检查功能。 结论先行Docker 健康检查是保障容器化应用可靠性的关键机制。 不健康的容器会被 Docker 网络自动隔离,但 Docker 本身不会重启它们。我们需要结合 autoheal 工具实现自动重启,并通过 Prometheus + Alertmanager 实现告警监控。 为什么需要健康检查?默认检查方式的局限性默认情况下,Docker 判断一个容器是否存活的方式是通过检测容器内 PID = 1 的进程是否存活(这个进程就是 Dockerfile 的 ENTRYPOINT 中启动的进程)。 这个检查方式非常粗放,因为有时容器已经失去了正常对外提供服务的能力,但是进程仍然存活。例如: 应用陷入死锁...
安全地远程调用Docker API
安全地远程调用Docker API引言你也许知道如何在一台安装了 docker 的机器上创建、停止、删除容器。但是如果发号施令的程序和 docker 不在同一台机器上该怎么办? 本文将介绍如何开启 docker api 远程调用、使用 http api 或者 java sdk 操作另一台机器上的 docker、以及如何确保 docker api 不被他人调用。 开启 docker api 远程调用(简单,不鉴权,快速体验)默认 docker 只允许本机使用docker命令进行操作,我们现在来开启 http api 调用,使得其他机器可以通过 http 请求来操作 docker。 注意:这种方法不对调用者权限进行校验,也就是说互联网上任何一个人都可以控制你的 docker。我们这里为了快速体验临时使用这种方法,长期使用请务必使用 tls 来鉴权,具体方法下文会介绍。 vim /lib/systemd/system/docker.service 编辑 docker 启动命令,找到 service 模块下的 ExecStart=xxx 这一行,在其末尾添加`-H=tc...
轻松配置 https:Let‘s Encrypt 介绍及 Nginx Proxy Manager 实用操作教程
轻松配置 https:Let‘s Encrypt 介绍及 Nginx Proxy Manager 实用操作教程前言一般我们在本地进行 web 开发时用的都是 http 协议,而部署到服务器上之后为了安全都要配置 https,以保证客户端和服务器之间的通信内容得到加密,不会被泄露或篡改。 本文将介绍 https 协议的基本知识(如果有基础可以跳过),以及如何使用 Let’s Encrypt 给你的服务优雅地配置 https。 HTTPShttps本质上还是http,只不过https使用了ssl协议来加密通信内容。 ssl是一个介于TCP和应用层的协议,基于非对称加密算法,用于确保通信双方的交流是私密的 对称加密加密解密使用同一把密钥,但是如何安全地传输这个密钥是个问题 非对称加密有三条原则: 私钥加密,公钥解密 公钥加密,私钥解密 公钥加密,公钥无法解密 服务端给客户端发放公钥,客户端使用公钥加密请求,只有服务端的私钥能解密。服务端使用私钥加密响应,客户端使用公钥解密。 看起来很美好,但这样存在很一个很大的问题:如果有一个坏人(中间人)像下图这样操作,你们的通讯还是会被窃听甚至...
ThreadLocal 内存泄漏问题
前言ThreadLocal 是 Java 中常见的线程隔离工具,但使用不当容易引发内存泄漏。这是一道经典的面试题,涉及 GC、引用类型、线程池等核心知识点。 结论先行使用不当可能导致内存泄漏,但只要及时调用 remove() 就可以避免。 ThreadLocal 的工作原理数据存储结构每个 Thread 对象都有一个类似哈希表的属性 threadLocals,用于存储该线程的私有变量。虽然这个哈希表的 Entry 结构与 HashMap 不同,但可以用哈希表的思想来理解: Key:ThreadLocal 对象的弱引用 Value:实际存储的数据 这样设计的好处是,同一个 ThreadLocal 对象在不同线程的 threadLocals 中对应不同的 value,从而实现了数据隔离。 为什么 Key 使用弱引用?这里最关键的设计是:为什么 Key 是弱引用,而不是 ThreadLocal 对象本身? 考虑这样的场景: 在 Web 服务器中,处理请求的线程通常是池化的,生命周期很长。如果不断有新的 ThreadLocal 对象被添加到线程的 threadLocals 中,而且...
深入理解 Java 虚拟机-学习笔记
前言《深入理解 Java 虚拟机》是周志明老师的又一力作,系统深入地讲解了 Java 虚拟机的内部原理。本文是我阅读本书的学习笔记,涵盖内存管理、垃圾回收、类加载、并发等核心主题。 我所践行的知识整理方法是”将思考具象化”。做技术不仅要去看、去读、去想、去用,更要去说、去写。将自己”认为掌握了的”知识叙述出来,在此过程之中,会挖掘出很多潜藏在”已知”背后的”未知”。 如无特殊说明,本文默认使用 HotSpot 虚拟机(目前最常见的 Java 虚拟机)。 结论先行理解 JVM 的核心在于理解内存管理和垃圾回收机制。 掌握 JVM 内存模型、GC 算法、类加载机制和锁优化策略,是 Java 开发者进阶的必经之路。这些知识不仅能帮助你写出高性能的代码,更能在生产环境中快速定位和解决内存溢出、性能瓶颈等问题。 一、内存区域 Java 内存分为图中几个区域,各个区域的功能如下: 方法区(Method Area)功能:存储常量值、静态变量、类信息(类的元数据)。 特点:所有线程共享。 堆(Heap)功能:存储对象实例。 特点: 所有线程共享 GC 的主要工作区域 通常是 JVM 中最大...
《凤凰架构》阅读笔记
前言《凤凰架构》是周志明老师撰写的一本关于软件架构演进的著作,不仅内容质量极高,而且阅读起来就像小说一样畅快。本书从单体架构到微服务、从 Spring Cloud 到 Kubernetes,系统地讲述了现代软件架构的演进历程和设计哲学。本文记录了书中的核心思想以及我的思考。 结论先行软件架构的本质是管理复杂性。 没有完美的架构,只有适合当前阶段的架构。架构应该随着业务的发展而演进,而不是一开始就追求最先进的技术栈。理解这一点,就理解了架构设计的核心智慧。 一、架构设计的核心理念非业务功能下沉到基础设施问题背景: 业务代码本身已经足够复杂了,如果一些技术性的代码(例如去重、事务、日志、负载均衡、数据同步)也参与进来,就会显得层次不清晰。 解决方案: 把非业务的功能下沉到基础设施层面去实现。例如: 使用 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 来给 updateTime 字段自动赋值,而不是每次写数据时手动赋值 使用数据库的唯一索引来实现去重,而不是在应用层判断 好处: 代码可以专注于业务实现:应用层代码更简洁、更易维护 更可靠:用基础设施来代替...














