背景
这几天回归小型进销存系统之后,由于落下同伴太多的知识点,就想着先启动一下整个项目来操作操作。然后去学习一些新的代码、新的知识、新的解决方法。
一开始后台启动失败,定位到 elasticsearch 这一块。然后,才发现离组时间中,添加了很多新的镜像:redis、elasticsearch...
接着 docker-compose up -d 拉去镜像,但是还是报错。
自己弄半天,最后还是求助学长们才得以解决
具体解决流程
环境
mac mini m4
Docker Desktop 4.25.2
elasticsearch 8.14.3
1. 后台报错信息
截取 “Caused by” 后面的核心信息:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contactDocumentServiceImpl' defined in file
[/Users/zhangyuxuan/Desktop/code/mini-crm/api/target/classes/club/yunzhi/minicrm/service/ContactDocumentServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'contactDocumentRepository' defined in club.yunzhi.minicrm.repository.ContactDocumentRepository defined in @EnableElasticsearchRepositories declared on WebConfig: Failed to instantiate
[org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception2. 查看 docker 容器日志
发现,elasticsearch 容器根本没起来。查看 log
2025-10-13 16:09:35 # A fatal error has been detected by the Java Runtime Environment:
2025-10-13 16:09:35 #
2025-10-13 16:09:35 # SIGILL (0x4) at pc=0x0000ffff9416ee68, pid=7, tid=16
2025-10-13 16:09:35 #
2025-10-13 16:09:35 # JRE version: (22.0.1+8) (build )
2025-10-13 16:09:35 # Java VM: OpenJDK 64-Bit Server VM (22.0.1+8-16, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, serial gc, linux-aarch64)
2025-10-13 16:09:35 # Problematic frame:
2025-10-13 16:09:35 # j java.lang.System.registerNatives()V+0 java.base@22.0.1
2025-10-13 16:09:35 #
2025-10-13 16:09:35 # No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
2025-10-13 16:09:35 #
2025-10-13 16:09:35 # An error report file with more information is saved as:
2025-10-13 16:09:35 # /usr/share/elasticsearch/hs_err_pid7.log
2025-10-13 16:09:35 [0.012s][warning][os] Loading hsdis library failed
2025-10-13 16:09:35 #
2025-10-13 16:09:35 # The crash happened outside the Java Virtual Machine in native code.
2025-10-13 16:09:35 # See problematic frame for where to report the bug.从错误信息来看,这是一个 SIGILL (非法指令) 错误,通常与 CPU 架构不兼容有关
错误关键点:
SIGILL (0x4)非法指令错误linux-aarch64显示运行在ARM64架构上
可能的原因:
- CPU架构不兼容
JVM 在启动时遇到SIGILL(非法指令)信号,发生在java.lang.System.registerNatives()方法中。
使用的JDK可能与CPU的指令集不匹配 - 版本不匹配
当前的 elasticsearch 镜像与当前的电脑的架构不匹配
docker 版本
3. 逐步排错
- 查看 elasticsearch 的镜像和本机电脑的架构是否一致
但是,从 docker hub 中查看到的 8.14.3 它既支持 linux/amd64,也支持 linux/arm64
并且,docker 有 仿真机制 当拉去的镜像与计算机架构不匹配的时候。会利用 QEMU 来进行动态翻译 x86 指令 -> ARM 指令最终容器可以在ARM CPU 上运行,就像原生 x86 一样
‼️ 但是,拉下来镜像后,问题依旧存在
- 查看 Docker Desktop 的版本是否有影响
首先,可以看到当前的版本是 4.25.2。
关键背景:Elasticsearch 镜像和架构问题
同时,elasticsearch 8.14.3 官方只提供了 amd64(x86_64)架构版本,没有 arm64版本;
这意味着:
- 在 Apple Silicon 上运行它时,Docker 必须做 跨架构仿真
Elasticsearch 的底层是 Java(JVM)
- JVM 启动时会使用大量的 JIT 编译和汇编级指令
- 这些指令通常和 CPU 架构紧密绑定
➡️ 如果用QEMU 仿真 x86 -> ARM 的指令时,某些复杂的指令或 JIT 优化可能 未完全支持 或 性能极差,就可能触发 SIGILL(非法指令错误)
也就是说:
Elasticsearch 容器崩溃的根本原因是:
JVM 的 JIT 生成了 QEMU 无法正确仿真的 x86 指令
4. 解决
我们先升级一下 Docker Desktop 的版本至最新的版本。在试着去重新拉取镜像,开启容器。容器成功运行!
到此,我们就定位到了,具体的错误。
5. 看看官方怎么说
在官方文档中说明,在 Docker Desktop 4.35.0 版本之前仍存在一些小问题:Docker Desktop 对 Rosetta 的支持并不是很好 具体文档请点击查看
Docker Desktop 4.26 中对 Rosetta 有一定程度的优化。Rosetta 的性能得到了显著的提升。 具体文档请点击查看
😂 而我们出现问题的 Docker Desktop 的版本正好是它的上一个版本
浅谈 QEMU(Quick Emulator) 与 Rosetta 的区别
仿真模式
是什么?
Docker 的仿真模式(Emulation Mode)允许在不同 CPU 架构之间运行容器。
例如在 ARM 芯片上运行 x86 镜像。它底层依赖 QEMU 模拟器和 Linux 的 binfmt_misc 机制,通过 Docker Desktop 或 buildx 自动启用。开发者只需指定 --platform 参数,即可实现跨架构运行和构建。
为什么需要?
为了解决像上述遇到的这种“架构不匹配”,Docker 引入了仿真模式。
让我们可以在 ARM 上运行 x86 镜像
区别
一句话总结:QEMU 是“通用的CPU模拟器”,能让任何架构假装成另一种架构;而 Rosetta 是“苹果专用的翻译官”,只负责让 macOS 上的 Intel 应用能在苹果芯片上流畅运行。
| 维度 | 4.25 版本 4.26 | (及以上)+ Rosetta 版本 |
|---|---|---|
| 仿真机制 | QEMU | Rosetta for Linux |
| 兼容性 | 一般,JVM 类容器易崩溃 | 几乎兼容所有 x86 用户态 |
| 性能 | 慢 | 快 |
| Elasticserach 启动 | ❌ SIGILL 崩溃 | ✅ 正常运行 |
| 原理 | 动态指令仿真 | 动态指令翻译 |
拓展学习
🤔 x86 是什么?
是一种 CUP 的指令集,是一种复杂指令集。可以在一次操作中完成多个任务
🤔 arm64 是什么?
另一中指令集 -- 精简指令集。其指令集设计更简单,指令长度较短
86、amd64、arm64 三者关系 + Rosetta 如何在 Mac 上桥接
总结
Docker 的“仿真模式”其实是靠 QEMU 模拟其他 CPU 架构来实现的。
它让 ARM 用户也能运行 x86 镜像,但性能和兼容性取决于 QEMU 版本。
你的 Elasticsearch 镜像在 4.25.2 启动失败、4.48.0 成功,其根本原因就在于 QEMU 更新后改进了 JIT 仿真能力。
而相比之下,macOS 的 Rosetta 是另一种“针对应用级别”的高性能仿真,
这就是为什么 “运行 x86 的 Navicat 没问题,但运行 x86 的 Elasticsearch 容器会崩溃” 的原因。
参考文献:
dockerdocs 官方文档
dockerhub 镜像仓库
感谢
这个问题,对于我而言,我只能想到可能是elasticsearch的版本与我的电脑版本不匹配。而,由于对 Docker 等一些基础的底层逻辑的不了解,倒是我想不到问题可能出现在Docker Desktop的版本也会有影响。
在这里,要感谢刘宇轩学长和柯晓彬学长,这个问题我尝试去检索关键词以及问大模型,得到的答案都不尽如人意。最后还是靠学长们解决的。
还有需要注意的一点,对于这种环境问题,当前阶段可以尝试先自己解决。但是,一定要注意时间。发现一个小时都解决不了,应该马上求助他人!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。