使用 acme.sh 自动签发 ZeroSSL 的 ECC 证书

使用 acme.sh 自动签发 ZeroSSL 的 ECC 证书

acme.sh 使用 ACME 协议自动申请 SSL 证书,项目地址:acme.sh

环境:CentOS 8

安装 acme.sh

先安装好 curl,然后:

1
curl https://get.acme.sh | sh

该安装脚本做了几件事:

  1. 把 acme.sh 安装到了 home 目录下:~/.acme.sh/
  2. 创建了一个 bash 的 alias, 方便使用: alias acme.sh=~/.acme.sh/acme.sh
  3. 创建了 cronjob,每天 0:00 点自动检测所有的证书,如果快过期了,则会自动更新证书。

如果因为网络问题,无法连接到 https://raw.githubusercontent.com 域名,则要手动更改安装脚本内容:

1
2
3
4
5
6
7
# 下载并保存脚本
curl https://get.acme.sh -o acme_install.sh
# 更改脚本内域名,使用代理加速
sed -i 's/raw/ghproxy.com\/https:\/\/raw/g' acme_install.sh
# 安装
chmod +x acme_install.sh
./acme_install.sh
阅读更多

解决 Parallels Desktop 16 by TNT 网络初始化失败的问题

Parallels Desktop 16 “歪门邪道版” 在 macOS Big Sur 下面启动会提示:网络初始化失败(您的虚拟机将继续正常运作,但将无法连接网络。)

目前网络上的方法都是用 sudo 启动 prl_client_app 进程,但是效果并不好,而且 USB 不可以使用。

这里通过修改文件参数的方式,立即生效,完美解决!

阅读更多

使用 dockerfile-maven-plugin 插件构建并推送 Docker 镜像

这篇笔记的目标是使用本地 IDEA 编译 SpringBoot 工程为 jar 包,并且使用安装好 Docker 的远程 Linux 主机构建 Docker 镜像,Push 到阿里云的镜像托管服务。

首先需要一台安装好 Docker 的 Linux 主机或虚拟机,并且开放远程控制(见 -> 开启 Docker 的远程控制

添加环境变量

IDEA 设置里添加 Maven 环境变量,告知 Docker Host 地址,具体操作如下:

  1. 找到 Preference -> Build, Execution, Deployment -> Build Tools -> Maven -> Runner
  2. 在 Environment variables 中填写 DOCKER_HOST=tcp://xxx.xxx.xxx.xxx:2375
阅读更多

一些容易忘掉的知识点 - Java

1 Java 基础

1.1 快速失败(fail-fast)和安全失败(fail-safe)机制

快速失败(fail-fast)是 Java 集合的一种错误检测机制。

使用迭代器对集合进行遍历的时候,在多线程下操作非安全失败(fail-safe)的集合类可能就会触发 fail-fast 机制,导致抛出 ConcurrentModificationException 异常。

在单线程下,如果在遍历过程中对集合对象的内容进行了修改的话也会触发 fail-fast 机制。

例如:多线程下,如果线程 1 正在对集合进行遍历,此时线程 2 对集合进行修改(增加、删除、修改),或者线程 1 在遍历过程中对集合进行修改,都会导致线程 1 抛出 ConcurrentModificationException 异常。

原理

迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。

每当迭代器使用 hashNext ()/next () 遍历下一个元素之前,都会检测 modCount 变量是否为 expectedmodCount 值,是的话就返回遍历;否则抛出异常,终止遍历。

采用安全失败(fail-safe机制的集合容器(JUC 包下的容器),在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历,可以在多线程下并发使用,并发修改。所以,在遍历过程中对原集合所作的修改并不能被迭代器检测到,故不会抛 ConcurrentModificationException 异常。

1.2 HashMap 与 ConcurrentHashMap 对 null 值的处理问题

结论:HashMap 的 key 和 value 都可以为 null,ConcurrentHashMap 的均不可以为 null

HashTable 也是不允许 key 和 value 为空的,原因和 ConcurrentHashMap 一致

上源码!

HashMap,当 key 为 null 的时候,hash 值为 0,后续的 put 方法中也没有判断 value 是否为 null 的代码。

1
2
3
4
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

ConcurrentHashMap,key 或 value 为 null 直接抛出空指针异常!

1
2
3
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
......

这么做的原因:

会有一个问题,当通过 get(k) 获取对应的 value 时,如果获取到的是 null,无法判断它是 put(k,v) 的时候 value 为 null,还是这个 key 从来没有做过映射。

HashMap 多用于非并发场景中,可以通过 contains(key) 来做这个判断。而在多用于并发场景中的 ConcurrentHashMap 中调用 m.contains(key) 判断然后再 m.get(key) 时,m 可能已经被其他线程修改而不同了。为了避免这种二义性,ConcurrentHashMap 在设计之初就直接令 key 和 value 都不为 null。

阅读更多

使用 Docker 自建支持 DoH、DoT 的 DNS 服务器

DoH (DNS over HTTPS) 和 DoT (DNS over TLS) 有效避免了运营商的 DNS 监听和劫持,本文记录在公网搭建一个可以去广告的 DNS 服务器(借助 Adguard Home)。

前期准备

  • 公网服务器一台
  • 域名一个,并且指向该公网服务器
  • 域名指向该公网服务器,并申请好 TLS 证书(可使用 Let’s Encrypt 申请)
阅读更多