课前语言提醒,第三方目前支持最大的并发量是200,目前平台高峰期并发量会在2000。
课前提醒时,不在同一时间推送提醒消息,间隔1s或多s提醒,分批次处理消息推送。
1、验证分批次处理推送消息,即按时间随机散列分布在5分钟
2、验证课前提醒推送到消息中心接收,再到呼叫服务中心,推送消息无延迟、不重复、不丢失,呼叫成功率100%,不出现课前提醒在上课时间之后的情况。
3、测试环境下同一时间上课学生数多大时会出现性能问题
每隔半小时系统定时扫描lessons表,将符合课前提醒条件的数据同步到mongodb计划表,最终将这些消息分批次推送给消息中心,消息中心接收这些消息,保存在t_message_log_bus_buffer表,发送给呼叫中心,待呼叫完成后,调用呼叫中心的接口,收集打电话事件的数据,保存在t_msg_log表。分析表中数据得出测试结果。
准备多组同一时间上课的数据,统计打电话事件结束后表中相关数据
测评课数 |
上课时间 |
1000 |
18.01 |
1500 |
18.31 |
2000 |
19.01 |
2500 |
19.31 |
3000 |
20.01 |
lesson表的数据需要符合下面条件才可以推送给消息中心:
SELECT * FROM lessons WHERE lessons.client_state = 0 AND lessons.tea_id IS NOT NULL AND lessons.is_close = 0 AND lessons.deleted_at IS NULL and lessons.les_start_time like '2019-05-14 19:01%' and lessons.les_type='test-lesson' and les_subject ='语文'; |
因此我们需要准备一定数量的老师id 、学生id、 课程id 并且课程id不可重复。
老师id 取自teachers表,sql如下:
select t.id from teachers t join users u on u.id=t.user_id where u.mobile is not null order by u.id desc limit 7000; |
学生id 取自students表,sql如下:
select s.id from users u join students s on u.id=s.user_id where u.mobile is not null order by id desc limit 7000 ; |
由于课程id 不能重复,所以需要在courses表中插入一定数量的数据 ,取出课程id 用于在lesson表中新增测试数据 。
jdbc:mysql://test.db.weikeu.com:3306/test?allowMultiQueries=true&characterEncoding=utf8 |
需要两个请求,第一个JDBC请求,是向courses表中插入数据,并取出新增数据的courses id 。这里我们用一个变量couid保存id,并在下一个JDBC请求中引用。
INSERT INTO courses (tea_id,stu_id,les_subject,subject_name,subject_code, grade,subject_cat,price,is_paid,total_mins, out_trade_no,pay_title,pay_url,pay_url_expired_at,pay_history, transformed,created_at,updated_at,deleted_at,price_unpaid, total_mins_unpaid,had_test_lesson,course_situation,is_special_cou,course_type, color,cid,bu,remark ) VALUES ('${teaid}', '${stuid}', '语文', '语文', 'CHINESE', '高一', null, null, '0', '0', null, null, null, '2014-10-03 00:00:00', null, '0', '2019-05-07 17:33:16', '2019-05-07 17:33:59', null, '0', '0','0', null, '0', '0', null, '10390000000002140201010000000000','1', null);
select id from courses where stu_id='${stuid}' and tea_id='${teaid}' order by id desc; |
第二个JDBC请求,是向lessons表中插入数据,需用到couid,引用时couid_0代表字段名称id ,couid_1代表该列第一个值,这里我们最新的课程Id 。
INSERT INTO lessons (les_type,les_subject,stu_id,cou_id,tea_id, room_id,sel_id,les_last_mins,les_tea_notify,les_stu_notify, les_start_time,les_end_time,les_match_time,random_code,select_knowledge, les_mark,created_at,updated_at,stu_sid,tea_sid, cost_points,sure_pay,before_cache_time,after_cache_time,student_token, teacher_token,deleted_at,completion_notified,les_uid,client_state, les_started_at,les_ended_at,les_slides_hash,is_virtual,is_activity, is_close,deduct_salary,msg_flag,source,test_need_pay, state,stu_mark,test_sure_pay,stu_grade ) VALUES ('test-lesson', '语文', '${stuid}', '${couid_1}', '${teaid}', '3224', '7323', '30', '0', '0', '2019-05-16 23:01:00', '2019-05-16 23:31:00', '2019-05-07 17:33:15', null, null, '', '2019-05-07 17:33:16', '2019-05-07 17:33:59', '', '', null, '1', '0', '0', null, null, null, '0', '53dUcZ1aYc8xdx4wjV9H0DaaTJ5cd150db', '0', null, null, null, null, '0', '0', null, '0', null, '0', '0', null, null, null); |
以造200测试数据为例,由于在CSV数据文件设置里设置了线程共享模式为所有线程,即取值不重复。这里我们可以设置任意合适的线程数与循环次数,即每个线程循环多次。这里我设置的是线程数2 循环次数100 ,生测试数据200条。
查看数据库lessons表中符合消息推送条件的数据200条,上课时间为2019-05-16 23:01:00
同理我们可以修改上课时间、下课时间和线程组设置,或者创建多个线程组 分别造1000 1500 2000 2500 3000数据,等到上课时间开始,查看数据库中t_message_log_bus_buffer表和t_msg_log表,统计如下 数据(以200测评课为例):
消息中心接收到的数据
select * from t_message_log_bus_buffer where event_no = 'KCTX02_WX' and create_time > '2019-05-16 22:00:00' and data like '%23:01%' order by create_time desc ; |
消息中心每个时刻接收数据的次数
select count(id),create_time from t_message_log_bus_buffer where event_no = 'KCTX02_WX' and create_time > '2019-05-16 22:00:00' and data like '%23:01%' group by create_time ; |
消息中心记录呼叫中心打电话的数据
select * from t_msg_log where code = 'KCTX02_WX' and create_time > '2019-05-16 22:00:00' and content like '%23:01%' ; |
消息中心记录呼叫中心打电话成功的数据
select * from t_msg_log where code = 'KCTX02_WX' and create_time > '2019-05-16 22:00:00' and content like '%23:01%' and state=1 ; |
消息中心记录呼叫中心打电话失败的数据
select * from t_msg_log where code = 'KCTX02_WX' and create_time > '2019-05-16 22:00:00' and content like '%23:01%' and state!=1; |
测试环境下 课程语言提醒限流正确,同一时间上课学生数为2000时,消息中心接收及打电话成功率均为100% ,无数据推送延迟情况,即不出现打电话在上课时间之后的情况 ,测试期间call_service服务器资源使用正常。
但当同一时间上课学生数为2500+时,消息中心接收到的数据量比推送的数据量少,并且数据推送有延迟情况 ,打电话成功率有所下降。
测评课数 |
上课时间 |
消息中心接收 |
打电话成功 |
打电话成功率 |
call服务 CPU使用率 |
call服务 Free内存 |
1000 |
2019-5-13 11:00 |
1000 |
1000 |
100% |
20% |
34% |
2000 |
2019-5-13 15:31 |
2000 |
2000 |
100% |
- |
- |
2500 |
2019-5-14 20:01 |
2399 |
2376 |
99.04% |
- |
- |
3000 |
2019-5-13 17:20 |
2860 |
2817 |
98.47% |
- |
- |
1、数据量2500+时,推送给消息中心的数据有延迟。
2、数据量2500+时,消息中心接收的数据量比推送的数据量少一些,有数据丢失现象。
3、多次测试2500+学生数时,测试结果不同,有时会延迟推送,有时没有,打电话成功率也略有差异,失败原因接口超时和网关超时。
4、数据量2500+时,消息中心重复调用call_service接口,已使用幂等编程,使同一个请求,发送一次和发送N次效果是一样的,解决了重复调用的问题 。
个人博客: http://weikeu.com