线上问题排查-思路小分享

来源:互联网 发布:破解网络尖兵 编辑:程序博客网 时间:2024/04/28 22:39

1、抓包工具抓包,看看请求路径、参数已经响应数据信息,看数据是否有误或者缺失。

2、查看线上日志,尽量缩小范围定义问题。

3、定义好问题后,分析问题,数据流的思路分析问题-分析数据的来源。

 

 

if(AppUtils.isNotBlank(shopProd.getProdMallBeanRate())&&AppUtils.isNotBlank(shopProd.getMallBeanRate())&&shopProd.getProdMallBeanRate()>shopProd.getMallBeanRate() && extraMallBeanRate!=null && extraMallBeanRate>0){

注:红色部分是修复后才增加的非空判断,修复前没有做非空判断。

ShopProd shopProd = null;

shopProd = shopProdMap.get(basket.getShopProdId());//通过shopProdId获取map的value

 

Map<String, ShopProd> shopProdMap = buildShopProdInfo(pbaskets);

**
 * 组装Map<String,ShopProd>
 * @param baskets
 * @return
 */
private Map<String,ShopProd> buildShopProdInfo(List<ShopCartItem> baskets){
   if(AppUtils.isBlank(baskets)||(baskets.size())==0)
      return null;
   String[] shopProdId = new String[baskets.size()];
   for(int i=0;i<baskets.size();i++){ 
      shopProdId[i] = baskets.get(i).getShopProdId();
   }
   return shopProdService.queryShopProdByIdArray(shopProdId);
}

@Override
public Map<String, ShopProd> queryShopProdByIdArray(String[] shopProdIds) {
   List<ShopProd> shopProdList = shopProdDao.queryShopProdByIdArray(shopProdIds);
   Map<String, ShopProd> map = new HashMap<>();
   for(ShopProd shopProd : shopProdList){
      map.put(shopProd.getId(), shopProd);
   }
   return map;
}

 

@Override
public List<ShopProd> queryShopProdByIdArray(String[] shopProdIds) {
   if(AppUtils.isBlank(shopProdIds)){
      return null;
   }
   StringBuffer querySql = new StringBuffer("SELECT lp.mall_bean_rate as prodMallBeanRate,sp.id,sp.shop_id as shopId,sp.prod_id as prodId,sp.status,");
   querySql.append("sp.update_time as udpateTime,sp.mall_bean_rate as mallBeanRate,sp.rebate_rate as rebateRate,sp.dist_commis_rate as distCommisRate,");
   querySql.append("sp.user_mall_bean_rate as userMallBeanRate,sp.user_rebate_rate as userRebateRate,sp.user_dist_commis_rate as userDistCommisRate,");
   querySql.append("sp.extra_mall_bean_rate as extraMallBeanRate FROM ls_shop_prod sp LEFT JOIN ls_prod lp ON sp.prod_id=lp.prod_id WHERE id IN (");
   List<Object> paramList = new ArrayList<Object>();
   for(int i=0;i<shopProdIds.length;i++){
      if(i==0){
         paramList.add(shopProdIds[0]);
         querySql.append("?");
      }else{
         paramList.add(shopProdIds[i]);
         querySql.append(",?");
      }
   }
   querySql.append(")");
   return query(querySql.toString(), ShopProd.class, paramList.toArray());
}

 

sql 复制到数据库中直接查询,把对应的参数传入,看看返回的数据。

SELECT lp.mall_bean_rate as prodMallBeanRate,sp.id,sp.shop_id as shopId,sp.prod_id as prodId,sp.status,

sp.update_time as udpateTime,sp.mall_bean_rate as mallBeanRate,sp.rebate_rate as rebateRate,sp.dist_commis_rate as distCommisRate,

sp.user_mall_bean_rate as userMallBeanRate,sp.user_rebate_rate as userRebateRate,sp.user_dist_commis_rate as userDistCommisRate,

sp.extra_mall_bean_rate as extraMallBeanRate FROM ls_shop_prod sp LEFT JOIN ls_prod lp ON sp.prod_id=lp.prod_id WHERE id IN ('26ad2320-19b5-4901-a734-3a715bee81e3')

 

开发中,排查线上问题查看linux日志,常用linux指令。

awk  cat  cksum  df  du  echo  find  free  grep  ls  more  ps  sed  sz  tail  top  view

linux ---tail命令

linuxtail命令---用于查看文件内容

最基本的是catmoreless

1. 如果你只想看文件的前5行,可以使用head命令,如:

head -5 /etc/passwd

2. 如果你想查看文件的后10行,可以使用tail命令,如:

tail -10 /etc/passwd tail -n 10 /etc/passwd

tail -f /var/log/message

参数-f使tail不停地去读最新的内容,这样有实时监视的效果 用Ctrlc来终止!

3. 查看文件中间一段,你可以使用sed命令,如:

ed -n '5,10p' /etc/passwd

这样你就可以只查看文件的第5行到第10行。

tail语法格式:

tail [ -f ] [ -c Number | -n Number | -m Number | -b Number | -k Number ] [ File ]

或者

tail [ -r ] [ -n Number ] [ File ]

使用说明:

tail 命令从指定点开始将 File参数指定的文件写到标准输出。如果没有指定文件,则会使用标准输入。Number变量指定将多少单元写入标准输出。Number变量的值可以是正的或负的整数。如果值的前面有+(加号),从文件开头指定的单元数开始将文件写到标准输出。如果值的前面有-(减号),则从文件末尾指定的单元数开始将文件写到标准输出。如果值前面没有+(加号)或-(减号),那么从文件末尾指定的单元号开始读取文件。

主要参数:

-b Number Number变量表示的512字节块位置开始读取指定文件。

-c Number Number变量表示的字节位置开始读取指定文件。

-f 如果输入文件是常规文件或如果 File参数指定FIFO(先进先出),那么tail命令不会在复制了输入文件的最后的指定单元后终止,而是继续从输入文件读取和复制额外的单元(当这些单元可用时)。如果没有指定File参数,并且标准输入是管道,则会忽略-f标志。tail -f命令可用于监视另一个进程正在写入的文件的增长。

-k Number Number变量表示的1KB块位置开始读取指定文件。

-m Number Number变量表示的多字节字符位置开始读取指定文件。使用该标志提供在单字节和双字节字符代码集环境中的一致结果。

-n Number 从首行或末行位置来读取指定文件,位置由 Number变量的符号(+-或无)表示,并通过行号Number进行位移。

-r 从文件末尾以逆序方式显示输出。-r标志的缺省值是以逆序方式显示整个文件。

如果文件大于 20,480 字节,那么-r标志只显示最后的20,480字节。-r标志只有  -n标志一起时才有效。否则,就会将其忽略。

 

ll  |grep ‘2017-11-20’ 表示列出所有包含 2017-11-20的文件( ll |grep‘模糊查询的关键字符’)

显示行号,定位大致问题所在行

cat -n catalina.out.2017-11-20-13:59:01.log |grep 'Nike耐克 男鞋2017新款HYPERDUNK'模糊查询

 

备注:客服反馈截图:

 

 

而我自己在13:00到14:00期间,在私教小店购买相同商品,重现问题。

故排查时间选择在catalina.out.2017-11-20-13:59:01.log 这个文件中。

定位问题日志打印在14985行附近。查看日志。

查看所对应的行的日志

 view  catalina.out.2017-11-20-13:59:01.log

:14985 (跳转到所需要查看的行数)

备注:

1) 注意,输入行数时,不能用小键盘。

2) 需要跳转到行数时直接用冒号+行数.例如(:14958)

3) 需要跳转到内容时,用冒号+斜杠(/)+搜索的内容.例如 :/Nike耐克 男鞋2017新款HYPERDUNK

查看完日志后,强制退出且不保存命令

:q!

:数字  定位到行数

:/ 搜索关键字

n 跳转到下一个关键字

PageUp/PageDown 上下翻页


原创粉丝点击