Bug的产生,通常分为三种类型:逻辑漏洞、越界访问、条件考虑不全面。
为了便于你理解,我以女朋友来大姨妈举例。
某日,你收到了女朋友的一条微信,跟你说自己来大姨妈,肚子疼。这时,你要写一段文字回复, 这段回复你就可以认为是你写的一段代码。 这段代码需要达到的目的是让你的女朋友感受到你对她的爱,增进(至少不减少)你俩之间的感 情。我们可以把这个目的当成你对自己提出的这段代码背后的产品需求。
1,逻辑漏洞:
你:我叫外卖来给你买个热饮吧。
女朋友:滚!你是想让我从床上趴下去给外卖小哥开门么?
分析:低级错误,程序执行后无法达到想要效果。
2,越界访问:
你:我给你室友打个电话,让她帮忙照顾下你。
女朋友:滚,谁让你联系我室友的。
分析:访问了非法区域,造成程序崩溃。
3,条件考虑不全面:
你:亲爱的,我早就知道有这天,所以暖宝宝、热水壶、痛经药....(此处省略一万字),我都给你准 备好了,就在家里。
女朋友:我现在在地铁站。
分析:你以为你万无一失,但你永远都不知道输入参数究竟是什么! 除了上面三种主流错误,还有一大堆,这里就不细说。 我跟其他答主不一样的是,我不光要告诉你们Bug是如何产生的,我还要跟大家解释我们程序员平 常如何防范未知Bug,因为你们也看到了,Bug就像你女朋友的微信,你永远不知道她下一句攻击 你哪个点。
所以,这里要祭出利器:异常捕获。
异常捕获一般依靠try,catch语句。很好理解:try(尝试)一下,如果有问题,直接捕获 (catch)住,防止程序崩溃。
1、这里同时存在三个问题:
-
问题排查以及快速恢复
-
异常数据修复
-
服务高可用,规避服务宕机
2、先抢通业务
当发现服务器宕机后,最关键的是抢通业务,而不是抢修服务器。
因此,需要做应急方案。最好准备2个网站服务器,他们存放的内容相同,而ip不同,并且机房的地理位置不同。这样第一时间发现宕机问题后,可以迅速的通过修域名记录,指向目前正常的网站空间。而且2个主机,同时宕机的可能性就大大降低了。
3、服务器崩溃问题定位
-
内存溢出,磁盘资源耗尽
-
线程死锁,进程过多或者不断创建,耗尽资源导致
-
数据库慢查询,连接数过多,临时表不够用,程序死锁
-
主备数据不一致
-
应用程序异常
-
流量负载过大
-
DOSS攻击
-
散热问题
4、异常数据修复
-
写数据做事务控制,保障数据安全。
-
磁盘备份,重启服务时恢复数据。
-
记录关键日志。
5、服务高可用
-
服务多实例集群部署,负载均衡策略访问,做好服务降级、服务限流。
-
数据库读写分离、分库分表方案。
-
做好服务性能测试、压力测试。
开发中常见问题:
空指针异常,判断传入参数是否为空
强转Integer,对象有可能是非数字
金额数值计算精度问题,金额一般都是用BigDecimal
事务不起作用没有回滚,异常被try.catch吃了或数据源没有配置事务管理器
编码不规范,各有各的习惯,造成太多重复代码块
遇到问题不使用Debug调试,就一直耗着猜问题
业务复杂时,客户端响应时间较长的请求,加提示进度条让用户等待
Redis缓存穿透,一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统(DB)造成很大的压力。这就叫做缓存穿透。
1、对一定不存在的key进行过滤。
2、对查询结果为空的情况也进行缓存,缓存时间设置短一点。
Redis缓存雪崩,当缓存服务器重启或者大量缓存集中在某一个时间段失效时,会给后端系统(DB)带来很大压力。导致系统崩溃。
1、在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。
2、做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期
3、不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。