• 测试那些事儿-后端


     

    记一次服务由amq切rmq时线上事故:

     

    背景:

    订单服务有过两次宕机,分析是原因指出当时订单服务连接amq集群时超时,服务一直尝试连接,导致服务夯死。研发决定把amq消息中间件切成rmq。

    切中间件涉及到40多个服务,经过整个研发组讨论,定制了严格的上线方案。

    事故:

    es服务生产环境连接消息集群配置错误,服务发完灰度后没有在rmq的console确认es服务是否连接到了rmq集群,之后发生产导致了事故。

    反思:

    为什么没有按照流程确认服务是否正常连接到了rmq?

    上es服务之前,很多边缘服务切rmq都已经上线了,并且都没出问题,导致测试和开发都放松了,没有按照流程走。

    es服务听订单服务消息,变更es库订单相关数据。不管是什么原因,一但消息积压没有在业务允许的时间范围内及时消费,es服务再消费这些过时消息,导致订单状态不一致,就会引起问题。

    所以,最后研发讨论,es消费消息时要加一层check机制,当一条消息没有及时消费时,要查询原始订单数据更新es库。

    已上线的老接口改动慎重:

    1. 接口返回数据结构不能变,返回数据字段的类型不能变。

      开发因为开发周期或者个人习惯,很少做返回数据异常的兼容,如果改变接口返回数据,会导致调用方解析异常。

    2. 业务逻辑谨慎变动。

      中台校验验证码接口,一个验证码可以多次使用。安全组的同事说这块不符合安全规范,中台(老服务,已经换了几波人了)开发看了代码,发现里面有段备注说个别手机校验短信验证码时请求了多次接口。然后找端上问了一圈,说那些机型已经没了。于是就改了,结果上线后多数闪送员反馈修改、注销手机号时校验手机验证码报验证码失效。

      稳妥的做法应该是线上加日志,看看那些业务线存在多次校验的情况,再决定是否要修改。

     

    记一次内存溢出问题:

    订单画像服务提供订单是否与画像匹配接口,该接口处理业务时的流程是:将画像所有规则加载到内存,然后遍历订单是否命中某一条规则。

    第一期该服务提供手动生成画像,生成画像规则颗粒度大,一个画像配置生成的规则不超过500条。所以上面的处理方式没问题。

    订单画像服务之前由开发A负责,A离职后B负责。画像服务支持提供系统生成画像,生成画像规则的颗粒度很小,一个画像生成的规则超过了10万条(12M),查询一个订单是否命中该规则时加载12M,订单高峰期加载到内存的数据过多,最终导致内存溢出。

    记一次接口超时问题:

    CRM系统调大数据接口查询商户店铺(一个商户下有N多个店铺),CRM开发处理方式是每次传10个店铺ID查询数据,多次调大数据接口直到查完一个商户下所有店铺的订单数据,将数据组装后返回给前端展示。

    商家版放开了店铺创建数量后,线上有一个商户账号下创建了1千多个店铺,加载该商户店铺订单数据时前端报接口超时。查询该商户店铺订单数据时中间调了10多次大数据接口,一次调用400ms左右,10次就4s了。

    这里有个知识点:内存处理数据是纳秒级别的,服务相互调用是毫秒级别的,如果两个服务之间有交换数据的需求,在内存消耗允许范围内尽量做到1次链接将所需数据拿到,然后在内存中处理。

    数据库数据同步问题:

    主业务变动,device表中新增一个字段,忘记将该字段同步至分支业务(音箱平台)的device表中,导致音箱设备全都不能正常连接。

    原因:每个数据表对应一个model(java类),两个平台用一个model,一边增加了字段,另一边数据表没有这个字段,就会报找不到这个字段

    如何避免问题:

    ①测试角度:梳理出所有分支业务与主业务的关联关系,给每个分支业务写一个冒烟脚本,每次主业务有变动后,所有相关分支业务都跑冒烟测试

    开发人员惰性引发的bug:

    1)接口返回的data值(里面包括一大堆数据的值)null,前端开发认为这个数据没意义就没处理,结果页面从当data值不为null切为null的页面时,数据没有刷新。

    5.开发人员大意引发的bug:

    1)用户数据通过大数据获取,其中本月/上月数据在同一条记录中,计算本月均值时拿的是本月份天数,计算上月值时拿的月份依旧是本月份天数(不同月份天数有时不一样)。

    6.B/S架构新版本上线注意事项:

    对于登录等一些页面,新版本上线后,要提醒运维将新版本登录页面强推给用户,不能使用缓冲!

    7.线上服务器跟换IP:

    找开发确认要更换的IP是否在代码中有直接用到!!不知道出于何种原因,总有些项目中开发直接使用IP而不是域名的情况。。

    8.运维人员上线bug:

    有个项目线下测试没问题,上线后,session验证拦截器获取不到order_search_api给的session,拦截器在这个项目中也是新发版。

    拦截器开发各种排查,死活找不到问题;运维人员重装服务器系统、对比各种代理配置,无结果。

    最后发现,线下环境所有项目共用一个名为common的redis集群,线上redis集群分别为common、sso,拦截器所用的session配置在名为sso的redis集群中(sso redis集群中没有存session的key)

    9.前端组件对特定字段有特定“解释”引发的bug:

    项目中前端引用的下拉框组件以disabled字段判断下拉项是否可用,后端开发在某次需求中将一个老旧口新增了一个字段“disabled”并将值默认返回true,结果导致该组件下拉项不可选中。

    10.旧数据导致app崩溃:

    之前商户名称没有做限制,某期需求“商户名30个字符,编辑时光标放在商户名输入框后面”。有一条旧数据商户名38个字符,编辑该条数据,app崩溃。

    11.sql中查询条件变更导致慢sql拖垮服务器:

    之前商户数据是根据手机号查询(有索引),因商户更改手机号导致商户的历史数据查询有bug,开发将查询条件改为userId(无索引),测试环境数据量级不够,没有触发慢sql,上线后查询触发慢sql打满服务器cpu导致服务异常。

    对于查询的数据量级很大的接口,上线前一定要走压测。

    12.数据的边界值一定要让产品、业务确认:

    业务反馈线上导出数据每次只能导出5千,能否支持导出5万。

    第一回合:产品(新来的)一拍头让开发支持5w,结果线上有7w的数据量,导出时报错。因为Excel每张表最大支持65536行,开发未分sheet。

    第二回合:开发分sheet存数据。上线后业务导出40w数据,导致服务卡顿

    12.数据的边界值一定要让产品、业务确认:

    问题:线上有时候有人登录后显示别人的身份信息(中台开发说是api层错值了,api层确认没问题,互相扯皮,这个问题持续了好两三天后开发开始重视了)

    原因:父类整一个静态变量,线程中的变量没销毁前(同一毫秒)另外一个人登录就会拿到第一个人的身份信息。

    13.数据库新增字段引发的bug:

    数据库新增字段,开发忘记更新某些sql,导致数据提交、更新失败导致bug。所以某个表中新增了字段,问清楚涉及到改表的业务有哪些,记得回归。

    14.给内部平台调用的接口其他组开发用给公网用户调用:

    优惠券系统开了个充值返券信息列表接口,该接口多表查询,券系统开发考虑是个内部接口,没在意接口性能问题,就提供给券及CRM内部系统使用了。结果CRM系统将改接口暴露给了商户端,商户端展示充值返券信息时调用了该接口,该接口访问量上升,导致数据库性能下降。

    开发的问题在于:系统之间调用接口时没有相互沟通。

    商家端测试问题在于:高流量接口没有考虑性能测试。

    15.记一次不同组程序员设计模式的潜在问题:

    业务:用户端、闪送员端读取某个城市是否开启了某一功能,决定是否展示相应的模块。系统组支持配置及提供两个端查询配置。

    用户端开发让系统组开发提供接口查询城市配置;闪送员端开发让系统组开发在配置变动时发mq消息,将配置同步一份保存在自己的业务库,读取自己的业务库数据决定是否展示相应模块。

    用户端开发图省事,不考虑系统间解耦,这种设计存在的潜在问题是:当系统端服务挂了,用户端相应模块也就不好用了;另外,也增加了系统组服务的性能压力。

  • 相关阅读:
    Laravel中Contracts的理解和使用
    laravel 服务容器的用法
    linux 安装go环境
    权限设计-系统登录用户权限设计
    Laravel 中使用 JWT 认证的 Restful API
    使用laravel-wechat微信支付
    composer查看全局配置
    如何在 Laravel 项目中处理 Excel 文件
    laravel各种请求类
    Centos创建用户并授权
  • 原文地址:https://www.cnblogs.com/FengZiQ/p/9229473.html
Copyright © 2020-2023  润新知