Apache ShenYu: 现代化的API网关解决方案
在微服务架构日益流行的今天,API网关作为微服务生态系统中的核心组件,扮演着越来越重要的角色。本文将介绍Apache ShenYu,一个功能强大的Java原生API网关,我有幸参与了该项目的开发和维护。
API网关的重要性
在微服务架构中,API网关承担着以下关键职责:
- 请求路由:将请求转发到相应的微服务
- 负载均衡:分散请求负载到多个服务实例
- 协议转换:支持不同协议之间的转换(如HTTP到gRPC)
- 认证授权:集中管理访问控制
- 限流熔断:保护后端服务免受流量冲击
- 监控日志:收集请求和性能指标
Apache ShenYu简介
Apache ShenYu是一个高性能、可扩展的Java原生API网关,专为微服务架构设计。它提供了丰富的功能集,包括:
核心功能:
- 动态流量控制
- 灰度发布
- 服务治理
- 多协议支持(HTTP, WebSocket, Dubbo, gRPC, Spring Cloud等)
- 插件化架构
- 高性能
架构设计
Apache ShenYu采用了模块化的架构设计,主要包括以下几个组件:
- Gateway Core: 核心网关引擎
- Admin Console: 管理控制台
- Sync Data: 配置同步模块
- Plugin System: 插件系统
插件系统
ShenYu的一个显著特点是其灵活的插件系统。所有功能都以插件形式提供,可以根据需要进行组合和配置。
public class RateLimiterPlugin extends AbstractShenyuPlugin {
private final RateLimiterHandler rateLimiterHandler;
@Override
public Mono<Void> execute(final ShenyuPluginChain chain, final ServerWebExchange exchange) {
final ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
final RuleData rule = plugin.matchRule(exchange, handle.getSelector(), handle.getRuleData());
return rateLimiterHandler.doRateLimit(exchange, chain, rule)
.flatMap(result -> {
if (result) {
return chain.execute(exchange);
}
return ShenyuResponseUtils.error(exchange, "rate limit exceeded");
});
}
@Override
public int getOrder() {
return PluginEnum.RATE_LIMITER.getCode();
}
@Override
public String named() {
return PluginEnum.RATE_LIMITER.getName();
}
}
性能表现
在性能测试中,ShenYu展现了卓越的性能:
测试环境:
- 8核CPU,16GB内存
- 1000并发连接,持续60秒
测试结果:
- QPS: 20,000+
- 平均响应时间: 5ms
- 99%响应时间: 15ms
- CPU使用率: 65%
这样的性能足以满足大多数企业级应用的需求。
Rust客户端
作为ShenYu生态的一部分,我参与开发了ShenYu Rust Client项目。这是一个Rust实现的ShenYu客户端,允许Rust应用程序无缝集成到ShenYu网关生态系统中。
use axum::routing::post;
use axum::{routing::get, Router};
use shenyu_client_rust::axum_impl::ShenYuRouter;
use shenyu_client_rust::ci::_CI_CTRL_C;
use shenyu_client_rust::config::ShenYuConfig;
use shenyu_client_rust::core::ShenyuClient;
use shenyu_client_rust::IRouter;
async fn health_handler() -> &'static str {
"OK"
}
async fn create_user_handler() -> &'static str {
"User created"
}
#[tokio::main]
async fn main() {
// Spawn a thread to listen for Ctrl-C events and shutdown the server
std::thread::spawn(_CI_CTRL_C);
// Initialize tracing
tracing_subscriber::fmt::init();
let app = ShenYuRouter::<()>::new("shenyu_client_app")
.nest("/api", ShenYuRouter::new("api"))
.route(
"/health",
&format!("{}::{}", env!("CARGO_PKG_NAME"), stringify!(health_handler)),
get(health_handler),
)
.route(
"/users",
&format!(
"{}::{}",
env!("CARGO_PKG_NAME"),
stringify!(create_user_handler)
),
post(create_user_handler),
);
let config = ShenYuConfig::from_yaml_file("config.yml").unwrap();
let client = ShenyuClient::new(config, app.app_name(), app.uri_infos(), 3000).unwrap();
let axum_app: Router = app.into();
client.register().expect("TODO: panic message");
// Start Axum server
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, axum_app)
.with_graceful_shutdown(async move {
tokio::signal::ctrl_c()
.await
.expect("failed to listen for event");
client.offline_register();
})
.await
.unwrap();
}
结论
Apache ShenYu作为一个强大而灵活的API网关解决方案,正在被越来越多的企业和组织采用。它的高性能、可扩展性和丰富的功能集使其成为微服务架构中不可或缺的组件。
如果您正在寻找一个功能完备的API网关,Apache ShenYu绝对值得考虑。欢迎加入ShenYu社区,一起为项目做出贡献!