加群联系作者vx:xiaoda0423
仓库地址:https://webvueblog.github.io/JavaPlusDoc/
https://1024bat.cn/
方法定义:
public void handleBiz(List<ConsumerRecord<?, ?> > records, long countTime, String timeStr)
records
:从 Kafka 消费到的消息列表。countTime
:用于记录处理耗时的初始时间戳。timeStr
:处理时间字符串,一般为当前时间格式化结果。
1. 遍历 Kafka 消息:
for (ConsumerRecord<?, ?> record : records) {
对每条消息进行业务处理。
解析 JSON 转为对象:
String value = record.value().toString();
ES 异步写入及耗时记录:
将事件信息写入 ES 异步批处理系统(可能用于后续查询或分析)并记录耗时。
设备响应处理(设备侧上报才响应):
如果设备上传带有响应信息,并且是 设备端上报,则向设备返回响应;
失败则跳过,等待下次设备重发。
判断是否重复事件(幂等性处理):
构造唯一标识,并通过 Redis 判断事件是否已经处理,防止因设备重发造成重复操作。
查询事件明细判断是否已经入库(避免重复):
如果该事件的明细数据已经存在,说明该事件已经完整处理,跳过即可。
校验用户订单:
判断当前用户是否正在进行换电操作(有进行中的订单),如果没有,调用 isReportBlChangeBat
判断是否需要响应,并跳过处理。
总结版对比:
场景/特性 | MongoDB | Elasticsearch | Cassandra |
---|---|---|---|
查询速度(通用) | ⭐⭐☆(较快) | ⭐⭐⭐(超快) | ⭐☆(一般) |
复杂查询支持 | 强(文档查询、聚合) | 强(全文检索、聚合、打分) | 弱(只支持简单查询) |
全文搜索 | 一般(支持,但不强) | 非常强(核心优势) | 弱(几乎不支持) |
实时数据分析 | 中等 | 非常快 | 较慢(非设计目的) |
批量写入性能 | 高 | 中等 | 非常高(写入利器) |
写入一致性保障 | 强(支持事务) | 弱(可配置) | 最终一致性 |
适合数据结构 | 文档型(JSON) | 文档型(JSON) | 表结构(类SQL行列结构) |
🔍 场景具体说明
1. MongoDB
优势:
查询灵活:支持字段索引、聚合查询、复杂的 JSON 条件。
写入快,查询也很快(如果有合适索引)。
可支持一定的全文搜索(用
text
索引)。
适用场景:
一般业务系统(订单、用户、配置、日志等)
高并发读写场景
不需要复杂全文检索或海量实时分析的应用
2. Elasticsearch
优势:
全文搜索王者,模糊匹配、打分、分页、排序等功能很强。
聚合分析超快,适合实时 BI、日志分析。
对查询响应时间极其敏感的系统(比如推荐系统、搜索系统)
缺点:
占用资源较多
写入延迟可能较高(非实时一致)
适用场景:
搜索引擎、日志系统(如 ELK)
实时大数据查询分析
3. Cassandra
优势:
分布式写入非常快,适合大规模并发写入。
高可用、最终一致,适合 IoT、监控指标、时序数据。
缺点:
查询支持简单:不能 LIKE、不能 JOIN、不能聚合
所有查询必须走主键或二级索引,否则很慢
适用场景:
写多读少场景:时序数据、传感器数据、指标监控
电信、银行等对可靠性要求高的系统
🚀 查询速度谁最快?
如果单纯比较查询速度:
ES最快(针对搜索/聚合查询)
MongoDB次之(针对结构化文档)
Cassandra最慢(查询能力受限)
但前提是你有没有建好索引、你的查询类型是否适配该数据库的引擎。
📌 举个实际例子:
比如你要处理“换电柜子事件日志”的查询:
需要模糊搜索、关键词查询、时间区间聚合 → 用 ES
需要存储结构化文档+偶尔查询分析 → 用 MongoDB
只需要持续高频写入(比如电量日志)+ 定期批量分析 → 用 Cassandra
写入性能横向对比总结
特性/对比点 | MongoDB | Elasticsearch | Cassandra |
---|---|---|---|
写入速度 | ⭐⭐☆(快) | ⭐⭐(中等) | ⭐⭐⭐(非常快) |
批量写入效率 | 高 | 中 | 非常高 |
并发写入能力 | 强 | 中 | 非常强(写入机器) |
写入延迟 | 低 | 可能有延迟 (刷新机制) | 极低 |
写一致性保障 | 强(可配置事务) | 最终一致(不强一致) | 最终一致(AP系统) |
写放大影响 | 少 | 大(Lucene索引刷新) | 少 |
写入容错能力 | 中 | 低 | 非常强(P2P复制架构) |
🔍 单点结论:
🥇 写入最快:Cassandra
为什么快?
写入是 append-only(顺序写入磁盘,无需更新原位置)
每次写入都是异步同步到副本(最终一致)
架构天然为高吞吐写入优化,支持百万级写入/秒
适用场景:
海量写入(IoT 数据、日志、传感器)
不要求强一致、写入后延迟可接受的系统
🥈 次快:MongoDB
写入比较快,支持:
文档级别原子性
批量插入性能高
可以通过副本集+分片扩展写入吞吐量
若开启写确认和事务,性能会略降
🥉 最慢:Elasticsearch
为什么慢?
每次写入都要刷新 Lucene 索引(涉及倒排索引、分词等操作)
写入默认不是实时,有刷盘机制(
refresh_interval
默认 1 秒)
适合“写多、查更频繁”的搜索场景,而不是极致写入
📌 真实写入场景举例
应用场景 | 推荐数据库 | 原因说明 |
---|---|---|
IoT 高频数据写入(每秒上万) | Cassandra | 最终一致性+写入并发强+分布式友好 |
业务系统记录日志、订单等 | MongoDB | 支持事务、写入快,结构灵活 |
日志分析、搜索日志系统 | Elasticsearch | 写入还可以,但为了搜索、不是写入而优化 |
🔧 额外 Tips
MongoDB 开启
writeConcern=1
(默认)写入会非常快,但牺牲一点持久性Cassandra 尽量避免读后写或更新场景(不擅长更新,适合追加写)
Elasticsearch 可以通过设置
refresh_interval=-1
临时关闭刷新,提升写入,但数据不可查询
✅ 总结:
写入速度排名(从快到慢) :
Cassandra > MongoDB > Elasticsearch
ssr 渲染时机 服务器端生成完整HTML,浏览器直接渲染,首屏速度,较快,用户可快速看到内容,Seo 友好性,高,搜索引擎可直接抓取完整内容。
React Native 端开发流程
本篇主要讲解 Taro React Native 端开发流程,React Native 开发前注意事项请看 开发前注意。
Taro3.x 跨端(h5、weapp、rn)开发可参考项目:Taro 跨平台 demo(React Native + Weapp + h5)
Taro React Native APP 开发调试工具,请查看 Taro Playground 项目。
简介[1]
Taro 移动端的开发基于 Facebook 的开源项目 React Native。选择 React 框架开发的 Taro 项目,经过适配可以编译成 React Native 的 bundle 文件,再通过对应平台的工具可编译为 Android 及 iOS APP。
开发前准备[2]
为了更顺利地进行开发,我们强烈地建议您,先对 React Native 开发进行学习。学习资料可在 React Native 中文网中找到,也可到 React Native 官网中查看。
完成基础知识的学习后,建议上手完成环境搭建,并确保能够顺利运行。环境搭建参考 React Native 中文网的文档 及 React Native 官网的文档。
开发模式[3]
Taro 开发 React Native APP,提供了两种模式:
集成模式:JS、iOS、Android 在同一仓库,通过
taro init
生成且选择 react-native 模板的项目,会采用此模式。与npx react-native init AwesomeProject
生成的项目结构基本一致。入门开发者推荐使用此模式。分离模式:JS 代码在一个仓库,iOS 和 Android 代码在另外一个仓库(也称壳工程)。JS 代码可通过
taro init
选择任意模板生成。壳工程代码可 fork Taro Native Shell 项目。
本地开发完Taro项目。想发布到H5和app端,请问是使用yarn build:h5编译成H5发布,然后使用yarn build:rn --platform ios编译成app发布吗
配置说明:
堆设置
o -Xms:初始堆大小
o -Xmx:最大堆大小
o -XX:NewSize=n:设置年轻代大小
o -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
o -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
o -XX:MaxPermSize=n:设置持久代大小收集器设置
o -XX:+UseSerialGC:设置串行收集器
o -XX:+UseParallelGC:设置并行收集器
o -XX:+UseParalledlOldGC:设置并行年老代收集器
o -XX:+UseConcMarkSweepGC:设置并发收集器垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
"并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。
(4)
参数解释:
-Xms3072m -Xmx3072m
针对JVM堆的设置,通过-Xms -Xmx限定其最小、最大值
-Xmn1024m设置年轻代大小为1024m
整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小(perm)。
-Xss768k 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-XX:PermSize=512m -XX:MaxPermSize=512m
持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4
-XX:+UseConcMarkSweepGC
CMS收集器也被称为短暂停顿并发收集器。它是对年老代进行垃圾收集的。CMS收集器通过多线程并发进行垃圾回收,尽量减少垃圾收集造成的停顿。CMS收集器对年轻代进行垃圾回收使用的算法和Parallel收集器一样。这个垃圾收集器适用于不能忍受长时间停顿要求快速响应的应用。
-XX:+UseParNewGC对年轻代采用多线程并行回收,这样收得快;
-XX:+CMSClassUnloadingEnabled
如果你启用了CMSClassUnloadingEnabled ,垃圾回收会清理持久代,移除不再使用的classes。这个参数只有在 UseConcMarkSweepGC 也启用的情况下才有用。
-XX:+DisableExplicitGC禁止System.gc(),免得程序员误调用gc方法影响性能;
-XX:+UseCMSInitiatingOccupancyOnly
标志来命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期。而是,当该标志被开启时,JVM通过CMSInitiatingOccupancyFraction的值进行每一次CMS收集,而不仅仅是第一次。然而,请记住大多数情况下,JVM比我们自己能作出更好的垃圾收集决策。因此,只有当我们充足的理由(比如测试)并且对应用程序产生的对象的生命周期有深刻的认知时,才应该使用该标志。
-XX:CMSInitiatingOccupancyFraction=68
默认CMS是在tenured generation(年老代)占满68%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值;
-XX:+UseParNewGC:对年轻代采用多线程并行回收,这样收得快;
-XX:HeapDumpPath
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:/usr/aaa/dump/heap_trace.txt
上面的的参数打Heap Dump信息
" -XX:+HeapDumpOnOutOfMemoryError
此参数可以控制OutOfMemoryError时打印堆的信息
cms的概念:
CMS收集器也被称为短暂停顿并发收集器。它是对年老代进行垃圾收集的。CMS收集器通过多线程并发进行垃圾回收,尽量减少垃圾收集造成的停顿。CMS收集器对年轻代进行垃圾回收使用的算法和Parallel收集器一样。这个垃圾收集器适用于不能忍受长时间停顿要求快速响应的应用。CMS采用了多种方式尽可能降低GC的暂停时间,减少用户程序停顿。停顿时间降低的同时牺牲了CPU吞吐量 。这是在停顿时间和性能间做出的取舍,可以简单理解为"空间(性能)"换时间。
JVM(Java Virtual Machine)监控是对Java应用程序运行时的性能、资源使用情况、垃圾回收(GC)、线程活动等进行观察和分析的过程。常用于诊断性能瓶颈、内存泄漏、线程死锁等问题。
下面是常见的JVM监控方法与工具:
一、常见监控指标
堆内存使用情况(Heap Memory Usage)
非堆内存(Metaspace, Code Cache等)
GC次数和时间
线程数和线程状态
类加载数量
CPU使用率
磁盘I/O和网络I/O
二、常用监控工具
1. JConsole
JDK自带的图形化工具。
启动:
jconsole
功能:查看内存、线程、类加载、GC等信息。
2. VisualVM
比JConsole更强大,支持插件。
启动:
jvisualvm
支持远程监控、Heap Dump分析、CPU/Memory Profiler。
3. jstat
命令行工具,监控JVM性能。
示例:
jstat -gc <pid> 1000
用于实时查看GC行为、类装载信息等。
4. jstack
打印线程栈信息。
示例:
jstack <pid>
常用于分析线程死锁、阻塞等问题。
5. jmap
查看堆内存使用情况、生成heap dump。
示例:
jmap -heap <pid>
,jmap -dump:live,format=b,file=heap.hprof <pid>
6. Java Flight Recorder (JFR) & Mission Control
JDK内置的高性能监控工具。
适合线上生产环境,开销小。
用JMC打开
.jfr
文件进行分析。
7. Prometheus + Grafana + JMX Exporter
适合微服务、分布式架构。
JMX Exporter以HTTP方式暴露JVM指标,Prometheus收集,Grafana可视化展示。
三、在线生产监控建议
开启JMX端口
允许远程连接JConsole、VisualVM、JMC。定期Dump分析(如OOM后)
使用-XX:+HeapDumpOnOutOfMemoryError
和-XX:HeapDumpPath=/path/to/heapdump.hprof
监控报警机制
比如:堆内存使用率超过80%报警、Full GC频繁报警等。
==== Memory Usage ====
Heap Memory: init = 532676608(520192K) used = 45293464(44231K) committed = 510656512(498688K) max = 7572291584(7394816K)
Non-Heap Memory: init = 2555904(2496K) used = 14640968(14297K) committed = 15138816(14784K) max = -1(-1K)==== Garbage Collectors ====
Name: PS Scavenge
Collection Count: 0
Collection Time: 0ms
Name: PS MarkSweep
Collection Count: 0
Collection Time: 0ms==== Threads ====
Live Threads: 6
Peak Threads: 6
Total Started Threads: 6==== JVM Runtime Info ====
Uptime: 1072ms
JVM Name: Java HotSpot(TM) 64-Bit Server VM
JVM Vendor: Oracle Corporation
JVM Version: 25.351-b10
1. 🧾 方法区(Method Area)
作用:用于存储类的结构信息,如类名、访问修饰符、字段、方法、常量池、静态变量、JIT 编译后的代码等。
特点:
所有线程共享
也称为 “永久代(PermGen)”(JDK 8 之前)或 “元空间(Metaspace)”(JDK 8 之后)
2. 🛏️ 堆(Heap)
作用:存储所有对象实例、数组。是垃圾回收器的主要管理区域。
特点:
新生代进一步细分为 Eden 区、Survivor 区(S0 和 S1)
所有线程共享
分代管理:新生代(Young Gen)、老年代(Old Gen)
GC 主要在这一区域发生
3. 🌀 虚拟机栈(JVM Stack)
作用:每个线程私有,存储方法调用的栈帧(局部变量表、操作数栈、动态链接、返回地址等)
特点:
每调用一个方法就会创建一个栈帧
栈帧中包含该方法的所有执行信息
会抛出栈溢出异常(
StackOverflowError
)
4. 🧬 本地方法栈(Native Method Stack)
作用:与 JVM Stack 类似,但专用于处理 Native 方法(用 C/C++ 写的本地方法)
特点:
每个线程私有
抛出
StackOverflowError
或OutOfMemoryError
5. 🧭 程序计数器(Program Counter Register)
作用:记录当前线程正在执行的字节码指令的地址(即程序执行位置)
特点:
每个线程私有
是唯一不会发生 OOM 的区域
参考资料
[1]
简介的直接链接: https://docs.taro.zone/docs/react-native#%E7%AE%80%E4%BB%8B
[2]开发前准备的直接链接: https://docs.taro.zone/docs/react-native#%E5%BC%80%E5%8F%91%E5%89%8D%E5%87%86%E5%A4%87
[3]开发模式的直接链接: https://docs.taro.zone/docs/react-native#%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F