# 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
![Java](https://img.shields.io/badge/Java-8+-red) ![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.3.9-brightgreen) ![Spring Cloud](https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR8-blue) ![License](https://img.shields.io/badge/License-MIT-green) 一个基于 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状态码规范化 - ✨ 多内容类型自动协商 **优化改进**: - 🔧 参数转换逻辑统一化 - 🔧 异常处理体系完善 - 🔧 代码复用率提升 --- **祝您使用愉快!** 🎉