Observability - OpenTelemetry Java Zero Code
Java Agent
Zero-code instrumentation with Java uses a Java agent JAR attached to any Java 8+ application.
It dynamically injects bytecode to capture telemetry from many popular libraries and frameworks.
It can be used to capture telemetry data at the “edges” of an app or service
such as inbound requests, outbound HTTP calls, database calls, and so on.
Getting startedSetup
Download opentelemetry-javaagent.jar from Releases of the opentelemetry-java-instrumentation repository
place the JAR in your prefer ...
Observability - OpenTelemetry Java
Intro to OpenTelemetry Java
OpenTelemetry Java is the set of OpenTelemetry observability tools for the Java ecosystem.
At a high level, it consists of the API, the SDK, and instrumentation.
Overview
The API is a set of classes and interfaces for recording telemetry across key observability signals.
It supports multiple implementations, with a low-overhead minimalist Noop and SDK reference implementation provided out of the box.
It is designed to be taken as a direct dependency by libraries, frameworks, ...
AI Agent - MCP Overview
提示工程 + RAG
LLM 可以开箱即用,通过提示工程和它直接对话并解决问题
随着 LLM 的能力越来越强,尤其是其推理模型的出现,LLM 的回答越来越准确
但 LLM 并非全知全能,预训练的数据有截止时间 - RAG
RAG 是一种 LLM 应用开发范式
将 LLM 与外部数据源相结合来提高准确性和相关性
先通过向量之间的相似度,用检索系统从外部数据源搜索数据,以识别与用户查询相关的信息
LLM 随后利用检索到信息生成更精确,更及时的响应
RAG 过程 - 通过 RAG 增加 LLM 的知识,大大提高了 LLM 回答的准确性和相关性
Key
Value
检索
通过向量数据库或者其它检索系统,找出与用户查询相关的信息
增强
将检索到的信息作为上下文提供给 LLM
生成
LLM 基于这些额外信息生成回答
Agent + Tool Call
RAG 解决的是让 LLM 使用内部知识,同时减少幻觉的问题,但 RAG 本身并没有增强 LLM 的行动能力 - Agent
Agent 本质上是赋予 LLM 使用工具并采取行动的开发范式
Agent 的工作流程
Key
 ...
AI Agent - Overview
技术更迭
LLM 应用工程化难题
模型与外部世界割裂
LLM 是基于概率计算的新范式,虽然很强大,但仍需要与传统的结构化计算范式相结合,即通过工具调用来完成精确任务
目前传统结构化工具与 LLM 之间是割裂的,LLM 难以直接动态地接入实时数据、数据库或企业工具
传统的 API 调用方式零散且不标准,导致开发效率低下
Agent 协作的孤岛效应
不同 Agent 框架(LangGraph、AutoGen、CrewAI)各自为政,缺乏统一的通信标准,跨平台协作很难实现
复杂场景的工程化瓶颈
从搜索助手到企业知识中台、RAG 与多 Agent 系统需要处理多源数据、多模态交互和长时任务,现有工具链难以提供统一的解决方案
MCP + A2A
标准化 + 可扩展
MCP
模型主控 + 客户端驱动
MCP 是一个为 LLM 更方便地利用外部资源(主要是工具)而设计的标准化接口,旨在打破 LLM 与外部数据、工具之间的壁垒
传统上,将 AI 系统连接到外部工具需要集成多个 API - 代码冗余 + 难以维护 + 扩展性差
MCP 将繁琐细节都隐藏到服务器端 - 开发者只需关心 LLM 想用 ...
New Java Feature - Foreign Function API
概述
Java 的外部函数接口这个特性,与外部内存接口一起,会极大地丰富 Java 语言的生态环境
像 Java 或者 Go 这样的通用编程语言,都需要和其它的编程语言或者环境打交道 - 如操作系统或者 C 语言
Java 通过 Java 本地接口 JNI 来支持该做法
本地方法接口示例1234567891011public class HelloWorld {    static {        System.loadLibrary("helloWorld");    }    public static void main(String[] args) {        new HelloWorld().sayHello();    }    private native void sayHello();}
sayHello 使用了 native 修饰符,是一个本地方法,可以使用 C 语言实现 - 生成对应的 C 语言的头文件
1234$ javac -h . HelloWorld.java$ lsHello ...
New Java Feature - Foreign Memory API
概述
在讨论代码性能的时候,内存的使用效率是一个绕不开的话题 - Flink/Netty
为了避免 JVM GC 不可预测的行为以及额外的性能开销,一般倾向于使用 JVM 之外的内存来存储和管理数据 - 堆外数据 - off-heap data
使用堆外存储最常用的办法,是使用 ByteBuffer 来分配直接存储空间 - direct buffer
JVM 会尽最大努力直接在 direct buffer 上执行 IO 操作,避免数据在本地和 JVM 之间的拷贝
频繁的内存拷贝是性能的主要障碍之一
为了极致的性能,应用程序通常会尽量避免内存的拷贝
理想的情况下,一份数据只需要一份内存空间 - 即零拷贝
ByteBuffer
使用 ByteBuffer 来分配直接存储空间
1public static ByteBuffer allocateDirect(int capacity);
ByteBuffer 所在的 Java 包是 java.nio,ByteBuffer 的设计初衷是用于非阻塞编程
ByteBuffer 是异步编程和非阻塞编程的核心类,几乎所有的 Java 异步模式或者 ...
New Java Feature - Flow
指令式编程
最常用的代码控制模式
1System.out.println("Hello, World!");
通过代码发布指令,然后等待指令的执行以及指令执行带来的状态变化
并且根据目前的状态,来确定下一次要发布的指令,并且用代码把下一个指令表示出来
指令式编程模型关注的重点在于控制状态
1234567try {    Digest messageDigest = Digest.of("SHA-256");    byte[] digestValue =            messageDigest.digest("Hello, world!".getBytes());} catch (NoSuchAlgorithmException ex) {    System.out.println("Unsupported algorithm: SHA-256");}
首先调用 Digest.of 方法,得到一个 Digest 实例
然后调用该实例的方法 Digest.dig ...
New Java Feature - Error Code
概述
Java 的异常处理是对代码性能有着重要影响的因素
Java 的异常处理,有着天生优势,特别是在错误排查方面的作用,很难找到合适的替代方案
用例123456789101112131415161718192021222324252627282930313233343536package me.zhongmingmao;import java.security.NoSuchAlgorithmException;public class UseCase {  public static void main(String[] args) {    String[] algorithms = {"SHA-128", "SHA-192"};    String availableAlgorithm = null;    for (String algorithm : algorithms) {      Digest md;      try {        md = Digest.of(algorithm) ...
New Java Feature - Exception
概述
Java 异常的使用和处理,是滥用最严重,诟病最多,也是最难平衡的一个难题
Java 语言支持三种异常的状况
非正常异常(Error)、运行时异常(Runtime Exception)、检查型异常(Checked Exception)
异常,除非特别声明,一般指的是 Checked Exception 和 Checked Exception
异常状况的处理会让代码的效率变低 - 不应该使用异常机制来处理正常情况
理想情况下,在执行代码时没有任何异常发生,否则业务执行的效率会大打折扣
几乎无法完成,不管是 JDK 核心类库还是业务代码,都存在大量的异常处理代码
软件都是由很多类库集成的,大部分类库,都只是从自身的角度去考虑问题,使用异常来处理问题
很难期望业务执行下来没有任何异常发生
抛出异常影响了代码的运行效率,而实际业务又没有办法完全不抛出异常
新的编程语言(Go),彻底抛弃类似于 Java 这样的异常机制,重新拥抱 C 语言的错误方式
性能
没有抛出异常的用例,能够支持的吞吐量要比抛出异常的用例大 1000 倍
案例
在设计算法公开接口时,算法的敏捷性是必须要要考虑的问题
 ...
New Java Feature - Switch Matching
案例
假设上面表示形状的封闭类和许可类是版本 1.0,它们被封装在一个基础 API 类库里 - 基础类库
而 isSquare 的实现代码,被封装在另一个 API 类库里 - 扩展类库
新加入一个许可类,用来表示长方形 - 基础类库的升级,扩展类库也要同步升级 - 但不一定能意识到
对于需要更改扩展类库这件事,基础类库的作者,不会通知到扩展类库的作者
一般情况下,基础类库和扩展类库是独立的作品,由不同的团队和社区维护
基础类库的作者不太可能意识到扩展类库的存在,更不可能去研究扩展类库的实现细节
扩展类库维护者也不会注意到基础类库的修改,更不容易想到基础类库的修改会影响到扩展类库的行为
模式匹配的 switch
具有模式匹配能力的 switch - 将模式匹配扩展到 switch 语句和 switch 表达式
允许测试多个模式,每个模式多可以有特定的操作 - 简洁安全地表达复杂的面向数据的查询
扩充的匹配类型
在 JDK 17 之前的 switch 关键字可以匹配的数据类型包括 - 数字、枚举和字符串 - 本质上都是整型的原始类型
在 JDK 17 之后,匹配的目标数据类型,可以是一个 ...










