当前位置:首页 > 综合

渗透后端

去年秋天,渗透后端我帮一个做电商的渗透后端朋友排查服务器异常。他的渗透后端订单系统每到下午三点就卡顿,运维查了三天,渗透后端CPU、渗透后端内存、渗透后端磁盘IO全正常。渗透后端最后发现是渗透后端某个促销活动页面的接口没加缓存,每次请求都去查一次商品库存表,渗透后端那张表有四百多万行。渗透后端一个没加索引的渗透后端查询拖垮了整个数据库连接池。

这就是渗透后端典型的后端问题——表面上看是A处故障,根子埋在B处。渗透后端前端调接口超时,渗透后端可能怪后端;后端响应慢,渗透后端可能怪数据库;数据库查询慢,可能怪表结构设计。一层层往下挖,像剥洋葱,剥到最后眼泪直流。

接口不是写完就完事

很多人写接口有个习惯:功能跑通就提交。参数校验?后面补。异常处理?先不管。日志打印?等出问题再说。这种接口上线就是埋雷。

我见过一个用户注册接口,没做手机号格式校验。结果有人用脚本批量注册,手机号字段塞了一堆乱码,数据库里存了几十万条垃圾数据。清理花了两天。还有个支付回调接口,没做签名验证,被伪造请求刷了几百笔虚假充值。这些都不是什么高深的技术问题,纯粹是写代码时少想了一步。

接口设计有个笨办法但管用:把自己当成攻击者,想想这个接口能被怎么滥用。参数能不能传空?能不能传超长字符串?能不能重复调用?想清楚这些,比事后加防护强得多。

数据库是后端的命门

后端性能问题,八成出在数据库。我自己的经验是,看到慢查询先别急着加缓存,先看执行计划。很多问题加个索引就解决了,根本不用上Redis。

有个做社交产品的团队,用户动态列表接口响应时间从200毫秒涨到3秒。他们第一反应是加Redis缓存,结果缓存命中率只有40%,因为每个用户的关注列表不同,缓存key太分散。后来把关注关系表的联合索引调整了一下,响应时间直接回到150毫秒。缓存不是万能的,索引才是基础。

表结构设计也是重灾区。有人喜欢用JSON字段存一切,觉得灵活。等到要按JSON里的某个字段查询时,才发现没法建索引,只能全表扫描。灵活性是有代价的,这个代价往往在数据量上来之后才显现。

日志和监控不是摆设

线上出问题不可怕,可怕的是出了问题不知道去哪找原因。我见过一些项目,日志打得乱七八糟,关键路径没有日志,不重要的地方刷屏。排查问题时像在垃圾堆里找钥匙。

我的习惯是:接口入口打一条请求日志,包含请求ID和关键参数;数据库慢查询单独记录;异常捕获时打印堆栈和上下文。不用多复杂,够用就行。监控也是,别只盯着CPU和内存,业务指标更重要。比如订单创建成功率、支付回调延迟、消息队列积压量,这些数字异常往往比服务器指标更早暴露问题。

缓存用不好就是灾难

缓存能扛住流量,也能制造麻烦。缓存穿透、缓存击穿、缓存雪崩,这三个词听着玄乎,说白了就是:查不存在的数据、热点key过期、大批key同时过期。解决办法也简单:空值也缓存、热点key不过期或加互斥锁、过期时间加随机值。

但真正难的是缓存一致性。数据库更新了,缓存怎么处理?先删缓存再更新数据库?先更新数据库再删缓存?两种都有问题。我的做法是:能接受短暂不一致的场景,用过期时间兜底;不能接受的,走数据库不走缓存。别为了用缓存而用缓存。

后端这摊事,说到底是细节堆出来的。一个索引、一行日志、一次参数校验,单看都不起眼,堆在一起就是系统的稳定性。写代码的时候多想一步,上线之后就能少熬一夜。

分享到: