Jetcache踩坑合集

写在前面

本文主要是记录个人在使用jetcache时遇到的一些问题以及相应的解决方案,次之是将这些问题和解决方案发布到互联网中希望能帮助到一些人,如果觉得文章写得还不错,可以点赞收藏以鼓励我继续更新博客,这将对我非常重要。

流水账子标题中重复带上jetcache关键字主要是为了提高搜索的准确性,本身文章上下文已足够表达含义,但是为了优化搜索情况特意加上的。

踩坑流水账

jetcache默认返回值为null时候,不会缓存

这个是jetcache的默认策略,我之所以遇到这个问题是我自己写的测试代码时直接返回了null,我误认为是我spring aop配置有问题,导致缓存没有生效,实则是jetcache默认策略。

com.alicp.jetcache.anno.Cached注解中有一个属性cacheNullValue,默认值为false,表示不缓存空值。

jetcache不支持模糊清空缓存

这点其实在GitHub issue清单中有好几个issue 都是与这个问题相关的,如果你也是从Spring Cache转到jetcache,由于缺少模糊清空缓存,会导致整个系统原有的实现都必须调整。

这个特性主要影响到缓存的数据是一个列表或者是一整颗树的情况,当列表或树中部分值更新以后,这个列表的缓存或树的缓存没有办法更新。

jetcache多节点缓存清空需要先有@Cached注册

阅读全文 »

2024年7月5日更新:

  1. 原帖在这里:https://baofeidyz.hashnode.dev/apple-music
  2. 调整部分过时的内容,新增了iCloud云盘链接(阿里云盘不让分享apk文件,所以先暂时拿iCloud云盘用一下)

2023年10月12日更新:
很抱歉,就目前来看苹果已经在逐步收紧了,如果还没上车的朋友请尽快上车了,后期可能注册和订阅都将变的越来越困难,详细操作步骤我已经单独更新了一篇博客,请务必查看!链接:《新注册土耳其Apple ID订阅Apple Music详细操作步骤,新手一定要看!》

2023年7月23日更新:
很抱歉,就我今天测试结果来看,至少从今天(也许很早之前)苹果已经改为免费一个月了,博客原标题中的“-免费六个月”部分已修改为“每月最低不到2元”(目前家庭订阅是29.99里拉,约等于8元,家庭订阅最多可以六人,平均算下来人均不到1.4元)。此外,部分平台由于文章无法再编辑,已尽量通过评论区的方式告知,希望您理解。

阅读全文 »

mat用小内存解析超大堆快照的可行方法

写在前面的话1:服务器上的堆大小已经远超过我开发机的内存大小了,如果直接使用mat客户端来分析很快就会出现OOM的问题,这篇博客一定程度上可以解决这个问题

写在前面的话2:大部分同学一直都在使用mat的gui来做分析,但其实mat的gui只是增加来一个html预览功能,我们可以利用mat命令直接生成html,甚至我们还可以挂载成在线服务,以供其他人浏览,非常赞

命令

1
2
3
/Applications/mat.app/Contents/Eclipse/ParseHeapDump.sh ~/Downloads/java_pidxxx.hprof org.eclipse.mat.api:suspects
/Applications/mat.app/Contents/Eclipse/ParseHeapDump.sh ~/Downloads/java_pidxxx.hprof org.eclipse.mat.api:overview
/Applications/mat.app/Contents/Eclipse/ParseHeapDump.sh ~/Downloads/java_pidxxx.hprof org.eclipse.mat.api:top_components
阅读全文 »

解决macOS IntelliJ IDEA 卡顿问题

写在前面的话1:我在撰写这篇博客时候,所用的IntelliJ IDEA版本是IntelliJ IDEA 2022.3.3 (Ultimate Edition),你需要知道可能对于不同的IntelliJ IDEA版本会有一定的差异

写在前面的话2:如果我这篇博客可以帮助到你,请给我一个免费的赞和收藏,谢谢

问题描述

我遇到的卡顿问题主要体现在编辑代码时,输入中文时,cpu使用率飙升到100%,并且中文已经在键盘中打完了,但是展示到IntelliJ IDEA页面上还需要5秒以上,已经卡到没办法做研发工作了。

一些相关的因素

在特别卡的时候,我有更换过一次项目。我在做这个项目之前,虽然也卡,但是不会类似于这个项目这么卡。
但同时我在这期间有升级过macOS的系统版本和IntelliJ IDEA的版本,变量因素很多,加大了问题排查定位的难度。

排查思路

我以前很喜欢写流水账,但是这次来来回回花了我好几个月才解决,所以我已经回忆不起来我到底是怎么一步一步排查的了,我尝试写一些我还能想起来的作为排查思路

检查内存、硬盘、cpu使用率

这是我最开始的考虑,macOS上有一个系统应用,叫“活动监视器“,这里面可以比较清晰的看到IntelliJ IDEA的cpu、内存、硬盘、网络的使用情况,当然你也可以在终端中使用top或者htop来确认。
通过我的观察,我发现我输入中文的时候,我的八个很容易就达到了100%,CPU使用率轻轻松松超过400%

如果你使用IntelliJ IDEA开发程序,那么Java应用的卡顿问题如何处理,你应该是比较熟悉的,对吧?但是如果没有源码,我们直接去查IntelliJ IDEA的线程信息其实帮助也不是很大,我稍微花了一点时间在网络上翻找了一些帖子。

IntelliJ IDEA其实是有自己的分析工具,其位置在于【顶栏->Help->Diagnostic Tools->Activity Monitor】

说个题外话,不建议安装IntelliJ IDEA的中文语言包,因为互联网上大量文档主要还是用英文来写的,我在解决这个IntelliJ IDEA卡顿问题的时候也在IntelliJ IDEA自己的论坛看了很多帖子,如果你长期使用中文语言包,对于一些词汇太陌生会导致自己处理问题比较麻烦。

从这个工具里面咱们就可以看到具体什么进程导致CPU的高占用,对于进程名不熟悉的,借助于Google也可以很快了解具体是做什么的。

不同的使用场景下,会存在不同的原因,并且因为IntelliJ IDEA还支持了插件,所以导致卡顿的原因更是不计其数,但只要你懂得如何去排查问题,这个事儿就变得没有那么困难了。

一个一个的禁用插件来排查

这个方法是很多人都有提到的,并且在实际应用上是真的有效果!如果你安装的插件比较多,那么请一个一个的disable掉,利用排查法找到具体是哪个插件所导致的,插件越多理论上时间会比较长,你也可以选择以五个为单位快速定位一个大致的范围。

常见的一些解决方案

修改IntelliJ IDEA的内存

放到第一位肯定是相当重要的,但IntelliJ IDEA在扫描、编译、处理各类问题的时候,确实是需要很大内存的。我个人目前是给到了6G。

网上有各种各样教你修改配置文件的方法,但是IntelliJ IDEA自己就提供了这样的功能,你直接需要点击【顶栏->Help->Edit Custom VM Options】就可以在IntelliJ IDEA编辑框打开一个以.vmoptions结尾的文件。如果之前已经有-Xmx属性那么就改一下,如果没有就新起一行加上即可,如果你想和我一样配置成6G,那么修改属性值应该是-Xmx6144m即可,这表示最小堆内存位6G

使用更高版本的jdk以及IntelliJ IDEA的新界面

java 原来使用的是OpenGL,但是macOS从Mojave开始启用了新的Metal框架,jetbrains对此也是早早布局,我这里放两个链接供你了解更多的内容:

  1. Metal for IntelliJ Platform | The JetBrains Platform Blog
  2. https://youtrack.jetbrains.com/issue/JBR-745/Improve-java2d-rendering-performance-on-macOS-by-using-Metal-framework

当你的分辨率非常高,或者是显示器非常的多时,渲染的压力就会越大,cpu就会飙升,IntelliJ IDEA也会变卡。截止目前IntelliJ IDEA已经发布了New UI,虽然被标记为Beta,但从我个人使用情况来说,我还没遇到过问题。反而新版本的UI更让我聚焦我的开发工作,用了几天很快就适应了。
简单来说,你需要jre 17及以上版本且IntelliJ IDEA版本保持为最新版即可。

插件导致的卡顿

git插件

排查思路很简单,就是我在上一个章节中提到的一个一个的禁用插件来排查,如果你已经确定是IntelliJ IDEA的git插件导致的卡顿,但是你又想像我一样继续使用这个git插件,那么应该怎么解决呢?

这个问题我是偶然一次浏览到的,macOS 下 Intellij IDEA 变得特别卡该如何解决? - 知乎 其中第一个高赞回答就是解决方法,其实就是.gitignore文件设置不合理,导致git插件索引了大量无意义的文件,我目前维护的这个项目git下同时存放了多个子系统的代码,文件数量和层级都非常的夸张。

我在我本地修改了.gitignore文件的内容,去掉了一些我不需要管的文件夹后,git插件导致的IntelliJ IDEA卡顿问题就迎刃而解了。

其他插件

  • 如果你确定你不需要,比如alibaba的p3c检查,或者是一些其他的检查扫描类插件,可以disable的都尽量卸载即可。
  • 对于一些比较小众的插件,你可以尝试通过GitHub直接联系作者以寻求解决方案。

与此同时,这还是一份我个人重装macOS系统的备忘录😁

工具类

软件名称 软件用途 价格 推荐下载方式
homebrew macOS包管理工具 免费 终端执行:/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”
mos 用于鼠标切换上下滚动的顺序,以及鼠标平滑滚动 免费 brew install mos
AppCleaner 卸载app,并且删掉相关联的文件 免费 brew install appcleaner
numbers 替代Excel 免费 app store
keynote 替代PowerPoint 免费 app store
pages 替代word 免费 app store
chrome浏览器 上网、开发调试 免费 https://google.cn/chrome
sinology drive client 群晖文件同步工具 免费 Synology Drive
snipaste 截图、贴图工具 基本版免费(高级版macOS还没上) brew install snipaste
mircsoft remote windows操作系统远程桌面工具 免费 美区app store
infuse 一个跨iOS iPadOS macOS tvos,带资源刮削的播放器 x刀/年 美区app store
Obisidian markdown笔记软件 免费(同步服务收费) brew install Obisidian
marktext markdown编辑软件,操作表格的时候会比Obisidian好用很多很多,可以搭配使用 免费 brew install mark-text
ForkLift ftp、sftp软件 收费,买断制 brew install –cask forklift
Maccy 剪贴板记录软件 免费 brew install maccy
MonitorContror 显示器亮度控制软件 免费 brew install –cask monitorcontrol
Itsycal 菜单栏中的日期选起控件 免费 brew install Itsycal
omnidisksweeper 磁盘清理工具 免费 brew install –cask omnidisksweeper
vmware-fusion vmware虚拟机免费版 个人免费(需要自己在官网申请license) brew install –cask vmware-fusion

通讯软件

软件名称 软件用途 价格 推荐安装方式
telegram 聊天 免费(高级会员需订阅) app store(有沙盒机制)
foxmail 管理企业邮件 免费 brew install –cask foxmail

编程软件

软件名称 软件用途 价格 推荐安装方式
drawio UML绘图工具 免费 brew install drawio
vscode 文本编译器(也可以是IDE) 免费 brew install –cask visual-studio-code
docker 容器化工具 免费 brew install –cask docker
nginx web、代理服务等 免费 brew install nginx
mat java堆内存分析工具 免费 brew install mat
jmeter 并发测试工具 免费 brew install jmeter
node 开发环境 免费 brew install node
git 代码分支管理工具 免费 brew install git
sdkman 各类SDK管理工具 免费 curl -s “https://get.sdkman.io

Java云原生开发初体验报告

背景

前段时间在考虑做一款小工具,功能非常简单,调用多个HTTP接口,分析处理返回的数据,生成Excel文件即可。 为了尽量的让这个工具的实用性更高,我首先想到Java的云原生开发方案,直接构建为可执行文件,不需要使用的人再去安装jre运行环境,或者是带着庞大的jre文件发出。再者,我也想试试Java的云原生方案到底好不好用。

技术选型

因为一直在使用Spring开发业务,所以我这次直接使用了Spring Native

开发过程

注:均基于 macOS

开发环境安装

Spring官网的文章写的非常好,直接参考官文就可以了。Spring官方文档 我选择安装了sdk man,然后

1
sdk install java 22.1.r11-nik

剩下的就是直接用spring native创建一个项目就可以了,这个非常简单。

编译构建

  1. 如果你用了阿里云的maven仓库,请记得切换成apache的原库

  2. macOS默认mvn命令指定的jdk版本可能不是你新安装的GraalVM(像我本地就有七八个不同的JDK版本),会出现一些编译错误,那么你需要创建~/.mavenrc文件

1
2
// 路径记得自己改成正确的
export JAVA_HOME=/Users/baofeidyz/.sdkman/candidates/java/current

报错集锦

报错1

1
2
3
gu install native-image
Downloading: Component catalog from download.bell-sw.com
Error: Unknown component: native-image

在高版本里面,这个native-image好像不需要手动安装了(也有可能是我之前安装过)Install fails in 19.2.0 with gu · Issue #1665 · oracle/graal · GitHub 然后我直接运行了一下native-image发现已经有了

报错2 反射错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.baofeidyz.XXXDTO` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: java.util.ArrayList[0])
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1904)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1349)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:351)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:184)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:355)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4650)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2856)
有省略部分堆栈

这个报错只有在GraalVM下运行时才会出现,我最开始以为是因为我用了lombok然后导致的编译问题,同时我也有注意到,Spring Native本身是直接带了lombok的,我觉得不太可能吧。 但是我还是尝试去掉了lombok,当然并没有什么用。

然后我又开始在网上寻找一些蛛丝马迹,看看有没有其他人也遇到了类似的问题。但是Java Native问题的搜索真的是非常难找,因为这类问题有可能因为其他的原因也会出现,并且由于Spring Native使用人非常的少,你很难在Google的结果中找到真正的答案。我也尝试使用site:github.com再去Google搜索,仍没有找到答案。 我甚至都想去提issue了 😂 GitHub - graalvm/native-build-tools: Native-image plugins for various build tools

我后来咨询了一位做过Spring Native开发的朋友,他告诉我,可能是因为反射导致的,需要增加配置。 我顺着这位朋友的思路,去看了一下反射配置的问题,正好在这篇文章中给出了一个示例

1
2
3
@TypeHint(types = Data.class, typeNames = "com.example.webclient.Data$SuperHero") 
@SpringBootApplication
public class SampleApplication { // ... }

我顺着这个例子,修改了一下代码

1
2
3
4
5
@TypeHint(types = XXXDTO.class, typeNames = "com.baofeidyz.XXXDTO")  
@SpringBootApplication
public class MySpringNativeApplication {
// ...
}

确实解决了这个jackson反序列化导致的错误,但我又遇到了新的错误。

报错3 缺少字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java.nio.charset.UnsupportedCharsetException: CP1252
at java.nio.charset.Charset.forName(Charset.java:529)
at org.apache.poi.util.LocaleUtil.<clinit>(LocaleUtil.java:56)
at org.apache.poi.ss.usermodel.DataFormatter.<init>(DataFormatter.java:242)
at org.apache.poi.ss.usermodel.DataFormatter.<init>(DataFormatter.java:233)
at org.apache.poi.ss.formula.functions.TextFunction.<clinit>(TextFunction.java:33)
at org.apache.poi.ss.formula.atp.AnalysisToolPak.createFunctionsMap(AnalysisToolPak.java:82)
at org.apache.poi.ss.formula.atp.AnalysisToolPak.<init>(AnalysisToolPak.java:47)
at org.apache.poi.ss.formula.atp.AnalysisToolPak.<clinit>(AnalysisToolPak.java:33)
at org.apache.poi.ss.formula.udf.AggregatingUDFFinder.<clinit>(AggregatingUDFFinder.java:35)
at java.lang.Class.ensureInitialized(DynamicHub.java:518)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:155) ~[na:na]
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:226) ~[na:na]
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:214) ~[na:na]
// 有省略堆栈信息

这个看起来像是poi在操作的时候,遇到了一个chartset问题,spring有一个专门的仓库我在这个仓库里面找到了这个issue,我看到一个人也遇到了这个charset的问题,但是他是mysql的时候遇到的,他提到加了一个参数用于解决这个问题。 紧接着,我又找到了几个issue:

了解到说,需要在native-image编译的时候,增加一个AddAllCharsets参数 但是我是使用的spring native的maven插件,我的构建命令是mvn -Pnative,我并没有直接使用native-image,我不知道怎么增加这个参数才是对的。 此外,我还看了两份文档:

终于,我知道如何在Spring Native中增加这个AddAllCharsets参数了 😄

1
2
3
4
5
6
7
@TypeHint(types = XXXDTO.class, typeNames = "com.baofeidyz.XXXDTO")  
// 👇 下面这行代码就解决了我的问题
@NativeHint(options = "-H:+AddAllCharsets")
@SpringBootApplication
public class MySpringNativeApplication {
// ...
}

最佳实践就是加一个@NativeHint(options = "-H:+AddAllCharsets") 当然不可能这么顺利的,很快我又遇到了新的报错

错误4 POI的resource文件未加载

1
2
3
4
5
6
7
8
9
10
11
12
org.apache.xmlbeans.SchemaTypeLoaderException: XML-BEANS compiled schema: Could not locate compiled schema resource org/apache/poi/schemas/ooxml/system/ooxml/index.xsb (org.apache.poi.schemas.ooxml.system.ooxml.index) - code 0
at org.apache.xmlbeans.impl.schema.XsbReader.<init>(XsbReader.java:63)
at org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.initFromHeader(SchemaTypeSystemImpl.java:235)
at org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.<init>(SchemaTypeSystemImpl.java:201)
at org.apache.poi.schemas.ooxml.system.ooxml.TypeSystemHolder.<init>(TypeSystemHolder.java:9)
at org.apache.poi.schemas.ooxml.system.ooxml.TypeSystemHolder.<clinit>(TypeSystemHolder.java:6)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook.<clinit>(CTWorkbook.java:22)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onWorkbookCreate(XSSFWorkbook.java:475)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:232)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:226)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:214)
// 有省略

我猜测应该是因为资源没有引入导致的,所以我理解应该还是应该用spring native提供的hint去实现。我参考这个代码块 增加了一个@ResourceHint

1
2
3
4
5
6
7
@TypeHint(types = XXXDTO.class, typeNames = "com.baofeidyz.XXXDTO")  
@ResourceHint(patterns = {"(^/|[a-zA-Z])*/.+(/$)?.xsb"})
@NativeHint(options = "-H:+AddAllCharsets")
@SpringBootApplication
public class MySpringNativeApplication {
// ...
}

报错5

1
2
3
4
5
6
java.lang.ClassCastException: org.apache.xmlbeans.impl.values.XmlComplexContentImpl cannot be cast to org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onWorkbookCreate(XSSFWorkbook.java:475)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:232)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:226)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:214)
// 有省略

然后我在GraalVM的issue清单中找到了这个issue:Getting following error while generating excel file using native image. · Issue #1929 · oracle/graal · GitHub 基本上错误信息就是一致的。 我试了一下,不行。

我感觉POI和GraalVM配合坑有点多,我不打算一个一个找了,我尝试去找一些大而全的文章,于是,我找到了这篇文章:Graalvm使用采坑 - 行万里路才能回到内心深处,读万卷书才能看得清皓月繁星

可惜还是失败了,我感觉算了吧,POI和GraalVM的路还很长哦…

一些思考

  1. 对于这种POI组件的问题,处理起来确实很难。我查了GraalVM的ISSUE清单,5.0之前的POI确实是有一些问题,但与此同时GraalVM可能需要大量的构建参数去配置,然后Spring Native又在其中转了一次。也就是说,我需要知道这个问题不是POI导致的,然后去看native-image对应的解决方案(配置参数)是什么,然后再转成Spring Native的hints。如果我不能确定这个问题是不是POI导致的,我连提ISSUE给谁都不清楚,如果自己尝试去排查编译问题,这就会进入一个更深的坑。

  2. 我建议如果Spring Native example下找不到对应的例子之前,不要去趟这个浑水,整个开发过程非常阻塞,问题很难说真正的解决完。

  3. Java云原生的路确实很难走,不管是GraalVM去适配组件,还是组件去适配GraalVM,整个适配时间会拉得很长很长。

  4. GraalVM编译时间很长,我的项目并不大,4核8线程,16G内存,但是每次都需要大概3分钟左右,并且编译的时候,CPU使用率一直都很高。

后续

我后来用GO重写了整个程序,这是我第一次用GO,从0开始学,大概花了20个小时就写完了,并且我还用了协程并发,处理了一些线程安全的问题。相比之下,Spring Native至少花了我四倍的时间,并且没有做完。 GO编译速度非常快,我交叉编译linux或windows也才10s,CPU使用率也不高,相比之下,GO做这类小工具的云原生开发真的是非常好用。

所以我在怀疑,Java云原生是否真的有意义?希望十年后,能被打脸。

以上就是我Java云原生的初步体验报告,如果对你有一点点帮助,希望可以给我的文章点个赞和收藏。

NanoPi R2S 软路由折腾记

😩 问题多多

最开始用的是YouTuber 洋葱提供的固件,但是存在一些问题:

  1. TF卡的空间没有挂载完(8G的卡,只用到了1G左右),自己用fdisk挂载逻辑分区报错;
  2. 修改docker默认存储位置后,镜像依赖的一些程序无法使用,如curl等;
  3. 直接opkg install安装固件总会出一些莫名其妙的依赖问题,opkg update也好,还是直接ipk安装,都会遇到很多奇奇怪怪的问题;

🧐 有机会?

接着,我就去openwrt官网找了镜像,但无论是用工具balenaEther刷入,还是使用dd命令写入。当在TF卡插回R2S时,SYS灯一直红色长亮,wan和lan的灯无任何响应。
由于R2S本身还有挑卡的毛病,不太确定是不是镜像本身存在问题;

😋 解决啦~

后面意外发现其实友善也有自己的官网,在其wiki上找到了镜像下载地址
下载刷入以后,正常启动。

我用的是balenaEther,但使用dd应该也是可行的

docker也可正常使用。当然还是遇到了一些小问题。

🐛 一些小问题

openclash订阅更新一直失败

安装好openclash插件以后,在更新订阅时,一直提示失败。

DNS无法解析

常见DNS无法解析,直接写到etc/hosts,使用ping或者nslookup命令验证解决

curl命令缺少依赖文件

openclash下载文件也是依赖于wget或者curl之类命令,我ssh连接到路由器以后,测试了一下这两个命令是否可正常下载文件,结果到curl时,发现缺少了部分so依赖文件,使用opkg install安装对应的包就解决了。
参考:libwolfssl5.2.0.99a5b54a_5.2.0-stable-2_x86_64.ipk OpenWrt 21.02 Download

🥶 继续折腾HASS

未完待续…

Docker容器一启动就挂,要怎么排查?

1. 分析镜像信息

通过

1
docker inspect 镜像ID

可以查看当前镜像的属性信息,那么我们重点需要关注的是Entrypoint这个属性的信息。
关于entrypoint是什么,你可以参考Dockerfile reference | Docker Documentation

我这里获取到的Entrypoint信息如下:

1
2
3
"Entrypoint": [
"/docker-entrypoint.sh"
],

这个Entrypoint可以说是非常的简单,但是又非常的复杂。
简单在于就一行,是直接去执行/docker-entrypoint.sh这个脚本,但是复杂在于我们并不能直接看到这个docker-entrypoint.sh的内容。

2. 分析Entrypoint

一般来说,我们有几种方法可以看到这个/docker-entrypoint.sh文件:

  1. 挂载:通过docker run -v将这个目录挂载到宿主机上,就算这个容器一启动就死,我们也不用担心拿不到文件;
  2. 交互命令(这个词是我自己想的,可能不是很准确):通过docker run -it 镜像ID sh -c "cat /docker-entrypoint.sh"去查看内容。这个方法其实还是需要容器启动的,如果是启动立刻挂的情况,这个方法应该是会失效的;
  3. 跳过entrypoint:通过`docker run –entrypoint sh 镜像ID -c “cat /docker-entrypoint.sh”,即可覆盖镜像中的entrypoint,覆盖以后,容器并没有去运行entrypoint脚本,所以也就不会挂了。

3. 覆盖entrypoint

既然都可以覆盖entrypoint了,那我们为啥要局限于通过交互命令去查看文件呢?

1
docker run -d --entrypoint sh 镜像ID -c "ping 127.0.0.1"

通过这个命令,给容器一个不可完成的任务,那么这个容器将一直存活。然后再通过

1
docker exec -it 容器ID sh

进入容器,岂不是美哉?

如果你的镜像比较简单,可能会没有ping命令,那么你可能需要tail或者其他命令来保证容器可长期存活

4. 手动执行entrypoint

容器不会被自动杀掉以后,我们就可以一步一步的去分析这个entrypoint到底是死在哪儿了?

这里就没有办法展开讲了,因为每个人的情况都是不同的,只要有点耐心,我相信一定是可以解决的。

Docker(K8S)环境下开启JMX远程监控

问题引入

JMX(即Java Management Extensions),如果你在网上搜索如何配置JMX,你就会看到这样的一堆配置

1
2
3
4
5
6
-Djava.rmi.server.hostname=
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.rmi.port=
-Dcom.sun.management.jmxremote.port=
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

然后你就会发现在docker下,怎么弄都不对。

JMX分析

JMX其实需要注册三个端口,其作用为:

  • 端口1: 接收注册请求,JMX客户端(如jvisualvm)在连接时,需要填写的端口号

  • 端口2: 用于远程连接,可以与端口1使用同一个端口号

  • 端口3: 用于本地连接,随机(这个端口在实际业务场景中,不需要去指定,我暂时没研究如何指定这个端口)

排坑

坑点1 JMX端口仅暴露1个

由于JMX是在远程监控的情况下是需要两个端口的,所以在Docker环境下很可能就会出现因为端口没映射全而导致的失败

解决办法也很简单,就是把端口1和端口2设置为同一个端口即可,这样也可以减少端口映射过多而产生的端口冲突

1
2
-Dcom.sun.management.jmxremote.rmi.port=8888
-Dcom.sun.management.jmxremote.port=8888

注:8888这个端口是我随便写的,在合法范围内都可以

坑点2 java.rmi.server.hostname配置导致JMX连接失败

坑点1其实在网络上已经有大把大把现成的文章了,而对于坑点2,则在于java.rmi.server.hostname这个配置。我个人认为这个是因为JMX诞生比较早,所以JMX并没有适配容器化,这就导致了第二个坑点。

java.rmi.server.hostname配置失败的体现在于,你的JMX客户端,会在连接中卡顿很久,这其实就是JMX尝试连接,但连接不上导致的。

JMX客户端根据你填写的IP和PORT去查找JMX服务,这时候你的服务端会返回这个java.rmi.server.hostnamecom.sun.management.jmxremote.rmi.port,JMX客户端再根据这两个值去连接。

那么在docker环境下,你配置的java.rmi.server.hostname很可能就配置错了,你需要保证这个java.rmi.server.hostname是客户端直接可连的,并且这个com.sun.management.jmxremote.rmi.port也是可以直接访问的。

我使用的环境是我用我的笔记本去监控运行在服务器K8S集群中的服务,这种情况下,我需要把java.rmi.server.hostname配置为这个集群所使用的映射服务IP,

如果你的映射服务IP过多,这就会很麻烦,因为每次修改java.rmi.server.hostname需要重启,而重启等同于重新部署,这就导致有可能不匹配,这个问题可能需要想办法绑定,或者自己手动用kubectl做映射

并且你还需要保证com.sun.management.jmxremote.rmi.port是映射服务所使用的端口。

创建端口映射的时候,就保证你的容器端口和映射端口得是一致的,不然JMX服务返回给JMX客户端的端口,没办法通过端口映射连接了

![在这里插入图片描述](https://img-blog.csdnimg.cn/129b48695cbd44c5a6c6d0f346c23666.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAYmFvZmVpZHl6,size_20,color_FFFFFF,t_70,g_se,x_16 align=”left”)

参考

how-to-connect-with-jmx-from-host-to-docker-container-in-docker-machine

不要直接复用其他业务的线程池

前言

最近在复查团队小伙伴的代码时发现,错误复用了一个定时触发信息同步的线程池。但他开发的代码所对应的业务场景是响应前端页面的请求。而这次的线程池复用将可能会导致系统页面“卡死”。

信息同步的线程池,其主要配置信息为:

  • corePoolSize:4
  • maximumPoolSize:8
  • keepAliveTime:30L
  • unit:TimeUnit.SECONDS
  • workQueue:new ArrayBlockingQueue<>(1000)
  • threadFactory:new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("xxx-pool-%d").build()
  • handler:new ThreadPoolExecutor.CallerRunsPolicy()

这个定时任务设定为每半个小时执行一次,当定时任务开始执行后,这个队列任务很快就会装满。

如果这个时候响应前端页面请求的线程进入,就会进行等待队列,此时可能会发生:

  1. 任务队列满,触发丢弃策略,前端页面请求被丢弃,用户拿不到的正确的数据;
  2. 任务较多,前端页面请求等待,可能会出现前端页面请求超时,系统“卡死”;

分析

存在任务优先级存在问题。页面请求的优先级应大于信息同步任务的优先级,但如果复用同一个线程池,那么在任务执行顺序上,就是先进先执行。

如果此前已经有多个信息同步任务正在等待,页面请求也必须要等到信息同步任务执行完成以后才可以去与其他线程抢占系统资源。

结论

对于一些优先级较高的任务,应当独立维护线程池。虽然在JVM中还存在线程调度问题,但至少不会一直阻塞去等待其他任务的执行。

对于一些优先级较低的定时任务,可以考虑适当复用,与此同时也需要考虑好核心线程数、最大线程数、等待队列、丢弃策略等。

很多技术解决方案都是一把双刃剑,用得好,事半功倍,用不好,系统宕机😂

0%