Apache APISIX Java插件开发实战:从架构原理到企业级落地
一、技术背景:API网关的多语言困境与破局之道
在云原生架构中,API网关作为流量入口,承担着路由转发、认证授权、限流熔断等核心功能。Apache APISIX作为新一代云原生API网关,凭借其高性能和动态扩展性成为众多企业的首选。然而,Java技术栈团队在使用过程中普遍面临一个关键挑战:APISIX原生插件基于Lua开发,与企业现有Java技术栈存在显著隔阂。
1.1 企业级API网关面临的核心矛盾
Java技术团队在采用API网关时通常面临以下痛点:
- 技术栈割裂:团队熟悉Java生态但缺乏Lua经验,插件开发效率低下
- 代码复用困难:企业积累的Java业务逻辑和安全组件无法直接应用于网关层
- 调试链路复杂:跨语言调试增加问题定位难度,延长故障恢复时间
- 性能损耗:传统HTTP回调方式导致插件处理延迟增加30%以上
1.2 多语言插件架构的演进
API网关的多语言支持方案经历了三个发展阶段:
| 阶段 | 实现方式 | 性能 | 开发效率 | 典型应用场景 |
|---|---|---|---|---|
| 第一代 | 外部HTTP服务 | ★★☆☆☆ | ★★★★☆ | 简单业务逻辑 |
| 第二代 | Unix Domain Socket通信 | ★★★★☆ | ★★★★☆ | 复杂业务规则 |
| 第三代 | WASM沙箱执行 | ★★★★★ | ★★☆☆☆ | 高性能计算场景 |
Apache APISIX创新性地采用进程内RPC通信架构,通过ext-plugin机制实现了多语言支持,既保持了Nginx+Lua的高性能优势,又允许开发者使用Java等熟悉的语言编写插件。
图1:APISIX多语言插件架构示意图,展示了不同语言插件与APISIX核心的通信方式
二、架构解析:APISIX多语言插件通信机制
2.1 整体架构设计
APISIX的多语言支持架构主要包含三个核心组件:
- APISIX核心:基于Nginx+OpenResty的高性能流量处理引擎
- Plugin Runner:各语言插件运行时环境,负责插件生命周期管理
- RPC通信层:基于Unix Domain Socket的高效进程间通信机制
图2:APISIX软件架构图,展示了多语言插件在整体架构中的位置
2.2 外部插件通信流程
外部插件(ext-plugin)的工作流程可分为四个阶段:
- 请求拦截:APISIX在请求处理的特定阶段(pre-req/post-req/post-resp)触发插件调用
- 数据序列化:将请求上下文信息序列化为统一格式(Protocol Buffers)
- RPC调用:通过Unix Domain Socket发送请求到Plugin Runner
- 结果处理:接收处理结果并应用到请求流程中
图3:外部插件通信流程图,展示了APISIX与插件运行时的交互过程
2.3 Java插件运行时原理
Java插件运行时(apisix-java-plugin-runner)基于Netty实现高性能RPC服务,核心处理流程如下:
请求接入 → 协议解析 → 插件链调度 → 业务逻辑执行 → 结果返回
关键技术特性包括:
- 连接池化:复用与APISIX的通信连接,减少连接建立开销
- 线程模型:采用事件驱动模型,支持高并发请求处理
- 插件管理:基于SPI机制实现插件的动态加载与卸载
三、实战案例:企业级Java插件开发
3.1 场景一:基于OAuth2.0的统一认证插件
业务痛点:企业内部存在多套认证系统,需要在网关层实现统一身份验证,同时支持第三方应用授权。
技术选型:
- 认证协议:OAuth2.0 + JWT
- 存储方案:Redis(令牌缓存)
- 加密算法:RSA非对称加密
实现方案:
@Plugin(name = "oauth2-auth")
public class OAuth2AuthPlugin implements PluginFilter {
private OAuth2Config config;
private JwtParser jwtParser;
private RedisTemplate<String, String> redisTemplate;
@Override
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
// 1. 从请求头获取令牌
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
sendError(response, 401, "Missing access token");
return;
}
String token = authHeader.substring(7);
// 2. 检查令牌是否在黑名单中
if (Boolean.TRUE.equals(redisTemplate.hasKey("blacklist:" + token))) {
sendError(response, 401, "Token has been revoked");
return;
}
try {
// 3. 验证JWT令牌
Jws<Claims> claims = jwtParser.parseClaimsJws(token);
Claims body = claims.getBody();
// 4. 验证令牌有效期
if (body.getExpiration().before(new Date())) {
sendError(response, 401, "Token expired");
return;
}
// 5. 验证权限范围
String scope = body.get("scope", String.class);
if (!hasRequiredScope(scope)) {
sendError(response, 403, "Insufficient scope");
return;
}
// 6. 将用户信息添加到请求头
request.getHeaders().add("X-User-ID", body.getSubject());
request.getHeaders().add("X-User-Roles", body.get("roles", String.class));
// 7. 继续执行后续插件
chain.filter(request, response);
} catch (JwtException e) {
sendError(response, 401, "Invalid token: " + e.getMessage());
}
}
// 权限范围检查
private boolean hasRequiredScope(String scope) {
Set<String> requiredScopes = new HashSet<>(Arrays.asList(config.getRequiredScopes().split(",")));
Set<String> tokenScopes = new HashSet<>(Arrays.asList(scope.split(" ")));
return tokenScopes.containsAll(requiredScopes);
}
// 错误响应处理
private void sendError(HttpResponse response, int status, String message) {
response.setStatusCode(status);
response.setHeader("Content-Type", "application/json");
response.setBody("{\"error\":\"" + message + "\"}");
}
@Override
public void setConfig(JSONObject config) {
this.config = new OAuth2Config(config);
// 初始化JWT解析器
this.jwtParser = Jwts.parserBuilder()
.setSigningKey(RsaUtil.getPublicKey(config.getString("public_key")))
.build();
}
// 配置类
static class OAuth2Config {
private String publicKey;
private String requiredScopes;
public OAuth2Config(JSONObject config) {
this.publicKey = config.getString("public_key");
this.requiredScopes = config.getString("required_scopes", "read");
}
// getter方法省略
}
}
创新优化点:
- 令牌黑名单机制:使用Redis实现分布式令牌撤销
- 权限粒度控制:基于Scope的细粒度权限检查
- 性能优化:JWT验证结果本地缓存,减少重复计算
效果验证:
- 部署插件并配置路由:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '
{
"uri": "/api/*",
"plugins": {
"ext-plugin-pre-req": {
"conf": [
{
"name": "oauth2-auth",
"value": "{\"public_key\":\"-----BEGIN PUBLIC KEY-----(省略公钥)-----END PUBLIC KEY-----\",\"required_scopes\":\"read,write\"}"
}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:8080": 1
}
}
}'
- 测试验证:
# 无令牌请求
curl http://127.0.0.1:9080/api/users -i
# 应返回401 Unauthorized
# 有效令牌请求
curl http://127.0.0.1:9080/api/users -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." -i
# 应返回200 OK并包含用户数据
3.2 场景二:分布式追踪插件
业务痛点:微服务架构下,请求经过多个服务,需要实现全链路追踪,快速定位性能瓶颈。
技术选型:
- 追踪协议:OpenTelemetry
- 数据采集:Jaeger
- 采样策略:基于请求路径和延迟动态调整
实现方案:
@Plugin(name = "opentelemetry-trace")
public class OpenTelemetryTracePlugin implements PluginFilter {
private Tracer tracer;
private TraceConfig config;
private static final ThreadLocal<Span> CURRENT_SPAN = new ThreadLocal<>();
@Override
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
// 1. 从请求头提取或创建上下文
Context context = extractContext(request);
// 2. 创建span
Span span = tracer.spanBuilder("apisix." + request.getMethod())
.setParent(context)
.setAttribute("http.method", request.getMethod())
.setAttribute("http.target", request.getPath())
.setAttribute("http.host", request.getHeader("Host"))
.setAttribute("net.peer.ip", request.getRemoteAddr())
.startSpan();
CURRENT_SPAN.set(span);
try (Scope scope = span.makeCurrent()) {
// 3. 添加自定义标签
addCustomTags(span, request);
// 4. 记录请求开始时间
long startTime = System.currentTimeMillis();
// 5. 继续执行请求
chain.filter(request, response);
// 6. 记录响应信息
span.setStatus(StatusCode.OK);
span.setAttribute("http.status_code", response.getStatusCode());
span.setAttribute("duration_ms", System.currentTimeMillis() - startTime);
} catch (Exception e) {
// 7. 记录异常信息
span.setStatus(StatusCode.ERROR);
span.recordException(e);
throw e;
} finally {
// 8. 结束span
span.end();
CURRENT_SPAN.remove();
}
}
// 从请求头提取上下文
private Context extractContext(HttpRequest request) {
TextMapGetter<HttpRequest> getter = new TextMapGetter<HttpRequest>() {
@Override
public String get(HttpRequest carrier, String key) {
return carrier.getHeader(key);
}
@Override
public Iterable<String> keys(HttpRequest carrier) {
return carrier.getHeaders().keySet();
}
};
return OpenTelemetry.getPropagators().getTextMapPropagator()
.extract(Context.current(), request, getter);
}
// 添加自定义标签
private void addCustomTags(Span span, HttpRequest request) {
// 添加路由ID
String routeId = request.getVar("route_id");
if (routeId != null) {
span.setAttribute("apisix.route_id", routeId);
}
// 添加上游服务信息
String upstreamAddr = request.getVar("upstream_addr");
if (upstreamAddr != null) {
span.setAttribute("apisix.upstream_addr", upstreamAddr);
}
// 添加自定义业务标签
if (config.getCustomTags() != null) {
for (Map.Entry<String, String> entry : config.getCustomTags().entrySet()) {
String value = request.getHeader(entry.getValue());
if (value != null) {
span.setAttribute("custom." + entry.getKey(), value);
}
}
}
}
@Override
public void setConfig(JSONObject config) {
this.config = new TraceConfig(config);
// 初始化OpenTelemetry
initOpenTelemetry();
}
// 初始化OpenTelemetry
private void initOpenTelemetry() {
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(
JaegerGrpcSpanExporter.builder()
.setEndpoint(config.getJaegerEndpoint())
.build()
).build())
.setSampler(Sampler.traceIdRatioBased(config.getSampleRate()))
.build())
.setPropagators(ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance()
)
))
.buildAndRegisterGlobal();
this.tracer = openTelemetry.getTracer("org.apache.apisix.java-plugin");
}
// 配置类
static class TraceConfig {
private String jaegerEndpoint;
private double sampleRate;
private Map<String, String> customTags;
public TraceConfig(JSONObject config) {
this.jaegerEndpoint = config.getString("jaeger_endpoint", "http://localhost:14250");
this.sampleRate = config.getDoubleValue("sample_rate", 1.0);
// 解析自定义标签配置
if (config.containsKey("custom_tags")) {
this.customTags = config.getJSONObject("custom_tags").toJavaMap();
}
}
// getter方法省略
}
}
创新优化点:
- 动态采样:基于请求路径和响应时间动态调整采样率
- 上下文传递:完整支持W3C Trace Context规范
- 业务标签:可配置的自定义业务标签提取机制
3.3 场景三:基于规则引擎的动态路由插件
业务痛点:大型企业存在复杂的路由规则,需要基于多维度条件(用户、设备、地域等)动态路由到不同服务版本。
技术选型:
- 规则引擎:Drools
- 规则存储:etcd
- 动态更新:长轮询机制
实现方案:
@Plugin(name = "dynamic-router")
public class DynamicRouterPlugin implements PluginFilter {
private KieSession kieSession;
private RouterConfig config;
private ScheduledExecutorService scheduler;
private long lastRuleUpdateTime = 0;
@Override
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
// 1. 创建事实对象
RouteFact fact = createRouteFact(request);
// 2. 插入事实并执行规则
kieSession.insert(fact);
int fired = kieSession.fireAllRules();
// 3. 根据规则结果修改路由
if (fact.getUpstream() != null) {
request.setVar("upstream_host", fact.getUpstream());
request.setVar("upstream_scheme", fact.getScheme() != null ? fact.getScheme() : "http");
}
// 4. 继续执行
chain.filter(request, response);
}
// 创建路由事实对象
private RouteFact createRouteFact(HttpRequest request) {
RouteFact fact = new RouteFact();
// 基本信息
fact.setMethod(request.getMethod());
fact.setPath(request.getPath());
fact.setRemoteAddr(request.getRemoteAddr());
// 用户信息
fact.setUserId(request.getHeader("X-User-ID"));
fact.setUserAgent(request.getHeader("User-Agent"));
// 设备信息
String deviceType = parseDeviceType(request.getHeader("User-Agent"));
fact.setDeviceType(deviceType);
// 地域信息
String country = getCountryByIp(request.getRemoteAddr());
fact.setCountry(country);
// 时间信息
fact.setHour(LocalDateTime.now().getHour());
return fact;
}
@Override
public void setConfig(JSONObject config) {
this.config = new RouterConfig(config);
// 初始化规则引擎
initRuleEngine();
// 启动规则更新调度
startRuleUpdateScheduler();
}
// 初始化规则引擎
private void initRuleEngine() {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
// 从etcd加载规则
String rules = loadRulesFromEtcd();
kfs.write("src/main/resources/rules.drl", rules);
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
Results results = kieBuilder.getResults();
if (results.hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("规则加载失败: " + results.getMessages());
}
KieContainer kieContainer = kieServices.newKieContainer(
kieServices.getRepository().getDefaultReleaseId()
);
this.kieSession = kieContainer.newKieSession();
}
// 从etcd加载规则
private String loadRulesFromEtcd() {
// 实际实现中应使用etcd客户端获取规则
// 此处简化处理,返回默认规则
return "" +
"package com.apisix.rules\n" +
"import com.apisix.plugin.RouteFact\n" +
"\n" +
"rule \"Mobile users route to mobile API\"\n" +
" when\n" +
" fact: RouteFact(deviceType == \"mobile\")\n" +
" then\n" +
" fact.setUpstream(\"mobile-api-service:8080\");\n" +
"end\n" +
"\n" +
"rule \"VIP users route to premium service\"\n" +
" when\n" +
" fact: RouteFact(userId != null && userId.startsWith(\"VIP\"))\n" +
" then\n" +
" fact.setUpstream(\"premium-service:8080\");\n" +
" fact.setScheme(\"https\");\n" +
"end\n";
}
// 启动规则更新调度
private void startRuleUpdateScheduler() {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
try {
// 检查规则是否有更新
long currentUpdateTime = getLastRuleUpdateTimeFromEtcd();
if (currentUpdateTime > lastRuleUpdateTime) {
// 更新规则引擎
initRuleEngine();
lastRuleUpdateTime = currentUpdateTime;
log.info("规则已更新");
}
} catch (Exception e) {
log.error("更新规则失败", e);
}
}, 0, config.getRefreshInterval(), TimeUnit.SECONDS);
}
// 辅助方法:解析设备类型
private String parseDeviceType(String userAgent) {
// 简化实现
if (userAgent == null) return "unknown";
if (userAgent.contains("Mobile") || userAgent.contains("Android") || userAgent.contains("iOS")) {
return "mobile";
}
return "desktop";
}
// 辅助方法:根据IP获取国家
private String getCountryByIp(String ip) {
// 实际实现中应调用IP地理位置服务
return "CN"; // 默认返回中国
}
@Override
public void destroy() {
if (scheduler != null) {
scheduler.shutdown();
}
if (kieSession != null) {
kieSession.dispose();
}
}
// 配置类和事实类省略
}
创新优化点:
- 动态规则更新:基于etcd实现规则的热更新,无需重启插件
- 多维度路由:支持基于用户、设备、地域等多维度条件的组合路由
- 规则引擎集成:使用Drools规则引擎实现复杂业务规则的灵活配置
四、效能优化:Java插件性能调优实践
4.1 连接池优化
@Configuration
public class ConnectionPoolConfig {
@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> template = new RedisTemplate<>();
// 配置连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(20); // 最大连接数
poolConfig.setMaxIdle(10); // 最大空闲连接
poolConfig.setMinIdle(5); // 最小空闲连接
poolConfig.setTestOnBorrow(true); // 借出连接时测试
poolConfig.setTestWhileIdle(true); // 空闲时测试
JedisConnectionFactory factory = new JedisConnectionFactory(poolConfig);
factory.setHostName(config.getRedisHost());
factory.setPort(config.getRedisPort());
factory.afterPropertiesSet();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
4.2 线程模型优化
Netty线程模型配置:
public class PluginRunnerServer {
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private ServerBootstrap bootstrap;
public void start() {
// 根据CPU核心数配置线程池大小
int cores = Runtime.getRuntime().availableProcessors();
bossGroup = new NioEventLoopGroup(1); // 接受连接的线程组,通常1个线程足够
workerGroup = new NioEventLoopGroup(cores * 2); // 处理IO的线程组
bootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ProtobufDecoder(...));
pipeline.addLast(new ProtobufEncoder(...));
pipeline.addLast(new PluginHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true);
// 绑定端口
ChannelFuture future = bootstrap.bind(new UnixDomainSocketAddress(config.getSocketPath()));
future.syncUninterruptibly();
}
}
4.3 缓存策略
本地缓存配置:
@Configuration
public class CacheConfig {
@Bean
public LoadingCache<String, Jws<Claims>> jwtCache() {
return CacheBuilder.newBuilder()
.maximumSize(10000) // 最大缓存项数
.expireAfterWrite(5, TimeUnit.MINUTES) // 写入后过期时间
.recordStats() // 开启统计
.build(new CacheLoader<String, Jws<Claims>>() {
@Override
public Jws<Claims> load(String token) {
// 实际的JWT验证逻辑
return jwtParser.parseClaimsJws(token);
}
});
}
}
五、问题排查:常见问题及解决方案
5.1 插件不生效问题排查决策树
插件不生效
├── 检查APISIX配置
│ ├── ext-plugin路径是否正确
│ ├── runner进程是否启动
│ └── 路由配置是否正确引用插件
├── 检查插件日志
│ ├── 是否有初始化异常
│ ├── 是否有配置解析错误
│ └── 是否有运行时异常
├── 检查通信链路
│ ├── Unix Domain Socket文件是否存在
│ ├── 权限是否正确
│ └── 通信协议是否匹配
└── 检查插件代码
├── 是否正确实现PluginFilter接口
├── 是否正确设置@Plugin注解
└── 是否正确处理过滤器链
5.2 性能问题排查工具
- APISIX性能指标:
curl http://127.0.0.1:9091/apisix/prometheus/metrics | grep apisix_plugin
- Java运行时监控:
jstat -gcutil <pid> 1000 10 # 每1秒打印一次GC情况,共10次
jstack <pid> > plugin-stack.log # 导出线程栈
- 火焰图生成:
# 安装async-profiler
wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v2.9/async-profiler-2.9-linux-x64.tar.gz
tar -zxvf async-profiler-2.9-linux-x64.tar.gz
# 生成火焰图
./profiler.sh -d 30 -f flamegraph.html <pid>
5.3 常见问题解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 插件加载失败 | 类路径问题或依赖冲突 | 检查依赖包是否冲突,确保插件类可被SPI发现 |
| 通信超时 | 连接池配置不当或处理耗时过长 | 优化连接池配置,减少插件处理时间,设置合理超时 |
| 内存泄漏 | 资源未正确释放 | 使用JProfiler分析内存泄漏,确保资源正确关闭 |
| 性能下降 | 同步阻塞操作 | 将阻塞操作改为异步,使用CompletableFuture |
六、进阶路径:从入门到精通
6.1 技术提升路线图
-
基础阶段:
- 掌握APISIX插件开发基础
- 熟悉Java Plugin Runner架构
- 实现简单业务插件
-
进阶阶段:
- 深入理解APISIX请求处理流程
- 掌握高性能Java编程技巧
- 实现复杂业务逻辑插件
-
专家阶段:
- 参与APISIX Java Plugin Runner开发
- 优化插件运行时性能
- 设计企业级插件架构
6.2 扩展学习资源
- 官方文档:docs/zh/latest/
- 示例插件:example/apisix/plugins/
- 测试用例:t/plugin/
6.3 反常识技术实践
- 同步改异步:将耗时操作(如数据库查询)改为异步处理,使用CompletableFuture:
@Override
public void filter(HttpRequest request, HttpResponse response, PluginFilterChain chain) {
// 异步处理
CompletableFuture.supplyAsync(() -> {
// 耗时操作
return queryUserInfo(request.getHeader("X-User-ID"));
}, executorService).thenAccept(userInfo -> {
// 处理结果
request.getHeaders().add("X-User-Name", userInfo.getName());
// 继续处理请求
chain.filter(request, response);
}).exceptionally(ex -> {
// 异常处理
response.setStatusCode(500);
response.setBody("Internal error");
return null;
});
}
- 预计算热点数据:对于高频访问的数据,通过定时任务预计算并缓存:
@PostConstruct
public void init() {
// 每5分钟更新一次热点数据
scheduler.scheduleAtFixedRate(() -> {
Map<String, String> hotData = loadHotDataFromDatabase();
hotDataCache.putAll(hotData);
}, 0, 5, TimeUnit.MINUTES);
}
- 自适应限流:基于系统负载动态调整限流阈值:
private int calculateDynamicLimit() {
// 获取当前系统负载
double load = ManagementFactory.getOperatingSystemMXBean().getSystemCpuLoad();
// 根据负载调整限流阈值
if (load > 0.8) {
return config.getBaseLimit() / 2; // 高负载时降低阈值
} else if (load < 0.3) {
return config.getBaseLimit() * 2; // 低负载时提高阈值
} else {
return config.getBaseLimit(); // 正常负载
}
}
七、总结
Apache APISIX的多语言插件架构为Java技术团队提供了一条平滑的API网关扩展路径。通过ext-plugin机制,开发者可以充分利用Java生态系统的丰富资源,同时保持API网关的高性能特性。本文通过三个企业级实战案例,展示了Java插件在统一认证、分布式追踪和动态路由等场景的应用,提供了从架构理解到代码实现的完整指南。
随着云原生技术的发展,API网关作为流量入口的作用日益重要。掌握多语言插件开发技能,将帮助Java团队更好地应对复杂的业务需求,构建高性能、可扩展的API网关生态。希望本文能为你的APISIX Java插件开发之旅提供有价值的参考。
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5.1GLM-5.1是智谱迄今最智能的旗舰模型,也是目前全球最强的开源模型。GLM-5.1大大提高了代码能力,在完成长程任务方面提升尤为显著。和此前分钟级交互的模型不同,它能够在一次任务中独立、持续工作超过8小时,期间自主规划、执行、自我进化,最终交付完整的工程级成果。Jinja00
LongCat-AudioDiT-1BLongCat-AudioDiT 是一款基于扩散模型的文本转语音(TTS)模型,代表了当前该领域的最高水平(SOTA),它直接在波形潜空间中进行操作。00- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
HY-Embodied-0.5这是一套专为现实世界具身智能打造的基础模型。该系列模型采用创新的混合Transformer(Mixture-of-Transformers, MoT) 架构,通过潜在令牌实现模态特异性计算,显著提升了细粒度感知能力。Jinja00
FreeSql功能强大的对象关系映射(O/RM)组件,支持 .NET Core 2.1+、.NET Framework 4.0+、Xamarin 以及 AOT。C#00


