项目模拟实现消息队列第二天
消息应答的模式
1.自动应答:
消费者把这个消息取走了,就算是应答了(相当于没有应答)
2.手动应答:
basicAck方法属于手动应答(消费者需要主动调用这个api进行应答)
小结
1.需要实现生产者,broker server,消费者这三个部分的
2.针对生产者和消费者来说,
主要编写的是 客户端和服务器的网络通信部分,给客户端提供一组api,让客户端的业务代码来调用,从而通过网络通信的方式远程调用broker server的方法
至于生产者的数据从哪里来,消费者取到数据之后干嘛,生产者和消费者的具体业务逻辑,我们不去关心
3.[重点]
实现broker server以及broker server内部的一些核心概念和核心api
核心概念:Virtual host,Exchange,Queue,Binding,Message
核心api:创建交换机,删除交换机,创建队列,删除队列,创建绑定,解除绑定,发送消息,订阅消息,应答消息
4.持久化
上述这些关键数据,在硬盘上怎么存储,什么格式存储,存储在数据库中,文件中?后续服务器重启了,如何读取当前数据,把内存中的内容恢复过来
上述要做的工作,最终目标就是实现一个"分布式系统"下这样的生产者消费者模型
消息队列中存在的核心概念
1.交换机 Exchange
2.队列. Queue
3.绑定 Binding
4.消息 Message
针对交换机,队列,绑定,消息---内存中也需要存储(执行效率高),硬盘上也需要存储(持久化),有些交换机,队列,绑定等,需要持久化存储,但是有些则不需要,用户使用的时候,可以通过开关(boolean值)来决定是否真正需要持久化
管理关键概念需要两个部分
1.内存
2.硬盘 ->数据库,文件
考虑使用MySQL本身比较重量,此处为了使用更方便,简化环境,采用更轻量的数据库,SQLite(一个完整的SQLite数据库,只有一个单独的可执行文件(不到1M),这个数据库相当于是直接操作本地的硬盘文件
SQLite应用非常广泛,在一些性能不高的设备上,使用数据库的首选,尤其是移动端和嵌入式设备Android系统,就是内置的SQLite(不用额外安装,直接使用maven,把SQLite的依赖引入进来即可,会自动加载jar和动态库文件
SQLite如何建库能
当把依赖和配置都搞好了,
难点1:
如何把
private Map<String,Object> arguments=new HashMap<>()转化成数据库中的字符串类型呢?关键要点是:MyBatis在玩成数据库操作的时候,会自动调用对象的getter和setter
1.比如MyBatis往数据库中写数据,就会调用对象的getter方法拿到属性的值,再往数据库中写,如果这个过程让,getArguments得到的结果是String类型的,此时就可以把数据写到数据库中了
2.比如MyBatis从数据库读数据的时候,就会调用对象的setter方法,把数据库智能鼓独到的结果设置到对象的属性中,比如这个过程,让setArguments,参数是一个String,并且在setArguments内部针对字符串解析,解析成一个Map对象。
使用Mybatis来创建数据表的时候,需要先创建出数据库来,创建meta.db这个文件,由于data目录不存在,所以创建meta.db文件的操作,也就失败了。
Message,如何在硬盘上存储
1.消息操作并不涉及到复杂的增删改查
2.消息数量可能非常多,数据库访问效率是不高的
直接把消息存储在文件中
一下设定了消息如何在文件中存储
消息是依附于队列的
因此存储的时候,就把消息按照队列的维度展开
此处已经有了个data目录,meta.db就在这个目录中
在data中创建一些子目录,每个队列有一个子目录,子目录的名字,就是队列名
data->
meta.db
testQueue1 这几个也是目录,用来存储对应的消息
testQueue2
testQueue3
每个队列的子目录喜爱,再分配两个文件,来存储信息
第一个文件:queue_data.txt这里保存消息的内容
第二个文件: queue_stat.txt这里保存消息的统计信息
queue_data这个文件是一个二进制格式的文件
做出以下约定~
这个文件中包含若干个消息,每个消息都以二进制的方式存储
每个消息都由这几个部分构成
二进制的格式是java标准库序列化来实现的
Message对象,是在内存中记录一份,硬盘上也记录一份,内存中这一份,要记录offsetBeg和offsetEnd随时找到内存中的Message对象,就能找到对应的硬盘上的Message对象了。
对于Broker Server来说,消息是需要新增,也是需要删除的,生产者生产一个消息过来,就得新增这个消息,消费者吧这个消息消费掉,这个消息就要删除
新增和删除,对于内存来说-好办(直接使用一些集合类)
但是在文件上就麻烦了,新增消息,可以直接把新的消息追加到文件末尾~删除消息不好处理,文件可以视为一个顺序表,这样的结构,如果此时直接删除中间元素,就需要涉及到类似于顺序表搬运这样的操作-效率非常低的是。
因此我们采用逻辑删除-isValid为1,有效消息,isValid为0-无效消息
随着时间的推移,这个消息文件可能会越来越大~并且,这里可能大部分都是无效的消息,针对这种情况,就需要考虑对当前消息数据文件,进行垃圾回收。
使用复制算法,针对消息数据文件中的垃圾,进行回收
如果某个队列中,消息特别多,而且都是有效消息,此时就会导致整个消息数据文件特别大,后续针对这个文件的各种操作,成本就会上升很多,假如这个文件大小是10G,此时如果出发一次GC,整体耗时就会非常高了
对于RabbitMQ来说,解决方案是把一个大的文件,拆成若干个小文件。
文件拆分:当单个文件长度到达一个阈值之后,就会拆分成两个文件(拆者拆着,就变成了很多文件)
文件合并:每个单独的文件都会进行GC,如果GC之后,发现文件变小了很多,就可能会和相邻的文件合并。
这样做,就可以在消息特别多的时候,也能保证性能上的及时响应
这一块逻辑比较复杂,因此此处不进行实现,咱们只考虑单个文件的情况
如果要实现这个机制,大概思路:需要专门的数据结构,来存储当前队列中有多少个数据文件,每个文件大小是多少,消息数目是多少,无效消息是多少
2.设计策略,什么时候出发文件的拆分,什么时候触发文件的合并
统计文件,读写比较简单
消息数据文件,比较复杂
消息序列化如何实现:
首先什么叫做序列化:把一个对象(结构化数据)转成一个字符串/字节数组->(降维打击了)
注意这样的序列化完成之后,对象的信息是不丢失的。这样后面才可以进行反序列化
序列化之后,方便存储和传输->(相当于干粮脱水)
一般是存储在文件中,文件只能存字符串/二进制数据,不能直接存对象
通过网络传输 JSON来完成序列化,反序列化
由于Message,里面存储的body是二进制数据,不太方便使用JSON进行序列化,JSON序列化得到的结果是文本数据,无法存储二进制。
我们准备直接使用二进制的序列化方式,针对Message对象进行序列化~
针对二进制序列化,也有很多种解决方案
1.JAVA标准库提高了序列化的方案,ObjectInputStream(用来序列化)和ObjectOutputStream(反序列化)
2.Hessian也是一个解决方案
3.protobuffer
4.thrift
咱们此处使用第一个方案,标准库自带的方案,好处:不必引入额外以来,学习成本低
遇到的并发问题。,此时写入文件之后,真实消息所在的位置,就和刚才计算的offset不匹配了!
出路:加锁
如果两个线程,是往同一个队列中写消息,此时需要阻塞等待
如果两个线程,往不同队列中写消息,此时不需要阻塞队列。(不同队列,对应不同的文件,各自写各自的,就不会产生冲突了)
实现消息文件的垃圾回收
由于当前会不停的往消息文件中写入消息,并且删除消息只是逻辑删除,这就可能导致消息文件越来越大,并且里面又包含大量无效消息
此处的垃圾回收,使用复制算法
判定,当文件中信息总数超过2000,并且有效消息的数目不足50%,就要触发垃圾回收~,就把文件中所有有效消息取出来,单独的在写入到一个新的文件中,删除旧文件,使用新文件代替
相关文章:
项目模拟实现消息队列第二天
消息应答的模式 1.自动应答: 消费者把这个消息取走了,就算是应答了(相当于没有应答) 2.手动应答: basicAck方法属于手动应答(消费者需要主动调用这个api进行应答) 小结 1.需要实现生产者,broker server,消费者这三个部分的 2.针对生产者和消费…...
MySQL OCP和Oracle OCP怎么选?
近期oracle 为庆祝 MySQL 数据库发布 30 周年,Oracle 官方推出限时福利:2025 年 4 月 20 日至 7 月 31 日期间,所有人均可免费报考 MySQL OCP(Oracle Certified Professional)认证考试(具体可查看MySQL OCP…...
SR触发器为什么能够消抖
SR触发器(Set-Reset触发器)能够用于**消抖(Debounce)**,主要是因为它的双稳态特性和对输入信号的锁定能力。机械开关(如按键、拨动开关)在闭合或断开时,由于金属触点的弹性ÿ…...
2025ISCC练武校级赛部分题解WP
Web 战胜卞相壹 <!-- 路过的酒罐王柯洁九段说: --> <!-- 会叠棋子有什么用!你得在棋盘内战胜他!我教你个定式,要一直记得!一直! --> <!-- SGF B[ae];B[ce];B[df];B[cg];B[ag];B[ai];B[ci];…...
Microsoft Azure 在印度尼西亚区域正式上线
微软正式宣布,其首个落地印度尼西亚的云区域——Indonesia Central 已全面上线并正式投入使用!这一区域精心设置了三个可用性区(Availability Zones),每个可用性区均配备独立的电源、冷却系统以及网络设施,…...
day18 python聚类分析对数据集模型性能影响
聚类后的分析:推断簇的类型 知识点回顾: 推断簇含义的2个思路:先选特征和后选特征通过可视化图形借助ai定义簇的含义科研逻辑闭环:通过精度判断特征工程价值 作业:参考示例代码对心脏病数据集采取类似操作,并且评估特征…...
vue3的新特性
vue2 data属性和方法名散落于各个位置,量大了不好找 顺序变了,script在最前面 setup vue3中不用this,setup的执行时期比beforeCreate还要早,所以不要用this setup中写代码的特点 必须要有return,才能在上面使用 什么…...
NX二次开发——BlockUI 弹出另一个BlockUI对话框
最近在研究,装配体下自动导出BOM表格中需要用到BlockUI 弹出另一个BlockUI对话框。通过对网上资料进行整理总结,具体如下: 1、明确主对话框、子对话框1和子对话框2 使用BlockUI创建.cpp和.hpp文件,dlx文件内容如下所示 主对话框…...
《Overlapping Experiment Infrastructure: More, Better, Faster》论文阅读笔记
文章目录 1 背景2 三个核心概念3 Launch层:特性发布的专用机制4 流量分发策略和条件筛选4.1 四种流量分发类型4.2 条件筛选机制 5 工具链与监控体系6 实验设计原则7 培训参考与推荐 1 背景 谷歌(Google)以数据驱动著称,几乎所有可…...
【Machine Learning Q and AI 读书笔记】- 05 利用数据减少过拟合现象
Machine Learning Q and AI 中文译名 大模型技术30讲,主要总结了大模型相关的技术要点,结合学术和工程化,对LLM从业者来说,是一份非常好的学习实践技术地图. 本文是Machine Learning Q and AI 读书笔记的第5篇,对应原…...
前端面试测试题目(一)
一、Vue的双向绑定机制(v-model底层实现原理) Vue的双向绑定核心由 响应式系统 和 指令语法糖 共同实现,具体原理如下: 响应式系统 Vue通过数据劫持和依赖收集实现数据变化到视图的同步: • 数据劫持:在Vue…...
最优化方法Python计算:无约束优化应用——线性回归分类器
一、线性回归分类器 假设样本数据为 ( x i , y i ) (\boldsymbol{x}_i, y_i) (xi,yi),其中 i 1 , 2 , … , m i 1, 2, \dots, m i1,2,…,m。标签 y i y_i yi 取值于 k k k 个整数 { 1 , 2 , … , k } \{1, 2, \dots, k\} {1,2,…,k},从而构…...
【汇正自控阀门集团】签约智橙PLM,智橙助泵阀“以国代进”
签约智橙,汇正阀门的“以国代进”举措 随着阀门市场竞争日益激烈、市场需求日益多样化,无论是出口海外、以国代进,还是进军新能源、造船、油气等投资景气的下游市场,阀门企业能否在快速迭代产品、保持技术领先的同时,…...
【macOS】iTerm2介绍
iTerm2 和 iTerm 是 macOS 上两个不同的终端模拟器,虽然名字相似,但它们是两个独立的项目,且 iTerm2 是 iTerm 的现代化继承者。以下是它们的核心区别和演进关系: 1. 历史背景 项目诞生时间状态开发者iTerm2002 年已停止维护Greg…...
2025年五一假期旅游市场新趋势:理性消费、多元场景与科技赋能
2025年五一假期,国内旅游市场再次迎来爆发式增长,官方数据显示,假期期间国内出游人次达3.14亿,游客总消费1802.69亿元。尽管数据规模亮眼,但深入分析可发现,旅游市场正经历结构性变革——消费行为趋于理性、…...
第3章 模拟法
3.1 模拟法概述 模拟法设计思想 模拟法通过将现实问题抽象成计算机可识别的符号与操作,按逻辑顺序“模拟”其过程,从而得到结果;它不依赖复杂公式或高深技巧,只需理清问题背景与实现步骤即可。 示例:鸡兔同笼问题 题…...
16.状态模式:思考与解读
原文地址:状态模式:思考与解读 更多内容请关注:深入思考与解读设计模式 引言 在开发软件系统时,特别是当对象的行为会随着状态的变化而变化时,系统往往会变得复杂。你是否遇到过这样的情况:一个对象的行为在不同的状…...
ActiveMQ 源码剖析:消息存储与通信协议实现(二)
四、KahaDB 消息存储实现细节 (一)存储原理分析 KahaDB 作为 ActiveMQ 从 5.4 版本开始的默认消息存储引擎,其基于日志文件的存储原理具有独特的设计和优势 。在 KahaDB 的存储目录(如${activemq.data}/kahadb)下&am…...
明远智睿SD2351核心板:工业AIoT时代的创新引擎
在当今工业互联网飞速发展的浪潮中,人工智能(AI)与物联网(IoT)的深度融合正以前所未有的态势重塑着传统制造业的格局。从自动化生产线的精准控制到智能仓储的高效管理,从设备运行的实时监测到产品质量的严格…...
iPhone 和 Android 在日期格式方面的区别
整篇文章由iPhone 和 Android 在日期格式方面有所不同引起,大致介绍了,两种时间标准,以及在 JavaScript 下的格式转换方法。 Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 iPhone 和 Android 在日期格式方面有所不同。其中,iPhone(iOS)使…...
使用VSCode在Windows 11上编译运行项目
使用VSCode在Windows 11上编译运行项目 VSCode是一个功能强大的跨平台代码编辑器,可以很好地支持C/C项目开发。以下是使用VSCode在Windows 11上编译运行此项目的详细步骤。 1. 安装VSCode 访问VSCode官网下载并安装VSCode安装完成后,启动VSCode 2. 安…...
边缘计算,运维架构从传统的集中式向分布式转变
在当今数字化时代,边缘计算的崛起正在改变着运维的格局。随着物联网、5G 等技术的快速发展,越来越多的数据和应用正在向边缘设备迁移,这给运维团队带来了新的挑战和机遇。 一、边缘计算崛起带来的运维挑战 边缘计算将计算和数据存储靠近数据…...
【基础篇】prometheus热更新解读
文章目录 本篇内容讲解热更新参数源码解读本篇总结本篇内容讲解 prometheus热更新源码解读 热更新参数 –web.enable-lifecycle : 代表开启热更新配置 修改配置文件发http请求# curl -X POST -vvv localhost:9090/-/reload * About to connect() to localhost port 9090 (…...
为了结合后端而学习前端的学习日志(1)——纯CSS静态卡片案例
前端设计专栏 使用纯CSS创建简洁名片卡片的学习实践 在这篇技术博客中,我将分享我的前端学习过程,如何使用纯HTML和CSS创建一个简洁美观的名片式卡片,就像我博客首页展示的那样。这种卡片设计非常适合作为个人简介、产品展示或团队成员介绍…...
汽车服务小程序功能点开发
汽车养护服务功能 智能保养预约:根据车辆品牌、型号及行驶里程,自动推荐保养项目,支持线上预约 4S 店或合作维修厂,选择服务时间与地点。故障诊断与维修:车主上传车辆故障现象,系统智能初步诊断࿰…...
SENSE2020BSI sCMOS科学级相机主要参数及应用场景
SENSE2020BSI sCMOS科学级相机是一款面向宽光谱成像需求的高性能科学成像设备,结合了背照式(Back-Side Illuminated, BSI)CMOS技术与先进信号处理算法,适用于天文观测、生物医学成像、工业检测等领域。以下是其核心特点及技术细节…...
《汽车噪声控制》复习重点
题型 选择 填空 分析 计算 第一章 噪声定义 不需要的声音,妨碍正常工作、学习、生活,危害身体健康的声音,统称为噪声 噪声污染 与大气污染、水污染并称现代社会三大公害 声波基本概念 定义 媒质质点的机械振动由近及远传播&am…...
物流无人机结构与载货设计分析!
一、物流无人机的结构与载货设计模块运行方式 1.结构设计特点 垂直起降与固定翼结合:针对复杂地形(如山区、城市)需求,采用垂直起降(VTOL)与固定翼结合的复合布局,例如“天马”H型无人机&am…...
docker创建一个centOS容器安装软件(以宝塔为例)的详细步骤
备忘:后续偶尔忘记了docker虚拟机与宿主机的端口映射关系,来这里查看即可: docker run -d \ --name baota \ --privilegedtrue \ -p 8888:8888 \ -p 8880:80 \ -p 8443:443 \ -p 8820:20 \ -p 8821:21 \ -v /home/www:/www/wwwroot \ centos…...
D盘出现不知名文件
各位大佬,电脑D盘去年还干干净净的,后来突然就出现了所圈部分的几个不知名文件,请问这是什么东西?是否可以删除?...
Rust 中 Arc 的深度分析:从原理到性能优化实践
在 Rust 的并发编程中,Arc(Atomic Reference Counted) 是一个非常关键的智能指针类型,用于在多个线程之间共享数据的所有权。它通过原子操作维护引用计数,确保在多线程环境下安全地管理堆内存资源。然而,很…...
qsort函数
在本篇中,将深入了解qsort函数的用法。 1.qsort函数的基础知识 该函数是用来排序的,这是一个可以直接用来排序数据的库函数(#include<stdlib.h>),底层使用的是快速排序的方式。 常见的排序方式有: …...
01 一文了解大数据存储框架:数据库、数据仓库、数据集市、数据网格、数据湖、数据湖仓
1. 大数据存储框架 1.1 定义 数据库(Database):数据库是按照数据结构来组织、存储和管理数据的仓库,是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据仓库(Data Warehouseÿ…...
QT —— QWidget(2)
QT —— QWidget(2) windowTitlewindowIconQt 资源系统 (qrc 机制) 详解基本概念使用方法1. 创建 .qrc 文件 设置背景windowOpacity 我们今天继续来学习QWidget,如果大家上一次的博客还没有看过,可以点击这里: https:/…...
微信小程序预览文件 兼容性苹果
uni.request({url: url,method: GET,header: {Authorization: token,responseType: blob,},responseType: "arraybuffer",success: (res) > {uni.hideLoading()const fs wx.getFileSystemManager(); //获取全局唯一的文件管理器let index url.lastIndexOf("…...
QT:qt5调用打开exe程序并获取调用按钮控件实例2025.5.7
为实现在 VS2015 的 Qt 开发环境下打开外部 exe,列出其界面按钮控件的序号与文本名,然后点击包含特定文本的按钮控件。以下是更新后的代码: #include <QCoreApplication> #include <QProcess> #include <QDebug> #include…...
Flink + Kafka 数据血缘追踪与审计机制实战
一、引言 在实时数据系统中,“我的数据从哪来?去往何处?” 是业务方最关心的问题之一。 尤其在以下场景下: 📉 金融风控:模型出现预警,需回溯数据源链路。 🧾 合规审计:监管要求提供数据全流程路径。 🛠 运维排查:Kafka Topic 数据乱序或错发后快速定位来源。 …...
【图书管理系统】详细讲解用户登录:后端代码实现及讲解、前端代码讲解
1. 约定前后端交互接口 [请求] /user/login [参数] userName&password [响应] 登录成功返回–true;登录失败返回–false 2. 后端代码 2.1 后端代码的逻辑 Controller层: (1)从请求和参数可以得出,前端通过127.0.…...
uni-app实现完成任务解锁拼图功能
界面如下 代码如下 <template><view class"puzzle-container"><view class"puzzle-title">任务进度 {{completedCount}}/{{totalPieces}}</view><view class"puzzle-grid"><viewv-for"(piece, index) in…...
鸿蒙开发——1.ArkTS声明式开发(UI范式基本语法)
鸿蒙开发——1、ArkTS声明式开发:UI范式基本语法 [TOC](鸿蒙开发——1、ArkTS声明式开发:UI范式基本语法)一、ArkTS的基本组成(1)核心概念(像贴标签一样控制组件)(2)基础工具包(现成的积木块&am…...
ChatGPT-4o:临床医学科研与工作的创新引擎
技术点目录 2024大语言模型最新进展介绍ChatGPT-4o提示词使用方法与技巧ChatGPT-4o助力临床医学日常生活、学习与工作ChatGPT-4o助力临床医学课题申报、论文选题及实验方案设计ChatGPT-4o助力信息检索、总结分析、论文写作与投稿、专利idea构思与交底书的撰写ChatGPT-4o助力临床…...
Excel点击单元格内容消失
Excel点击单元格内容消失 前言一、原因说明二、解决方案1.菜单栏中找到“审阅”,选择“撤销工作表保护”2.输入密码3.解除成功 前言 Excel想要编辑单元格内容时,无论是单击还是双击单元格内容都莫名其妙的消失了 一、原因说明 单击或者双击Excel中单元…...
单片机-STM32部分:7、GPIO输入 按键
飞书文档https://x509p6c8to.feishu.cn/wiki/RtuVw6GgZiuwyBkxmdDcdsAFnKk 根据原理图,找到KEY1对应的PC3 找到CubeMX中的PC3,设置为GPIO_Input 右击,修改引脚名称为KEY1 或者在GPIO配置属性中修改 引脚模式:这里默认为输入模式&…...
从创意到变现:独立创造者的破局之路——解码《Make:独立创造者手册》
在创业浪潮奔涌的时代,独立创造者正成为商业领域中一股不可忽视的新兴力量。他们凭借对创新的执着、对问题的敏锐洞察,以及对自由创业模式的追求,试图在竞争激烈的市场中开辟属于自己的天地。《Make:独立创造者手册》如同一位经验丰富的创业导师,为独立创造者们提供了一套…...
14前端项目----登录/注册
登录/注册 assets用户注册模块登录模块tokenlogin组件业务token校验获取用户登录信息 登录成功---Header组件 assets assets文件夹:一般也是放置静态资源–>一般是多个组件共用的静态资源 webpack 会把 assests 静态资源当作是一个模块,打包到 js 文件里,不存在a…...
【FreeRTOS-消息队列】
参照正点原子以及以下gitee笔记整理本博客,并将实验结果附在文末。 https://gitee.com/xrbin/FreeRTOS_learning/tree/master 一、队列简介 1、FreeRTOS中的消息队列是什么 答:消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传…...
二叉查找树,平衡二叉树(AVL),b树,b+树,红黑树
🌲 一、二叉查找树(Binary Search Tree,简称 BST) 📌 定义 二叉查找树是一棵二叉树,它满足这样的特性: 每个节点最多有两个子节点(左、右)对于任意一个节点: 它左子树的所有节点值都比它小它右子树的所有节点值都比它大📈 举个例子 复制代码 10/ \5 20/ \ …...
可执行文件格式(ELF格式)以及进程地址空间第二讲【Linux操作系统】
文章目录 可执行文件的格式可执行文件中存储了什么可执行文件中的虚拟地址以及加载 进程地址空间第二讲CPU如何执行进程的代码再谈进程地址空间的区域划分 可执行文件的格式 源文件被编译器编译之后的可执行文件,并不是只有代码和数据,还有一定的格式&a…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】8.1 基础图表绘制(折线图/柱状图/散点图)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL数据分析实战:基础图表绘制(折线图/柱状图/散点图)8.1 基础图表绘制8.1.1 折线图:展现数据趋势数据准备图表绘制步…...
Yii2.0 模型规则(rules)详解
一、基本语法结构 public function rules() {return [// 规则1[[attribute1, attribute2], validator, options > value, ...],// 规则2[attribute, validator, options > value, ...],// 规则3...]; }二、规则类型分类 1、核心验证器(内置验证器࿰…...