#api-gateway #gateway #proxy #api #websocket #kubernetes #http-proxy

spacegate-plugin

以库优先,轻量级,高性能,支持云原生的API网关

1 个不稳定版本

0.2.0-alpha.12024年5月21日

#16 in #api-gateway


2 个crate中使用了(通过 spacegate-shell

MIT/Apache

390KB
8K SLoC

预览版本,不保证API的稳定性!请勿在生产环境中使用!


以库优先,轻量级,高性能,支持云原生的API网关🪐


Build Status License

SpaceGate("太空门是悬挂在太空或行星轨道中的星际之门") 来自 "星际之门"。

💖 核心功能

  • 小巧:基于rust,可执行文件仅占用6MB。
  • 云原生:实现了 Kubernetes Gateway API 规范。
  • 易于扩展:只需用rust编写两个函数即可构建自己的插件。
  • 易于扩展:只需用rust编写两个函数即可构建自己的插件。
  • 高性能
  • 低资源占用

用法

在k8s中使用spacegate

为kubernetes安装

kubectl apply -f https://github.com/ideal-world/spacegate/releases/download/0.2.0-alpha.1/spacegate-0.2.0-alpha.1.yaml

打开spacegate管理web,享受吧!

将spacegate作为可执行二进制文件使用

构建和安装

在自己的Linux机器上构建和安装。

安装spacegate

sh resource/install/install.sh

安装spacegate管理工具(可选)

此官方管理工具将提供一个Web界面来编辑网关配置。

sh resource/install/install-admin.sh

manage tool

配置您的网关

如果已安装spacegate管理工具,请访问localhost:9991。

firefox localhost:9991

或访问配置文件夹

ls /etc/spacegate

编辑配置后,使用systemctl重新加载配置。

sudo systemctl reload spacegate

安装插件

检查插件文件夹

ls /lib/spacegate/plugins

只需将 .so 文件放入插件文件夹并配置即可。

将spacegate作为Rust库使用

您可以使用 spacegate-kernelspacegate-shell。前者相对较低级别,而后者集成了插件和配置系统。

使用 spacegate-shell

spacegate-shell = { git="https://github.com/ideal-world/spacegate", branch="dev" }

通过配置变更监听器启动

async fn main() {
    let listener = todo!("create a listener!");
    spacegate_shell::startup(listener).await;
}

或直接使用内置监听器

// file config
spacegate_shell::startup_file("/etc/spacegate").await;
// k8s resource
spacegate_shell::startup_k8s(Some("spacegate-namespace")).await;
// fetch from redis
spacegate_shell::startup_redis("redis://my-redis").await;

使用 spacegate-kernel

spacegate-kernel = { git="https://github.com/ideal-world/spacegate", branch="dev" }

创建一个监听器和网关服务

let cancel = CancellationToken::default();
// create a gateway service
let gateway = gateway::Gateway::builder("test_gateway")
    .http_routers([(
        "test_gateway".to_string(),
        HttpRoute::builder()
            .rule(
                HttpRouteRule::builder()
                    .match_item(HttpPathMatchRewrite::prefix("/baidu"))
                    .backend(HttpBackend::builder().schema("https").host("www.baidu.com").port(443).build())
                    .build(),
            )
            .build(),
    )])
    .build();
let addr = SocketAddr::from_str("[::]:9002")?;
// create a listener
let listener = SgListen::new(
    addr,
    gateway.as_service(),
    cancel.child_token(),
);
// start listen
listener.listen().await?;

在rust中创建自己的插件

您需要做的就是实现一个 Plugin 特性

use spacegate_plugin::{SgResponse, SgRequest, Inner, BoxError, PluginConfig, Plugin};

pub struct ServerHeaderPlugin {
    header_value: String,
}

impl Plugin for ServerHeaderPlugin {
    // an unique code for this plugin
    const CODE: &'static str = "server-header";
    // this will be called when request passthrough this plugin
    async fn call(&self, req: SgRequest, inner: Inner) -> Result<SgResponse, BoxError> {
        // pre-request process

        // call inner to pass this request into inner layers
        let mut resp = inner.call(req).await;    

        // post-request process
        resp.headers_mut().insert("server", self.header_value.parse()?);

        // return the result
        Ok(resp)
    }

    // create a plugin instance from config
    fn create(plugin_config: PluginConfig) -> Result<Self, BoxError> {
        let Some(header_value) = plugin_config.spec.get("header_value") else {
            return Err("missing header_value".into())
        };
        Ok(Self {
           header_value: header_value.as_str().unwrap_or("spacegate").to_string(),
        })
    }
}

将插件作为静态库使用

在您的应用程序程序中。

// register the plugin into global plugin repository
spacegate_plugin::PluginRepository::global().register::<ServerHeaderPlugin>()

将插件作为动态链接库使用

使用宏dynamic_lib

use spacegate_plugin::dynamic_lib;
dynamic_lib! { ServerHeaderPlugin }

并将crate类型设置为dylib

[lib]
crate-type = ["dylib"]

获取库文件后,将其加载到应用程序中。

例如

spacegate_plugin::PluginRepository::global().register_dylib("/lib/spacegate/plugins/mylib.so")

为什么创建这个项目

目前市场上有很多API网关产品,但它们大多以独立服务的形式存在。定制能力相对较弱,使用和部署的成本相对较高。

本项目基于Rust语言,并使用hyper作为基础网络库。目标是:提供一个以库为基础、轻量级、高性能、云原生支持的API网关

📦 组件

类型 描述
spacegate-kernel Crate Docs rust-lib 创建网关服务的内核功能
spacegate-ext-redis Crate Docs rust-lib Redis功能扩展
spacegate-ext-axum Crate Docs rust-lib Axum web服务器功能扩展
spacegate-shell Crate Docs rust-lib 集成包括插件系统、配置监听器和易于使用的程序入口的集合。
spacegate-plugin Crate Docs rust-lib spacegate-shell的插件系统实现。
spacegate-model Crate Docs rust-lib spacegate项目中的常用数据结构。
spacegate-config Crate Docs rust-lib 配置监听器接口和实现。
spacegate bin 基于spacegate-shell的现成可执行文件。
spacegate-admin bin Spacegate管理应用程序后端服务。
spacegate-admin-client NPM Version js-lib spacegate-admin的JavaScript/TypeScript sdk。
spacegate-admin-fe web Spacegate管理前端。

项目结构

Crates

🔖 版本发布

发布二进制文件命名方法:{crate}-{arch}{OS}{abi}-{version} 在此下载

OS Arch abi 备注
linux x86_64,aarch64 gnu,musl 如果需要静态链接,请使用musl

依赖项

~19–33MB
~604K SLoC