java-app后台系统崩溃后的处理

系统架构:

系统用的是ngixn 、spirngcloud、nacos作为注册中心、gateway网管,数据库是mysql
数据库只有一个
服务也是单实例的
所以没有办法做负载均衡什么的。

问题描述:

公司近期开了几个活动之后由于访次数较多和代码问题导致系统挂了。
启动起来没多久后系统又崩溃了。
分析原因后发现是有首页一次性请求多个接口并且多个接口响应均在1~2秒,请求人数过多后有部分人出现了页面在等待响应的情况,等待响应人群因为响应时间过长又在频繁的切换刷新页面,系统也没对此类频繁刷新的请求进行限制,从而导致很多的无效请求产生,这些无效请求在未接收到响应之后连接就被断开了。
数据库压力比较大。

分析问题:

一打开首页就很卡顿,看控制台打开一次首页10多次请求,多个接口响应均在1~2秒。
其中红框中的这些请求里面有楼层商品,秒杀商品、特价商品等。

在这里插入图片描述
分析代码我发现查询活动商品需要经历大概以下步骤,我挑了其中两个列子。

查询满赠商品

SELECT * FROM ums_member_company_info WHERE id = 760; -- 返回客户的公司类型
SELECT * FROM ums_salesman_member_binding_relation WHERE company_id = 760; -- 返回用户绑定的业务员id
SELECT * FROM ums_salesman_info WHERE salesman_id =  3385; -- 返回业务员所在的省区
SELECT * FROM pms_special_goods_activity;  --  查询开启满赠活动的商品
SELECT * FROM pms_special_goods_activity_enable_area WHERE activity_id =1 and province_code = 6; -- 查询活动开启的省区 传入业务员省区
SELECT * FROM pms_special_goods_activity_enable_business_type WHERE activity_id =1 and business_type  =4; -- 查询活动开启的公司类型
SELECT * FROM pms_product_info WHERE product_id in('12','13');   -- 用活动返回的商品id去查询商品信息
SELECT * FROM pms_product_area_relation WHERE product_id in('12','13') and province_code =6;  -- 查询商品开放的省区,传入业务员省区
SELECT * FROM pms_product_price WHERE product_id in ('12','13'); -- 查询商品定价;
SELECT * FROM pms_product_images WHERE product_id in ('12','13'); -- 查询商品默认图片;
SELECT * FROM pms_product_stock WHERE product_id in ('12','13');  -- 查询商品的库存

查询秒杀商品

SELECT * FROM ums_member_company_info WHERE id = 760; -- 返回客户的公司类型
SELECT * FROM ums_salesman_member_binding_relation WHERE company_id = 760; -- 返回用户绑定的业务员id
SELECT * FROM ums_salesman_info WHERE salesman_id =  3385; -- 返回业务员所在的省区
SELECT * FROM pms_sec_spec_price_activity WHERE  FIND_IN_SET(2,business_type);  --  查询开启秒杀活动的商品,传入客户的公司类型
SELECT * FROM pms_sec_spec_price_activity_area WHERE activity_id =1 and province_code = 6; -- 查询秒杀活动开启的省区 传入业务员省区
SELECT * FROM pms_sec_spec_price_activity_product WHERE activity_id =1-- 查询秒杀活动开启的商品
SELECT * FROM pms_product_info WHERE product_id in('12','13');   -- 用活动返回的商品id去查询商品信息
SELECT * FROM pms_product_area_relation WHERE product_id in('12','13') and province_code =6;  -- 查询商品开放的省区,传入业务员省区
SELECT * FROM pms_product_price WHERE product_id in ('12','13'); -- 查询商品定价;
SELECT * FROM pms_product_images WHERE product_id in ('12','13'); -- 查询商品默认图片;
SELECT * FROM pms_product_stock WHERE product_id in ('12','13');  -- 查询商品的库存

导致系统挂掉的主要原因也在这里

  1. 之前的查询是先查询活动商品,然后在for循环里执行sql面查询商品的基础信息、价格、图片、库存。
  2. 活动、商品、都是需要用到客户的公司类型,以及绑定的业务员的省区,所以每次查询商品的时候都会先查询ums_member_company_info
    和ums_salesman_member_binding_relation 、ums_salesman_info 表。

其实上面的问题平时写代码也早就发现了,因为这个系统是第三方交付过来的,一开始设计就有不合理的情况。
一开始就有很多在for循环里面查询sql的问题。还有一些表可以合并的表拆分成了几张表,要优化需要改动以前的代码,且不说没有时间而且也属于吃力不讨好的行为。
随着后面新需求不断累加,开发时间紧张,后面又很多地方增加了根据登录门店公司类型、和门店绑定业务员省区来过滤商品过滤活动,只能在原有的基础上堆代码,导致后面在线人数增多系统崩溃。

针对以上的问题我们先后进行了四次优化。

四次优化

第一次优化

取消所有服务aop打印日志、只保留了sql日志,减少服务器io的压力
在这里插入图片描述

第二次优化

我们针对在for循环里执行sql进行了改造,全部都移除到了for循环外面,统一查询然后匹配商品id塞入需要的数据。为什么这样做呢?是因为当在for循环里面执行sql时会有以下情况

在for循环里面每次循环都打开和关闭数据库连接,这会消耗大量的时间。

优化后大概是这个样子,在循环外面统一查询,然后再塞入。
在这里插入图片描述

在优化后发现确实有所改善,但是接口的响应速度依旧不快,随后又进行了优化。

第三次优化

后面我们采用了比较极端的办法,将所有商品信息、商品的开放的区域、开放的活动、库存、价格、省区价格
用一个sql作为查询,执行一次sql查询所有的详细信息,然后将这个sql创建为视图
在这里插入图片描述

使用时是这样的、多个连表最终变成了一张表
在这里插入图片描述

这次上线之后接口相应的速度比之前快了好几倍,响应时间在100毫秒以下。但是这样处理也有问题
问题1:这个视图的sql比较复杂后期维护比较困难,sql不能出一点错误。
问题2:1个商品会对多个省区开放,所以一个商品返回的数据是商品*省区数因为视图是没办法传入参数的,所以取决于开始查询的第一张商品表的数据量大小,如果后续商品表数据量很大这个sql依旧会变慢
问题3:视图原本应该是比较通用的,这里把活动也维护进去了,而且用户能不能参与活动是在视图外面控制,最终的价格也是,-但是没办法领导要求的,要极致的速度

第四次优化

我们查询服务器日志发现有很多sql在查询用户表,数据库压力增大。

代码中所有查询活动或者查询商品,都需要先执行下面的sql查询到公司类型和业务员所在省区,也就是上面xml中查询方法里面的#{salesmanProvinceCode}、和#{companyBusinessType},sql如下:

SELECT * FROM ums_member_company_info WHERE id = 760; -- 返回客户的公司类型
SELECT * FROM ums_salesman_member_binding_relation WHERE company_id = 760; -- 返回用户绑定的业务员id
SELECT * FROM ums_salesman_info WHERE salesman_id =  3385; -- 返回业务员所在的省区

由于时间关系合并表肯定是来不及了,所以将这些数据统一丢入到了缓存中。
但是这样也会有问题数据库的数据如果更新了缓存没办法及时。
但系统处于崩溃边缘也管不了那么多了,所以最后我们给缓存设置了一天过期的时间,并在客户重新登录时更新缓存中的数据。
经过最后的优化系统在1000+以上人使用时也不会崩溃响应速度也很快。

在这里插入图片描述

总结

经过这次问题我发现大部分程序员都不愿意写sql,更加不愿意写连表的sql。

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Uni-app可以用于开发商城后台管理系统。通过使用Uni-app,开发者可以一次编码,同时生成多个应用程序,包括iOS、Android、H5、小程序等。开发者只需要使用Vue.js框架进行开发,而不需要考虑不同平台的差异,大大降低了应用程序的开发难度和复杂度。Uni-app的特点是使用Vue.js作为开发语言,可以在不同的移动端平台上共享组件库和业务逻辑代码,提高了开发效率和代码重用率。此外,Uni-app还提供了丰富的原生API和插件来实现更多功能。对于商城后台管理系统,开发者可以利用Uni-app的跨平台特性,快速构建多端应用,包括Web、iOS、Android、H5、小程序等,实现商城后台管理系统的功能和界面。全局配置文件page.json和pages.json可以用来对Uni-app进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar等,类似于微信小程序中的app.json的页面管理部分。通过配置这些文件,开发者可以灵活地管理商城后台管理系统的页面和功能。 #### 引用[.reference_title] - *1* *2* *3* [uni-app介绍](https://blog.csdn.net/weixin_63526054/article/details/130849946)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值