Fusen-rs High-performance RPC Framework
⚓ Rust 📅 2025-09-29 👤 surdeus 👁️ 7fusen-rs High-performance RPC Framework
fusen-rs is a high-performance, lightweight microservice framework that uses Rust macros to solve the current problems of complex use and low performance of mainstream rpc frameworks. It does not need to generate RPC calling code through scripts and scaffolding, and compiles it through macros. It uses "reflection" to achieve high-performance calls and meet the simplicity of RPC calls. It also supports user-defined components and other functions.
[ 中文 ]
Function List
 RPC call abstraction layer (Rust macro) RPC call abstraction layer (Rust macro)
 Multi-protocol support (HTTP1, HTTP2) Multi-protocol support (HTTP1, HTTP2)
 Service registration and discovery (Nacos) Service registration and discovery (Nacos)
 Microservice ecological compatibility (Dubbo3, SpringCloud) Microservice ecological compatibility (Dubbo3, SpringCloud)
 Custom components (custom load balancer, Aspect surround notification component) Custom components (custom load balancer, Aspect surround notification component)
 Graceful shutdown Graceful shutdown
 HTTP3 protocol support HTTP3 protocol support
Quick Start
Common Interface
#[fusen_trait]
pub trait DemoService {
    async fn sayHello(&self, name: String) -> String;
    #[asset(path = "/sayHelloV2-http")]
    async fn sayHelloV2(&self, name: RequestDto) -> ResponseDto;
    #[asset(path = "/divide", method = GET)]
    async fn divideV2(&self, a: i32, b: i32) -> String;
}
Server
#[fusen_service]
impl DemoService for DemoServiceImpl {
    async fn sayHello(&self, name: String) -> Result<String, FusenError> {
        Ok(format!("Hello {name}"))
    }
    #[asset(path = "/sayHelloV2-http")]
    async fn sayHelloV2(&self, name: RequestDto) -> Result<ResponseDto, FusenError> {
        Ok(ResponseDto {
            str: format!("HelloV2 {}", name.str),
        })
    }
    #[asset(path = "/divide", method = GET)]
    async fn divideV2(&self, a: i32, b: i32) -> Result<String, FusenError> {
        Ok(format!("a + b = {}", a + b))
    }
}
Client
let fusen_client = DemoServiceClient::init(
    &mut fusen_contet,
    Protocol::Fusen,
    Some(vec!["LogAspect", "TimeAspect"]),
).await.unwrap();
println!("{:?}", fusen_client.divideV2(1, 2).await);
println!("{:?}", fusen_client.sayHello("test1".to_owned()).await);
Custom component
Microservice custom components include load balancers, service breaker/current limiting components, pre- and post-request processors, service link tracking and other components. Since the components are highly customized, this project is provided with reference to the concept of AOP Two custom components are provided to provide flexible request processing.
LoadBalance
Load balancing component, LoadBalance provides a select interface to implement user-defined service balancing configuration.
#[handler(id = "CustomLoadBalance")]
impl LoadBalance for CustomLoadBalance {
    async fn select(
        &self,
        invokers: Arc<Vec<Arc<ServiceResource>>>,
    ) -> Result<Option<Arc<ServiceResource>>, FusenError> {
        if invokers.is_empty() {
            return Ok(None);
        }
        let mut thread_rng = rand::rng();
        Ok(Some(
            invokers[thread_rng.random_range(0..invokers.len())].clone(),
        ))
    }
}
Aspect
I believe everyone is familiar with the concept of dynamic proxy. This is a technology used by Java to enhance classes, and the Spring framework uses this feature to encapsulate a more advanced model, which is the AOP aspect-first programming model. This component is a reference This model implements the wraparound notification model. Users can implement various component requirements based on this component, such as service circuit breaker/current limiting, request pre- and post-processing, link tracking, request response time monitoring and other requirements, and Aspect Components support multi-level nested calls and provide flexible definition methods to meet users' complex needs.
#[handler(id = "TimeAspect")]
impl Aspect for TimeAspect {
    async fn aroud(&self, join_point: ProceedingJoinPoint) -> Result<FusenContext, FusenError> {
        let start_time = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_millis();
        debug!("开始处理时间 : {start_time:?}");
        let context = join_point.proceed().await;
        debug!(
            "结束处理时间 : {:?}",
            SystemTime::now()
                .duration_since(UNIX_EPOCH)
                .unwrap()
                .as_millis()
                - start_time
        );
        context
    }
}
1 post - 1 participant
🏷️ Rust_feed