网易首页 > 网易号 > 正文 申请入驻

公司搞末位淘汰,24岁员工从不加班产出是别人两倍,30岁老员工每天耗到10点没产出,结果准时下班的被裁了

0
分享至

公司搞末位淘汰,一个24岁的员工从来不加班,但产出是别人的两倍;另一个30岁的老员工每天耗到晚上10点,却没多少实际产出。最后,准时下班的人反而被裁了。


先不讨论这个淘汰标准合不合理。做后端久了,我看到“每天忙到10点”会先想到另一件事:有些系统也特别忙,线程很多、CPU很高、日志疯狂刷,看起来一刻没闲着,但真正完成的业务量并不高。我们线上就碰到过一次,订单服务CPU长期70%以上,线程池几乎打满,扩了机器还是扛不住,最后发现大量计算资源根本没产生有效产出。

CPU很忙,订单却没处理多少

当时是一个订单履约服务。支付成功后,消费MQ消息,查询订单、锁定库存、生成履约单,再更新订单状态。

最早业务量不大,这段代码一直没出过问题:

publicvoidhandle(PaySuccessEvent event){
Order order = orderMapper.selectById(event.getOrderId);

if (!"PAID".equals(order.getStatus)) {
return;
}

for (OrderItem item : order.getItems) {
Stock stock = stockClient.query(
item.getSkuId,
order.getWarehouseId
);

if (stock.getAvailable < item.getQuantity) {
thrownew BizException("库存不足");
}

stockClient.lock(
item.getSkuId,
item.getQuantity
);
}

fulfillmentClient.create(order);

orderMapper.updateStatus(
order.getId,
"PAID",
"FULFILLING"
);
}

代码不复杂,当时这么写也有理由:一个订单平均只有两三个SKU,库存服务RT不到20ms,每秒订单量只有几十。为了快速上线,把库存查询和锁定直接放循环里,成本最低。

问题出现在一次活动之后。订单峰值涨了差不多6倍,机器CPU从30%涨到75%,消费线程也从32加到了96,但MQ积压反而越来越严重。

监控第一眼很容易让人误判:CPU高、线程多,所以我最开始怀疑是JSON反序列化或者某段计算逻辑吃CPU。

order-consumer activeThreads=94
queueSize=1876
processCpu=76%
jvmCpu=71%


MQ lag:
10:05 12,431
10:10 28,903
10:15 51,772

于是先抓了JFR,又看了GC。结果Young GC很正常,没有频繁Full GC,CPU热点也没有某个特别夸张的方法。数据库慢SQL同样没发现问题,订单查询基本都在10ms以内。

这时候方向已经不对了。

真正的问题藏在线程状态里

继续看线程栈,才发现大量消费线程都停在HTTP调用上:

"order-consumer-71"
java.lang.Thread.State: WAITING
at CompletableFuture.get(...)
at StockClient.query(...)
at OrderHandler.handle(...)


"order-consumer-72"
java.lang.Thread.State: WAITING
at CompletableFuture.get(...)
at StockClient.lock(...)

再按调用链统计,一个8个SKU的订单会产生16次库存RPC:8次query,8次lock。

活动开始后库存服务本身也变慢了:

stock.query p95 = 86ms
stock.lock p95 = 112ms


order.handle p95 = 1843ms

这就解释了为什么加线程没用。单个消费线程两秒左右才能处理一个订单,其中绝大部分时间都耗在RPC等待和上下文切换上。96个线程看起来全部在工作,真正完成的订单却没增加多少。

而且原来的实现还有一致性问题:假设前5个SKU锁定成功,第6个库存不足抛异常,前面已经锁掉的库存怎么办?如果依赖MQ重试,同一条消息再次进来,还可能重复锁库存。

所以这次没有继续调线程池,而是先改库存接口粒度。

publicvoidhandle(PaySuccessEvent event){
Order order = orderMapper.selectForUpdate(event.getOrderId);

if ("FULFILLING".equals(order.getStatus)) {
return;
}

if (!"PAID".equals(order.getStatus)) {
thrownew BizException("订单状态异常");
}

String requestId = "FULFILL:" + order.getId;

List items = order.getItems.stream
.map(i -> new LockItem(i.getSkuId, i.getQuantity))
.toList;

BatchLockResult result = stockClient.batchLock(
requestId,
order.getWarehouseId,
items
);

if (!result.success) {
thrownew BizException(result.message);
}

orderMapper.updateStatus(
order.getId,
"PAID",
"FULFILLING"
);

outboxMapper.insert(
requestId,
"CREATE_FULFILLMENT",
order.getId
);
}

这里没有简单地把16次同步调用改成16个 CompletableFuture 。并发RPC确实能降低单个订单耗时,但会把压力直接放大到库存服务,活动峰值下很容易把下游连接池打穿。

我们最后让库存服务提供批量锁定接口,一次请求完成整单库存校验和锁定。

幂等不能只靠订单状态

批量接口里还有一个关键点: requestId 必须参与幂等,否则订单服务超时后重试,库存服务其实已经成功,第二次请求仍然可能重复扣减。

库存侧用了唯一键兜底:

CREATEUNIQUEINDEX uk_stock_request
ON stock_lock_record(request_id);

核心逻辑不是先查再插,而是让数据库约束处理并发:

@Transactional
public BatchLockResult batchLock(LockCommand cmd){
try {
lockRecordMapper.insert(
cmd.requestId,
"PROCESSING"
);
} catch (DuplicateKeyException e) {
return queryPreviousResult(cmd.requestId);
}

int affected = stockMapper.batchLock(
cmd.warehouseId,
cmd.items
);

if (affected != cmd.items.size) {
thrownew StockNotEnoughException;
}

lockRecordMapper.markSuccess(cmd.requestId);
return BatchLockResult.success;
}

库存更新本身也不能先 select 再由Java判断,否则并发订单可能同时读到“库存充足”。

实际SQL直接把库存条件放进更新:

UPDATE sku_stock
SET available = available - #{qty},
locked = locked + #{qty}
WHERE warehouse_id = #{warehouseId}
AND sku_id = #{skuId}
AND available >= #{qty};

affected_rows = 0 就说明库存已经不足。批量锁定在同一个本地事务中执行,只要其中一个SKU失败,整单回滚,不再留下“前5个成功、第6个失败”的半完成状态。

订单事务里也不能直接创建履约单

库存问题解决后,还有一个坑:如果库存已经锁成功,订单状态也更新成功,但调用履约服务时超时,MQ重试会再次走完整流程。

所以最终没有在订单事务里直接调用履约服务,而是落一条outbox事件:

@Transactional
publicvoidconfirmFulfillment(Long orderId){
int rows = orderMapper.casStatus(
orderId,
"PAID",
"FULFILLING"
);

if (rows == 0) {
return;
}

outboxMapper.insert(
"FULFILL:" + orderId,
"CREATE_FULFILLMENT",
orderId
);
}

后台任务只负责可靠投递:

SELECTid, biz_key, payload
FROM event_outbox
WHEREstatus = 'NEW'
AND next_retry_time <= NOW
ORDERBYid
LIMIT100;

发送成功改成 SENT ,失败记录重试次数并延迟下一次执行。履约服务继续按 biz_key 做唯一键幂等。这样数据库事务只负责本地状态和事件落库,不再把远程RPC塞进事务里长期占着数据库连接。

改完之后,同样流量下消费线程从96降回32,订单处理p95从1.8秒降到300ms以内,MQ也不再持续积压。这个问题最有意思的地方是:监控上所有线程都“忙”,但大量工作其实只是等待、重试和重复调用。

回到末位淘汰这件事,工程系统里同样不能拿“忙了多久”衡量产出。线程跑到晚上10点没有意义,最终还是得看吞吐、延迟、错误率,以及到底完成了多少有效业务。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
独家|大众中国:已启动涉星宇股份相关投诉专项调查,“尊重劳动者合法权益”贯穿于供应链管理

独家|大众中国:已启动涉星宇股份相关投诉专项调查,“尊重劳动者合法权益”贯穿于供应链管理

澎湃新闻
2026-09-01 10:06:30
1.4亿买来坐板凳!三场57分钟,皇马最贵替补,穆帅心里有数

1.4亿买来坐板凳!三场57分钟,皇马最贵替补,穆帅心里有数

林子说事
2026-09-02 01:35:18
宇树科技回应“超100元报销需王兴兴审批、只有罚几乎没有奖”:很多内容不实,切勿当真

宇树科技回应“超100元报销需王兴兴审批、只有罚几乎没有奖”:很多内容不实,切勿当真

都市快报橙柿互动
2026-09-01 19:58:54
曼联压哨签左闸失败过程揭秘!断定卡里克左后卫够用,明夏再买霍尔

曼联压哨签左闸失败过程揭秘!断定卡里克左后卫够用,明夏再买霍尔

罗米的曼联博客
2026-09-02 07:00:21
全网刷屏!网友给丁荭画同款自画像,终于看懂大众愤怒在哪

全网刷屏!网友给丁荭画同款自画像,终于看懂大众愤怒在哪

流云随风去远方
2026-08-28 11:12:40
河南一小学新生名单惊艳老师:“子涵”时代已经过去,取自国风典籍的名字格外亮眼,重名率也降低不少

河南一小学新生名单惊艳老师:“子涵”时代已经过去,取自国风典籍的名字格外亮眼,重名率也降低不少

河南交通广播1041
2026-09-01 23:18:51
斯英国公开赛!2日赛程出炉,赵心童VS韦尔斯,雷佩凡VS塞尔比!

斯英国公开赛!2日赛程出炉,赵心童VS韦尔斯,雷佩凡VS塞尔比!

阿月说体育
2026-09-02 04:30:58
“中俄美”的三角关联已然出现了剧变!过去中美俄三强鼎立,两弱制衡一强, 俄乌冲突后俄罗斯实力被大幅牵制,已经和中国不在一个层级

“中俄美”的三角关联已然出现了剧变!过去中美俄三强鼎立,两弱制衡一强, 俄乌冲突后俄罗斯实力被大幅牵制,已经和中国不在一个层级

扶苏聊历史
2026-09-01 17:57:55
郑丽文回应“请辞党主席”,什么情况?

郑丽文回应“请辞党主席”,什么情况?

新民周刊
2026-09-01 09:11:33
滔搏拿下美国前卫户外品牌中国运营权,三年引入五个“冷门”

滔搏拿下美国前卫户外品牌中国运营权,三年引入五个“冷门”

南方都市报
2026-09-01 11:54:17
全红婵近照变化太大了,熬过了最难的发育关,小姑娘彻底长开了,模样跟以前判若两人

全红婵近照变化太大了,熬过了最难的发育关,小姑娘彻底长开了,模样跟以前判若两人

In风尚
2026-08-22 06:04:58
美国人警告菲律宾:中国一旦填了黄岩岛,下一个就轮到巴丹群岛!

美国人警告菲律宾:中国一旦填了黄岩岛,下一个就轮到巴丹群岛!

讲者普拉斯
2026-09-01 10:30:41
高圆圆透露和赵又廷谈过身后事:两人有时开玩笑,我说希望我先走,他说那也行,我来收拾后续

高圆圆透露和赵又廷谈过身后事:两人有时开玩笑,我说希望我先走,他说那也行,我来收拾后续

韩小娱
2026-09-02 06:38:37
铁了心拉蒙古国入伙,俄罗斯提前放信号,要在上合和中方敲定大事

铁了心拉蒙古国入伙,俄罗斯提前放信号,要在上合和中方敲定大事

知法而形
2026-09-01 15:36:20
老干部因私出国「四不可」

老干部因私出国「四不可」

家传编辑部
2026-09-01 10:28:18
唏嘘!渣叔爱将连续2年被利物浦外租 曾获欧青赛MVP

唏嘘!渣叔爱将连续2年被利物浦外租 曾获欧青赛MVP

球事百科吖
2026-09-02 06:00:29
在北京,大批外地人已经开始撤退了

在北京,大批外地人已经开始撤退了

经济学教授V
2026-08-31 19:14:09
Here we go!罗马诺:恩佐加盟曼城,转会费超1.25亿英镑

Here we go!罗马诺:恩佐加盟曼城,转会费超1.25亿英镑

懂球帝
2026-09-02 00:07:14
500名内分泌科医生强调:只要确诊糖尿病,患者一定多关注这几点

500名内分泌科医生强调:只要确诊糖尿病,患者一定多关注这几点

今日养生之道
2026-09-01 10:29:06
任贤齐新车刚上路就被剐蹭,两车门变形心疼不已 才帅了没几天

任贤齐新车刚上路就被剐蹭,两车门变形心疼不已 才帅了没几天

小椰的奶奶
2026-08-30 14:18:29
2026-09-02 07:15:00
时尚的弄潮
时尚的弄潮
快乐学习化学
922文章数 9757关注度
往期回顾 全部

头条要闻

特朗普:终极打击一旦降临 伊朗将所剩无几

头条要闻

特朗普:终极打击一旦降临 伊朗将所剩无几

体育要闻

大爹杨瀚森,让中国男篮有了容错空间

娱乐要闻

孙宇晨破防,他无法接受孙割这个名字

财经要闻

"电梯亲热门"后 惠州首富给老婆转238亿

科技要闻

抖音突发推荐算法大面积错乱!

汽车要闻

山城试驾启源Q06 不光是智驾好用还有700km的续航

态度原创

亲子
健康
艺术
游戏
家居

亲子要闻

小菲法国学习,筱梅陪同!筱梅妈妈发来小宝宝照片,萌翻网友!

睡时发生脑梗,抢救时间该怎么算?

艺术要闻

刘晓庆竟然还会画画?

DLSS 5普及后游戏优化没救了?玩家:还得说谢谢

家居要闻

2026建博会(广州) 公装联探展交流活动

无障碍浏览 进入关怀版