# lix-rpc-platform
**Repository Path**: sclx/lix-rpc-platform
## Basic Information
- **Project Name**: lix-rpc-platform
- **Description**: No description available
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-12-23
- **Last Updated**: 2026-03-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Lix RPC Platform




一个基于 Spring Boot 和 Spring Cloud 的轻量级 RPC 框架,通过注解驱动实现透明的服务间调用。
[快速开始](#快速开始) • [核心特性](#核心特性) • [项目结构](#项目结构) • [API文档](#api文档)
---
## 概述
**Lix RPC Platform** 是一个微服务RPC框架,旨在**减少微服务调用的模板代码**。通过 `@RpcService` 和 `@RpcClient` 注解,开发者可以像调用本地方法一样透明地调用远程服务。
该框架集成 Spring Cloud Eureka 进行服务发现,使用 Feign 进行HTTP代理生成,支持多种内容类型(JSON、Multipart、OctetStream、TextPlain、XML)和文件流传输。
---
## 核心特性
- ⚡ **注解驱动** - `@RpcService` 自动注册,`@RpcClient` 自动代理注入
- 🌐 **服务发现** - 基于 Spring Cloud Eureka 的自动注册与发现
- 📦 **多内容类型** - 原生支持 JSON、Multipart、Binary、Text、XML
- 📁 **文件传输** - 内置文件上传/下载支持,自动处理二进制数据和Base64编码
- 🔒 **线程安全** - 缓存采用 LRU 策略和 ConcurrentHashMap 保证并发安全
- 🎯 **灵活配置** - 支持超时、内容类型、流式传输等细粒度控制
- 🛡️ **异常体系** - 完整的业务异常、系统异常、远程异常分类体系
---
## 快速开始
### 系统要求
- Java 8+
- Maven 3.6+
- Spring Boot 2.3.9 及以上
### 项目结构
```
lix-rpc-platform/
├── lix-rpc-platform-common/ # 核心公共库(DTO、注解、异常、工具)
├── lix-rpc-platform-server/ # 服务端框架(@EnableRpcServer 支持)
├── lix-rpc-platform-client/ # 客户端框架(@EnableRpcClient 支持)
├── lix-rpc-interfaces/ # 服务接口定义(共享契约)
├── lix-rpc-server/ # 示例服务端应用
├── lix-rpc-client/ # 示例客户端应用
└── lix-rpc-eureka/ # Eureka服务注册中心
```
### 1. 启动Eureka服务注册中心
```bash
# 进入eureka模块
cd lix-rpc-eureka
# 启动应用(默认8761端口)
mvn spring-boot:run
# 或直接运行 EurekaApplication.java
```
访问 http://localhost:8761/ 查看Eureka仪表板
### 2. 创建服务接口
在 `lix-rpc-interfaces` 中定义接口:
```java
package cn.lix.sc.rpc.service.demo.service;
/**
* 远程服务接口定义
* 注意:接口本身不需要任何注解
*/
public interface UserService {
User getUserById(Integer userId);
String saveUser(User user);
void deleteUser(Integer userId);
}
```
### 3. 在服务端实现接口
```java
package cn.lix.sc.rpc.server.service.impl;
import cn.lix.sc.rpc.impl.common.annotations.RpcService;
import cn.lix.sc.rpc.service.demo.service.UserService;
/**
* 使用 @RpcService 注解标记为RPC服务
* 该服务会自动通过HTTP暴露给客户端调用
*/
@RpcService
public class UserServiceImpl implements UserService {
@Override
public User getUserById(Integer userId) {
// 业务逻辑实现
return new User(userId, "张三", "zhangsan@example.com");
}
@Override
public String saveUser(User user) {
// 保存逻辑
return "用户保存成功";
}
@Override
public void deleteUser(Integer userId) {
// 删除逻辑
}
}
```
在 `lix-rpc-server/src/main/resources/application.yml` 中配置:
```yaml
spring:
application:
name: rpc-server # Eureka服务名称(必须)
servlet:
multipart:
max-file-size: 10MB # 文件上传限制
max-request-size: 50MB # 请求大小限制
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
```
### 4. 在客户端注入并使用服务
```java
package cn.lix.sc.rpc.client.controller;
import cn.lix.sc.rpc.impl.common.annotations.RpcClient;
import cn.lix.sc.rpc.service.demo.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
/**
* 使用 @RpcClient 注解注入远程服务代理
* serverName: 对应服务端的 spring.application.name
* 支持自定义超时:connectTimeout、readTimeout(毫秒)
*/
@RpcClient(serverName = "rpc-server")
private UserService userService;
@GetMapping("/user/{id}")
public User getUser(Integer id) {
// 就像调用本地方法一样,实际通过HTTP调用远程服务
return userService.getUserById(id);
}
@GetMapping("/user/save")
public String saveUser(User user) {
return userService.saveUser(user);
}
}
```
在 `lix-rpc-client/src/main/resources/application.yml` 中配置:
```yaml
spring:
application:
name: rpc-client # 客户端应用名称
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
```
### 5. 启动服务
```bash
# 终端1: 启动Eureka
cd lix-rpc-eureka
mvn spring-boot:run
# 终端2: 启动服务端
cd lix-rpc-server
mvn spring-boot:run
# 或直接运行 RpcServerApplication.java
# 终端3: 启动客户端
cd lix-rpc-client
mvn spring-boot:run
# 或直接运行 RpcClientApplication.java
```
### 验证调用成功
```bash
# 调用客户端接口
curl http://localhost:8762/user/123
# 预期响应
{
"id": 123,
"name": "张三",
"email": "zhangsan@example.com"
}
```
---
## API文档
### 核心注解
#### @RpcService
在服务端标记RPC服务实现类:
```java
@RpcService
public class MyServiceImpl implements MyService {
// 实现方法
}
```
**参数说明**:
- `value` - 自定义Bean名称(可选,默认使用类名首字母小写)
- `enableStreaming` - 是否启用流式传输(文件下载,默认false)
- `contentTypes` - 支持的内容类型数组(可选)
#### @RpcClient
在客户端注入远程服务代理:
```java
@RpcClient(serverName = "service-name", connectTimeout = 5000, readTimeout = 10000)
private MyService myService;
```
**参数说明**:
- `serverName` - 必填,服务端的 `spring.application.name`
- `beanName` - 可选,当存在多个实现时指定Bean名称
- `connectTimeout` - 连接超时(毫秒,0表示默认)
- `readTimeout` - 读取超时(毫秒,0表示默认)
- `contentTypes` - 支持的内容类型数组(可选)
### 响应对象
#### RpcResponse
基础响应对象:
```java
// 成功响应
RpcResponse.success("result");
RpcResponse.success("result", costTime);
// 错误响应
RpcResponse.error("error message");
RpcResponse.error(exception);
```
#### EnhancedRpcResponse
增强响应对象,支持文件和请求ID跟踪:
```java
// 成功响应
EnhancedRpcResponse.success("result", costTime, requestId);
// 错误响应
EnhancedRpcResponse.error("error message", costTime, requestId);
// 文件响应(支持文件下载)
EnhancedRpcResponse.successFile(fileBytes, fileName, contentType, costTime, requestId);
```
### 异常处理
框架提供三种异常类型:
```java
// 业务逻辑异常(4xx语义)
throw BizException.error("用户不存在: {}", userId);
// 系统错误异常(5xx语义)
throw SystemException.error("数据库连接失败");
// 远程服务调用异常
throw RemoteException.error("服务暂时不可用");
```
所有异常都支持 `{}` 占位符替换。
### 内容类型支持
框架原生支持以下内容类型:
```java
public enum ContentType {
JSON, // application/json
MULTIPART, // multipart/form-data(文件上传)
OCTET_STREAM, // application/octet-stream(二进制)
TEXT_PLAIN, // text/plain
XML // application/xml
}
```
---
## 进阶用法
### 文件上传
```java
// 服务端
@RpcService
public class FileServiceImpl implements FileService {
public String uploadFile(MultipartFile file) {
String filename = file.getOriginalFilename();
// 处理文件
return "文件上传成功: " + filename;
}
}
// 客户端
@RpcClient(serverName = "rpc-server")
private FileService fileService;
public void upload(MultipartFile file) {
String result = fileService.uploadFile(file);
}
```
### 文件下载
```java
// 服务端(启用流式传输)
@RpcService(enableStreaming = true)
public class FileServiceImpl implements FileService {
public byte[] downloadFile(String filename) {
// 读取文件内容
return Files.readAllBytes(Paths.get("/path/to/" + filename));
}
}
// 客户端
@RpcClient(serverName = "rpc-server")
private FileService fileService;
public void download(String filename) {
byte[] content = fileService.downloadFile(filename);
}
```
### 自定义超时
```java
@RpcClient(
serverName = "rpc-server",
connectTimeout = 10000, // 连接超时10秒
readTimeout = 30000 // 读取超时30秒
)
private MyService myService;
```
---
## 项目优化历程
### 已完成的优化(4项)
✅ **线程安全加固** - 使用ConcurrentHashMap和LRU缓存替代普通HashMap
✅ **HTTP状态码规范化** - 遵循HTTP语义(200/400/401/403/404/422/500等)
✅ **文件传输支持** - 完整的文件上传/下载和Base64处理逻辑
✅ **参数转换优化** - 统一的JsonNodeConverter工具类消除代码重复
### 运行时配置
所有应用都支持以下关键配置:
```yaml
spring:
application:
name: your-app-name # Eureka中的服务名
servlet:
multipart:
max-file-size: 10MB # 单个文件最大大小
max-request-size: 50MB # 单次请求最大大小
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ # Eureka地址
server:
port: 8080 # 应用端口
```
---
## 故障排查
### 问题:客户端无法找到服务
**排查步骤**:
1. 检查Eureka是否启动:访问 http://localhost:8761/
2. 检查服务端是否注册成功(Eureka仪表板中应显示 `rpc-server`)
3. 确认 `@RpcClient` 中的 `serverName` 与服务端的 `spring.application.name` 一致
4. 查看客户端日志中是否有Eureka连接错误
### 问题:文件上传失败
**排查步骤**:
1. 确认已配置 `spring.servlet.multipart` 的大小限制
2. 检查文件大小是否超过配置限制
3. 确认服务方法参数为 `MultipartFile` 类型
4. 查看服务端日志中的具体错误信息
### 问题:请求超时
**解决方案**:
1. 在 `@RpcClient` 中增加 `readTimeout` 值
2. 检查服务端是否正常响应
3. 检查网络连接和防火墙配置
---
## 贡献指南
我们欢迎所有形式的贡献!如果您有改进建议,请:
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交改动 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 开启 Pull Request
---
## 许可证
本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。
---
## 联系方式
- 项目主页:[GitHub Repository](#)
- 问题反馈:[Issues](#)
- 电子邮件:sclx1220@163.com
---
## 更新日志
### v1.0.0 (2025-12-23)
**新增特性**:
- ✨ 线程安全的LRU缓存实现
- ✨ 完整的文件上传/下载支持
- ✨ HTTP状态码规范化
- ✨ 多内容类型自动协商
**优化改进**:
- 🔧 参数转换逻辑统一化
- 🔧 异常处理体系完善
- 🔧 代码复用率提升
---
**祝您使用愉快!** 🎉