GraalVM Native Image

GraalVM 是 Oracle 开发的 JDK,本身就提供了更好性能的 JVM,GraalVM Native Image 可以通过 AOT 把 Java 代码直接编译成二进制可执行文件,编译后的二进制不再依赖 JVM,更快的启动速度,更小的运行内存,并且不会对性能有大影响。

Native Image 会执行静态分析,从应用入口(即 main)开始,找到所有会被访问的方法,并且只会编译找到的代码。完全按照 JVM 执行的逻辑去静态分析是不现实的,所以 Native Image 静态分析基于一个叫*封闭世界假设(closed-world assumption)*的约束:只考虑构建时的已知代码,不允许在运行时增加加载新代码。

下载安装 GraalVM 后你还需要安装必要的构建工具和 z-lib,例如 Ubuntu 下:

1
apt-get install build-essential zlib1g-dev
阅读全文 »

Spring Cloud Gateway

Spring Cloud Gateway 可以用来快速开发一个网关。

通过 Spring Initializr 创建一个 gateway 项目,添加依赖:GatewayConsul Discovery。网关项目有 Spring Cloud Gateway 依赖就够了,Consul Discovery 依赖后面要用到,加上这个依赖以后就需要在项目启动前启动一个 Consul Agent,详情查看上篇文章,另外我们不需要把网关注册到 Consul,所以要给 Application 类加一行注解 @EnableDiscoveryClient(autoRegister = false)

阅读全文 »

Spring Cloud Consul

Spring Boot 是用来构建应用的框架,Spring Cloud 则是基于 Spring Boot 构建云上应用的框架。在开发云上应用中,一个非常重要的场景就是服务发现和配置,Spring Cloud 框架提供了服务发现和配置管理机制,只要引入对应的组件和简单的配置,就能快速接入相应的中间件。

首先介绍的就是使用 Spring Cloud Consul 组件集成 Consul 服务发现和配置管理能力。

阅读全文 »

Java GRPC From Scratch

创建项目

直接使用 IDEA 创建一个项目,选择 Maven 构建系统,JDK 我一直用 GraalVM JDK 17。

依赖和构建插件

项目要用到的依赖有

  • 日志依赖 logback-classic,相对于 logback 和 slf4j
  • GRPC 依赖 grpc-netty、grpc-protobuf、grpc-stub
  • 以及 javax.annotation-api,GRPC 生成的代码用到了 javax 库注解,但是新版 JDK 默认不提供
  • lombok,这个依赖可以让 IDEA 自动添加

另外为了开发方便,还要在构建系统里加入自动编译 proto 文件的构建插件 protobuf-maven-plugin。

阅读全文 »

Spring 项目

哥们最近突击学习了一下 Spring 这些个东西。

Spring 提供了一个网站 Sping Initializr 用来创建初始的 Spring 项目,这里按我需求选了 Maven 和 Java 17,然后顺手添加了 3 个依赖:Spring Data JPAMySQL DriverSpring Web,依赖在项目创建后随时都能修改。点击 Generate 生成项目代码。

然后使用 IDEA 加载项目,这部分最好是能够提前配置一个镜像加速 Maven 下载依赖,配置镜像可以不用修改 Maven 自带的 settings.xml,可以在 $HOME/.m2/settings.xml 直接添加一个针对当前用户的配置文件或者在 mvn 中使用 -s 选项指定配置文件路径,这里可能需要注意的是,Maven 默认阻止 http 访问(你可以在 Maven 自带的 settings.xml 里看到相关配置),尽量使用 https 镜像仓库(或者删掉阻止规则?)。

IDEA 加载项目后可以利用自带的 Maven 执行 Package 操作,完成后会在 target 目录下两个 jar 文件。一个是默认打出来(被重命名过)的 jar.original,如果没有 spring-boot-maven-plugin,那么这个是生成的目标文件,但是这个 jar 是没办法直接通过 java -jar 运行的,它只包含了项目代码中最基本的文件,不包含运行 jar 必要的元信息和依赖,你可以通过命令查看一个 jar 包中的文件列表,例如:

1
jar tf demo-0.0.1-SNAPSHOT.jar.original

spring-boot-maven-plugin 插件会对 jar 重新打包,重新打包后的 jar 文件里包含了必要的元信息和依赖 jar 文件。直接把 jar 文件打包进 jar 的做法叫 jar in jar,其实 Maven 有插件能够搜集所有依赖并解压,然后把所有 class 文件重新打包成一个 jar,这样打包结果会更加精简,打包过程中可以做一些适当的裁剪,但是会和一些机制产生冲突(以后会解释)。

阅读全文 »

从 STAN 说起

去年本想水一篇关于 NATS JetStream 的博客,当时写了一部分,结果翻资料翻到一篇博客 淺談 NATS、STAN 和 JetStream 兩三事,把我想说的基本都提到了,所以我当时弃坑了。最近用上了 NATS 2.9 版本,所以想着把新了解到的概念和之前想聊的一些内容都整理一下。如果你对 NATS 了解不多,非常推荐先看看我前面提到的那篇文章。

在升到 NATS JetStream 之前,我一直在用 STAN(aka NATS Streaming)。STAN 是 NATS 上一代持久化方案,是一个独立的 Server,它内嵌了 NATS Server,在这之上构建了一个持久化层,并且支持集群,集群节点之间使用 Raft 算法。STAN 在使用上基本接近 NATS,但是有个别要注意的地方。

一个是客户端连接时要提供 Cluster ID 和 Client ID。可以把 NATS 抽象看作 STAN 的网络层,客户端连入的是 NATS 的网络,访问这个网络上的 STAN Server,那么连接这个网络上的 Cluster 需要说明;Client ID 必须是唯一的,STAN 用 Client ID 和 Durable Name 区分 Consumer 持久化视图。

还有一个比较重要的是断线重连问题,也是我们踩过的坑。基于前面提到的抽象理解,STAN 构建于 NATS 网络层之上,客户端实际上没有真正连接到 STAN Server,所以断线重连机制变得复杂。记得当时是阿里云网络波动,STAN 客户端集体掉线后没有恢复,造成了不小影响。后来我封装 stan.go 实现了一个支持重连的客户端,通过 SetConnectionLostHandler 在连接断开时创建新连接,并且支持在连接切换后恢复订阅。

不过这些都不重要了,STAN 已经被标记为 deprecated,只维护到 2023.6。

JetStream

JetStream 是 NATS 2.2 开始内置的持久化机制,满足 At-Least-Once 语义,也提供了一些机制支持 Exactly-Once 语义。目前发展到 2.9.15 版本,已经很好用了。

阅读全文 »

从 Linux Mint 到 Manjaro

我一个 Linux Mint 用户,怎么就变成 Manjaro 用户了呢?

自从上次装完 Linux Mint 20 Xfce 以后,我的体验还是不错的,我不需要很臃肿复杂的环境,很多软件对 Ubuntu 系发行版支持确实不错,用起来也算是没什么大问题。直到前段时间手贱安装了 TwistUI,想卸载时发现很难卸载干净,所以决(zhi)定(neng)重装系统,正好时间点在 7 月份中旬,Linux Mint 21 还没有发布,于是需求变成了换个发行版。开始的时候我打算试试 NixOS,在虚拟机上体验了一会,可惜 NixOS 不是 FHS,怕自己用得不太习惯,最后选择了 Manjaro。

阅读全文 »

更新 K8s 对象

在 K8s 更新资源操作有两种形式:Replace 和 Patch。

Replace 形式主要用于替换对象 spec,这是一个 read-then-write 操作,即你要先从 K8s 获取对象,修改 spec,再提交更新。这个过程中对象其他字段不需要特意维护,提交的 apiVersionkindmetadata 中提供的信息会用于确定对象,而 status 则会被 K8s 忽略(如果需要更新 status,需要用专用的操作)。

在对象 metadata 中有一个 resourceVersion 字段,用来追踪持久化对象的变动,每次持久化对象发生变化时 resourceVersion 都会改变。Replace 隐含的竞争策略乐观锁就是依靠这个字段实现的,当操作被提交到 K8s 但 resourceVersion 不匹配时,操作会失败。

Patch 操作直接在对象上修改指定的字段,并且通过 Patch 类型确定修改的方式(合并还是覆盖)。和 Replace 不同的是,Patch 操作竞争策略是 last-write-wins,这也意味着不需要先读取对象就可以修改对象。

阅读全文 »
0%