1. 背景
LZ 是一名在职的 Java boy ,花了上周一周的时间入门了 Rust 。周末使用 axum 写了个 web 项目,模拟了 SpringMVC 的架构。
2. 对比
均在我 mac 笔记本中进行测试
2.1 占用资源
这里可能不太公平。
Java 项目用了我之前的开源项目,虽然是个完整的项目但是也不是很大。没有打包成 jar ,使用 idea 启动,通过活动检测器根据 pid 查找发现占用内存494.2MB,JVM 配置:-Xms256m -Xmx4g 。
Rust 启动后发现内存占用为 2.0MB!!! 我人都傻了,虽然说是个很简单的项目,但是项目中必要的功能都有。
2.2 压测
为了进一步的看到差距,我开始了压测,代码如下。为了减少变量,没有加入 IO 操作,但也是正常的业务功能。
JAVA
@Override public AiUserVO loginTest(AiUserReq userReq) { CommonUtils.checkArgs(userReq.getAccountNo(),userReq.getPassword()); AiUser user = AiUser.builder().accountNo("admin").password("admin").name("admin").build(); user.setId(1941040891798581249L); //校验登录// checkLogin(user,userReq); AiUserVO result = ConvertUtils.beanProcess(user, AiUserVO.class); //处理用户角色// processUserRole(user,result); //生成 token String token = genToken(user); result.setToken(token); //放入 redis String key = CacheKeyEnum.format(CacheKeyEnum.ADMIN_LOGIN_KEY,user.getId(),token); SysCacheUserDto sysCacheUserDto = ConvertUtils.beanProcess(result, SysCacheUserDto.class); //删除原始 token// removeToken(user.getId());// redisCacheComponent.set(key,JSONObject.toJSONString(sysCacheUserDto),TimeConstant.ONE_DAY * 12); return result; }RUST
pub async fn login(user:UserReq)->Res<UserVO> { // 查询逻辑 let user_do = match query_user(&user.account_no, &user.password).await { Some(user_do) => user_do, None => return Res::build(FAIL), }; let mut user_vo:UserVO = user_do.into(); //加密 let token = match security_utils::aes_encrypt(&user_vo.id.to_string()) { Ok(token) => token, Err(_) => return Res::build(FAIL), }; user_vo.token = token; let key = SYSTEM_USER.key().format(&[&user_vo.id.to_string()]); //删除缓存 GlobalCache::del(&key); //放入缓存 GlobalCache::set(key,serde_json::to_string(&user_vo).unwrap()); Res::success(user_vo)}/** * 查询用户 */async fn query_user(account_no:&str,pwd:&str)->Option<UserDO> { let user = UserDO{ id:1912753992656158721, name:"admin".to_string(), account_no:"admin".to_string(), status:true, }; Some(user)}压测配置如下
Name: 线程组-30Number of Threads: 200Ramp-Up Period: 30 Loop Count: 1Scheduler: Duration: 90Name: 线程组-90Number of Threads: 200Ramp-Up Period: 30 Loop Count: 1Scheduler: Startup Delay: 90 Duration: 90压测流程如下
阶段一:0~30 秒启动 200 线程 → 持续到第 90 秒阶段二:从第 90 秒开始,30 秒内启动 300 线程 → 持续到第 180 秒压测结果对比如下
| 指标 | RUST | JAVA | 差异 |
|---|---|---|---|
| 平均响应时间 | 3~4 ms | 6~8 ms | ↑ 上升 50%~100% |
| 最大响应时间 | 17 ms | 26 ms | ↑ 上升 53% |
| 99% 百分位 | 11~15 ms | 15~20 ms | ↑ 上升 30%~45% |
| 吞吐量 | 6.7 → 10.0 req/sec | 6.7 → 10.0 req/sec | ✅ 相同 |
| 异常率 | 0% | 0% | ✅ 相同 |
| 数据包大小 | 294 B | 489 B | ↑ 增加 66% |
