目录
问题说明:
场景说明:
每次上线失败原因分析:
第一次上线失败原因分析:
第二次上线失败原因分析:
第三次上线失败原因分析:
第四次上线失败原因分析:
问题经验总结:
握手机制简单来说就是接口调用过程,现就握手机制反复上线失败问题作出如下总结、分析。
握手机制接口调用涉及3个厂商,5个服务。调用过程如下图:
失败结果体现:MOP和XSB在pdf工单加载和保存操作速度慢,影响了工单业务办理。
处理方式:版本回退
分析代码逻辑: DMZ Map存储必要参数,形成XML格式请求报文到BHPS服务,BHPS提供一个接口供DMZ调用,接口包含调用能开接口和请求响应报文入库两个主要逻辑。xml格式请求报文传输方式以字节流传输。
分析结果:认为是调用能开接口响应较慢,影响了页面工单pdf加载和保存效率。
解决方法:为不影响业务办理主线程,在调用能开接口和日志入库过程中采用异步方式。
失败结果体现:虽然解决了pdf工单加载慢和保存操作速度慢问题,但经数据比对,发现在核对数据准确性,存在较大出入。
处理方式:版本回退
分析:在比对数据是,发现数据错乱,不准确,调用能开接口响应结果报错情况,并且又了解到新需求,必须保障数据准确性达到100%,于是推翻调用能开接口和日志入库采用异步方式。
分析结果:认为是调用能开接口响应较慢,影响了页面工单pdf加载和保存效率。
解决方法:能开接口优化,请求报文新增地市编码(home_city)和月份(month),以供CRM进行表分区,建索引
失败结果体现:根据第二次优化,重新上线,上线后pdf工单加载和保存操作速度慢,影响了工单业务办理
处理方式:版本回退
分析:上线过程中,在调用能开接口代码处加了调用时长日志输出,经调用时长日志输出,发现接口调用耗时在200毫秒内,正常范围。重新分析,是不是可能在请求报文和响应报文入库环节耗时过多?于是在在入库环节增加耗时日志,发现请求报文和响应报文入库耗时在4/5秒左右,定位到问题结果在于表结构创建的不合理
表结构如下:
--日志表结构
create table T_BH_DXMLDOCEMAILYYYYMM
(
case_no VARCHAR2(15),
xmldoc BLOB,
op_time VARCHAR2(20),
handrespondxml BLOB,
handxml BLOB,
source_type VARCHAR2(100)
)
不合理原因:1 表结构存在过多BLOB类型字段,在日志入库、更新操作时,效率低下,耗时较久。
2. 表结构 针对主键也没有创建索引,导致查询数据较慢
解决方法:重新设计表结构
-- Create table
create table T_BH_HANDLOG201810
(
case_no VARCHAR2(15),
city_code VARCHAR2(10),
source_type VARCHAR2(100),
print_id VARCHAR2(20),
status VARCHAR2(10),
describe VARCHAR2(1000),
create_time DATE,
update_time DATE,
load_interface_time INTEGER,
save_interface_time INTEGER,
load_resp_type VARCHAR2(10),
load_resp_desc VARCHAR2(1000),
save_resp_type VARCHAR2(10),
save_resp_desc VARCHAR2(1000),
comments VARCHAR2(1000),
month VARCHAR2(20)
)
失败体现:重新设计日志表结构和对表创建索引之后,日志入库有了明显提高,并且工单pdf加载和保存效率有明显提高,工单业务办理正常。但是经比对分析日志表数据发现,日志数据准确性存在较大出入、并且能开接口响应报文也存在很多失败情况。
处理方式:版本回退
分析:经过日志分析,发现DMZ向BHPS服务传递参数数据存在错乱,导致请求报文里一些参数不准确。
解决方法:由于DMZ向BHPS传递参数存在错乱,由于我们只传一个关键参数caseNo作为查询条件,其他参数到数据库中获取,BHPS封装请求报文,然后在调用能开接口和日志入库。
传递参数数据错乱原因:经过分析,是因为多线程问题导致。 模拟实际问题如下代码DEMO,每个子线程代表一个工单业务办理过程。项目采用的框架是structs1,而structs1创建的Action是单实例,一个Action实例处理所有请求。structs1存在线程安全问题。
package com.agile.tool.test;/**
* Created by gaoming on 2019/11/7.
*/
import java.util.HashMap;
import java.util.Map;
/**
* @version 1.0
* @auther gaoming
* @create 2019/11/7
* @Description TODO
*/
public class jdbcTest {
private static Map map = null;
public static void main(String[] args) {
Thread thread0 = new Thread(new Runnable() {
@Override
public void run() {
init("0");
}
});
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
init("1");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
init("2");
}
});
//模拟多个业务办理操作
thread0.start();
//模拟业务办理操作间隔时间
//try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}
thread1.start();
//模拟业务办理操作间隔时间
//try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}
thread2.start();
}
//模拟pdf工单初始化加载过程
public static void init(String i){
//赋值
map = new HashMap();
map.put("caseNo","aa"+i);
//模拟实际业务操作其他代码处理耗时
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//模拟调用握手接口,传递参数信息
System.out.println(map.toString());
}
}
运行demo预想结果:
{caseNo=aa0}
{caseNo=aa1}
{caseNo=aa2}
运行DEMO实际结果(而且存在多种可能性):
握手机制经过反复上线回退,上线失败5/6次,多次局方投诉,受到公司领导层关注,导致影响较大,特此记录,铭记教训!!!