项目重构过程中碰到的一些严重的问题整理

作者: admin 分类: 异常处理 发布时间: 2018-06-02 00:12  阅读: 280 views

平台数据

2018年初,总用户数100w+,活跃用户20w+。

日均PC端的PV10W+。

用户量集中在IOS/安卓端。

每天有多个定时任务运行,数据量最大的是还款、投标、对账等任务。

 

 

重构前

重构后

语言

PHP【80%业务】JAVA【20%】

JAVA核心,PHP做活动

数据库

Mysql一主三从,两个库

mysql/mycat 十三个库

中间件

mongodb/redis/MQ

mongodb/redis/MQ

 

dubbo/zookeeper

dubbo/zookeeper

   

dms/job/xdiamond

日志

log4J

log4j

应用服务

PHP23个task/java4个服务

java11个服务

服务器

30多台中高配

100多台中低配

服务器变更前后,价格差别不大。数量增多。

分为开发、测试、预发布、发布环境;预发布和发布环境平均每个服务四个节点。

 

 

1. mysql5.6.16版本问题

背景:老项目线上半年多,出现过3次数据库重启情况。800多张表,50多张表都有触发器。

现象:查询分析器可以正常执行sql查询,数据库中数据正常,针对一个简单的单条插入sql,在执行触发器时一直查不到数据。

原因:版本问题,占用内存过大

处理:数据库重启之后就好了。之后msyql版本升级,之后随着业务量增加,再无出现过。

 

 

2. 数据迁移问题

背景:项目重构之后,数据库全部变更,要在上线凌晨当天将老库数据全部迁入到老库。所有web端、移动端首页要保证能够访问,但是不操作新数据。当时所有的定时任务关闭。【整个上线过程7小时】

现象:1. 导数据时发生了两次中断,导致整个数据迁移过程延长了1个小时左右时间。【原本1个小时】

原因:

1. 管理后台有人进入操作数据【后关闭】为了保证数据一致性,中断迁移过程

2.首页展示数据量大,相关表数据量多,很多用户凌晨在测试官网是否能打开,导致数据迁出有卡顿,进而超时停止。

处理:关闭所有服务器,官网指向静态页面,APP无数据展示。

 

3. 数据库一主三从,读写分离

背景:项目上线后,当数据读写压力大的时候,后台资金流水日志经常出现nullpointerException错误,经过几天的积累,涉及用户数据1万条左右。

现象:业务代码逻辑正常,单独测试、或者模拟小数据量测试的时候没有出现。但是线上每天数据量一上去了,就会出现多次。

原因:

数据库分主从之后,代码格式没有改变。

因为:主库写完数据,同步到从库需要时间。如果在时间内进行查询,则会出现查不到的情况。

处理:在方法头部加 @transactional(). 事务默认走主库。

 

4. Sql语句审核

背景:客服要查询用户的详细信息,所以在后台开发了一组关于用户详细信息的页面。

现象:新手写了一个联合查询语句,两张表,没有任何条件筛选。页面功能执行后,其他所有业务逐渐停滞,后来官网无法打开,数据库进程杀不掉。

原因:两张大表的数据 用户日志表 1200w * 用户表 200w。 形成笛卡尔积

处理:1. 重启数据库服务器。

2. 加强代码审核

3. 建立DMS审核工具,强制所有查询都需要加limit限制。所有语句都是标准化格式。【后期逐渐把正式数据库直连的权限没收,只能通过DMS去查询处理】

 

 

5. 三方配置相关

背景:项目在对接背景银行存管时,或者三方支付公司时。有相关的正式/测试环境配置一部分在公司,一部分在北京银行处。对接了融宝、易宝、连连、宝付等多家公司。

现象:面临公司/三方程序大升级时,配置搞错。导致真实用户的钱到了测试环境上/或者测试的钱到了正式环境上。双方都有配错过。

处理: 存管环境:开放了两条内网专线,分测试/正式。

A.运维首先将公司服务器地址针对两个ip做限制,正式服务器的无法访问测试的银行通道,或反之。

B.将配置提取到配置中心去。针对发布/预发布/测试/本地的启动脚本,指定对应的配置规格。将权限完全控制从开发手中拿走。

C.面临银行大动作的时候,针对支付接口做代码控制。从查询接口返回的数据分析运行环境的正确性,如果验签失败,就发送短信提醒相关负责人。

 

6. 备用电源

背景:公司有个机房,主要放置几台主机,和杂物。服务器存放本地/测试相关服务等。

现象:天气过热的时候,机房温度过高,主机断电自我保护。导致资料丢过几次。

处理:清理杂物,保持通风,放了2台电风扇,后来买了UPS【不间断电源】

 

7. 提现多次到账

背景:用户发生提现操作

现象:到账两次

原因:

1. 代码逻辑不严谨,没有做状态判断,幂等性验证。

2. 三方处理失误

处理:1. 修改代码,增加逻辑验证性。

2. 加强对账的正确性,尽早的处理多到账问题。

 

 

8. 红包优惠券/活动奖励等

背景:为了提高用户的积极性,通过举办一些活动发放奖励来实现。有一种是邀请的人越多,奖励越大

现象:活动期间,有天晚上,短信发送量异常【平常没有这么大量】,号码很多是空号,号段相似

原因:通过查日志,一段时间内,有大量不明号码注册,调用短验接口,邀请链接相同。

处理:后台接口禁止 该号段的 请求。

 

9. 跨库查询 mysql innoDB 存储引擎

背景:为了分散业务模块,对库进行了拆分。一个大库,拆成了9个库。每个库一个实例

现象:比如:库A,库B,库C…..

单库查询

1. 当jdbc_url 数据库连接串后指定为默认库A时。

查询库B 如果这种写法select * from 表 会报库B的表不存在。

如果指定 select * from 库B.表 查询正常;

2. 当连接串后没有指定默认库时

第一次查询正常,第二次查询如果是其他库,报错 表不存在。和上面类似。需要指定库名

多表查询

当连接串后指定默认库A或者没有指定默认库时

select * from 库A.表 inner join 库B.表 on …….

都会报错,库B的表不存在

原因:不是同一个实例

处理:通过mycat中间件将两个实例库映射到同一个地址上,供查询处理。

 

10. 业务效率更改

背景:公司有一款产品,销量好,产生了比较多的数据。相关数据分表等 108张,投资/还款/日志记录千万左右。

上线后每天11点开始投标操作10w条左右数据;3点左右还款操作10w条左右的数据;过程中产生40w条作用的日志记录。

其他业务正常进行。记录是通过塞到MQ中进行消费,有很多验证,任务链条较长。

业务:把昨天的投标数据/还款数据,在今天进行拆解、包装,和银行进行接口调用完成数据处理。

现象:刚上线时,这两个任务节点需要花费时间10个小时左右,并且会对日常操作产生影响。

原因:可能业务、数据库、代码等多个原因。

处理

第一版:主表、分表加索引【原来有部分索引,是根据业务对一些查询结构进行了索引优化】

效果:比较明显,时间加快了一半以上。全部完成共5-6个小时。但还是不理想,需要人手监控

第二版:业务不变,代码处理结构变化【使用多线程10~15个;数据分批提交;一些数据的存储优化】

效果:数据的存储优化【减少不必要的传递、对象创建等】效果较小

数据分批提交【针对塞到MQ的过程】减少了阻塞,降低了对正常业务的影响。【时间等待上】

多线程【线程数量的控制】效果比上面两个明显,但是收到了银行的警告,对他们压力过大,需要申请,

且线程数控制为8个左右。

整体时间缩短了1个小时左右,但是对中午用户的操作影响过大,还需要优化。

第三版:将消费者按业务拆分成了3个。按照业务量的大小进行消费的划分,并启动了4个消费服务。

效果:对日常操作的影响效果明显,基本没有了延时。整个任务控制在2个小时左右可以完成。

第四版:将部分业务前置【很多部分提前计算处理,涉及到业务的大改动了】

预估:时间要再缩短一半以上。

 

11. 日志处理

主要针对错误日志,以及业务计算日志。

在dubbo服务调用之间,web层与dubbo调用之间。将调用方法的入参、出参按照业务分类,进行输出。并标记特定标识。用于排错。

如:订单ID-用户ID-类名-方法名-数据标识

调用存管的接口存放在mongodb中,

存放业务名称、接口名称、发生时间、响应时间。 超过10s的短信通知。

业务日志用log4j存储。保留近两个月的数据


   原创文章,转载请标明本文链接: 项目重构过程中碰到的一些严重的问题整理

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注