2022年8月🤾

BUG

1、mybatis 相关

Subquery returns more than 1 row;

错误的意思是指子查询结果多于一行。


SELECT id FROM VEHICLE_DEVICE_INSTALLATION  WHERE sim_id =
 (SELECT id FROM  VEHICLE_SIM WHERE iccid = #{iccid})

这里的 = 修改为 IN

返回list,size =1,但是 对象 allelements is null

错误是 sql 查询的部分字段,但是这些字段刚好都是空值,但是实际是查出了这条数据,查询结果带上id 即可

SELECT vehicleId,status FROM VEHICLE_DEVICE_INSTALLATION  where xx

ProxyTransactionManagementConfiguration is not eligible for getting processed

代码中增加mybatis 查询,启动出现这个错,swagger访问404
尝试很多方式未解决,最后删除 swagger 配置类解决

2、Calendar的月

设置8实际结果表示9月,从0开始

3、redis

redis哨兵模式执行select 0命令报错: (error) ERR unknown command select, with args beginning with: 0
执行get 也不行,原因是哨兵模式,执行 info,找到主节点信息,然后连接主节点再进行操作即可
master0:name=mymaster,status=ok,address=xxx

cd /usr/local/bin
redis-cli -h 10.12.168.71 -p 6395 -a 1234

4、mysql导出csv 精度丢失 以及 字段在一行 乱码

精度问题 https://blog.csdn.net/weixin_42425365/article/details/111059168
https://wenku.baidu.com/view/da96b5030422192e453610661ed9ad51f01d54f4.html

乱码设置字符集gb2312

5、ping 网络

ping 的时候不要带上https:// 这样会出现unknown host 直接ping www.baidu.com

6、iccid数据比对

我在修复iccid数据比对时有一个问题,绑定时没有设置 status =VALID,
自己没有看清修复iccid数据的逻辑,只是简单的修改,而实际上是 解绑在绑定,那么这两个操作对应的业务逻辑是什么
sql 应该怎么写,自己忽略了

7、调用第三方接口问题

适用hutool工具调用第三方接口,测试环境正常,上生产出现报错
出现SocketExcetion错误,百度搜索了一下,没有搜到同样情况
接着又出现unknownException、有时候提示网络异常
分析:
1、排查记录调用的接口地址是否正确
2、检查秘钥syscode是否正确,用同样的参数在本地执行生成的结果是一样的
3、ping 网络是否通畅、curl 接口请求看如何
4、在接口接收方查看有没有收到请求
5、手动调用第三方接口 查看第三方接口是否通畅

经过以上步骤发现服务器与第三方接口是通畅的,接口地址正确,第三方未收到请求,也就是是内部问题
工具类有问题?生产环境的hutool版本和本地一样,jar冲突?但是又没有相关报错
反馈给领导,分析是jdk问题,服务器上用的是openJdk ,换成oracle的
第三方接口是https openJdk存在https支持问题

RestTemplate 调用第三方接口

RestTemplate 可以调用微服务接口,也可以调用第三方,但是使用方式不同

@Autowired
private RestTemplate restTemplate;
注入的是调用微服务的,调用第三方需要 RestTemplate restTemplate = new RestTemplate ();
restTemplate .xxx
不能直接 new RestTemplate ()。xxx 会出现报错

异步线程中没有try catch问题

在异步线程中执行批量插入,开始和结束都记录了日志,但是发现只有开始的日志,结束的没有,也没有异常日常
本地测试出现了异常
SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
.数据库的字段和输入的数据库的数据类型不匹配
在插入时添加try catch 最终显示了具体的异常,是因为字段太长
如果没有捕获日志,根本不知道是什么问题 ,加日志非常关键

  • 数据库字段创建时 可以适当放大点,这次手机号设置是20,结果导入时 有用户有2个手机号
  • 记录执行日志以及报错日志

8、功能超时

功能流程是A调用B服务 B服务中业务处理后 调用第三方接口
经过排查第三方有时候会响应超时,A调用B服务超时时间为5S
更多时候A调用时,到调用第三方接口中间耗时超过10秒,由于B接口中日志偏少,以为是restTemple调用有网络延迟,后来添加日志分析
发现是B接口中有一个业务操作是全表查询,且接口有2个分支,第二个分支是从联通逻辑,在2分支中又操作了一个全表查询
所以调用联通出问题概率更高

List<String> list = querySimList();
            if (!list.containsAll(msisdnList)) {
                throw new NEException("卡号不存在");
            }
			
ELECT number FROM `VEHICLE_SIM` WHERE id IN( SELECT sim_id FROM `VEHICLE_DEVICE_INSTALLATION` WHERE status ='VALID')

优化方案, 原先是查询出所有数据然后看数据是否在其中,效率低
直接根据参数进行查库,去掉联通分支中重复的校验逻辑

String number = iSimDao.countValidSim(phone);
        if (StringUtils.isBlank(number)){
            throw new NEException("卡号不存在");
        }
SELECT a.number FROM VEHICLE_SIM a inner join VEHICLE_DEVICE_INSTALLATION b on  a.id=b.sim_id  WHERE b.status ='VALID' and a.number=#{phone}

9、新增服务网点报错

运营人员新增服务网点报错,找到接口 定位到错误行,是因为用户对应oid 下有经销商了,不允许再次创建
运营说一直都是用运营账号创建的,我不理解。因为觉得当前账号有关联的经销商了,为什么还能创建呢
-----僵持不下,后台代码看着没问题,我觉得一定是有什么设置
自己在页面上看了下,发现页面上有个菜单栏是选择经销商账号,所以实际获取的是这个字段。
遇到问题细心点,从多个层面验证是最好的,后端代码没问题,看看页面,不要着急下结论,多了解



方案

1、同步数据问题

现在数据同步需要从a b c d几张表中获取数据,现在拿到一批数据也需要同步给x平台。
拿到的字段很多很乱,如果将这些数据也插入a bcd等表中涉及表多,字段多。而时间紧急
想到一个方案,将同步给X平台所需要的字段放在一个表里,让另一方按照所需字段直接导出

2、导入excel 50w数据效率问题

  • 数据导入提示Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
    hutool.core.text.csv.CsvBaseReader.read(CsvBaseReader.java:186)
    本地测试正常,发布到测试环境出现问题。测试环境内存不够,在导入时CPU暴增
    应对方式,限制导入文件大小为 20M 时正常

导入50w数据,数据根据vin作为唯一索引,
方案A 将导入的数据做成List 查询数据库,得到结果后去除已存在的 ,然后进行插入,发现性能一般

方案B 直接批量插入,使用 ignore ,速度很快,如果存在会忽略
数据入库采用异步

insert ignore into REALNAME_SUPPLEMENT_VEHICLE(vin)
        values
        <foreach collection="list" close="" index="index" item="item" open="" separator=",">
           (#{item.vin})
        </foreach>

insert ignore 不能更新,如果需要更新则不合适
利用唯一索引的特性,如果存在则更新,不存在就插入
ON DUPLICATE KEY UPDATE


 <insert id="insertBatch">
        insert into REALNAME_EV_VEHICLE(vin, msisdn, iccid,create_date)
        values
        <foreach collection="list" close="" index="index" item="item" open="" separator=",">
            (#{item.vin},#{item.msisdn},#{item.iccid},#{item.createDate})
        </foreach>
        ON DUPLICATE KEY UPDATE
        msisdn = values(msisdn),iccid = values(iccid),  create_date = now()
    </insert>

3、eureka注册不上,不显示连接日志

eureka:
client:
registerWithEureka: false
fetchRegistry: false

4、异步线程处理

不带线程池,异步没有返回值
出现问题:

  • 本地测试异步线程正常执行,但是部署测试异步线程没有执行,查询原因是
    异步线程为守护线程,在主线程执行完后,后续不执行了
    执行时间 > 主线程,是守护线程,会被杀死,不会打印

解决办法,配置线程池,线程池不能每次使用到 new,会消耗很多资源

private int threadSize = 2;
    @PostConstruct
    public void init() {
        executorService = new ThreadPoolExecutor(threadSize, threadSize, 60L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(threadSize * 1000), new ThreadPoolExecutor.CallerRunsPolicy());
    }


CompletableFuture.runAsync(()->{
                log.info("-begin-从CSV导入-vehicleListsize:{}",vehicleList.size());
                
                log.info("-end");
            },executorService);

5、查看日志时提示匹配到二进制文件 (标准输入)

解决办法:加上参数 -a
cat /opt/evlogs/vehicle.log | grep -a 'NullPointerException' -C 2;

6、接口日志

接口有入参记录以及返回的日志记录,内容中要包含 唯一id是非常好的

 logId.set(System.nanoTime());
        LogUtil.log(logId.get(), LogUtil.LogType.REQUEST,requestDto);
LogUtil.log(logId.get(), LogUtil.LogType.RESPONSE,response);

调用第三方时,记录请求和返回日志,记录返回日志时,可以带上入参的主键,比如这里的phone
不然有时候不好确定这个返回是哪个请求返回的
在日志中通过线程名 也能辅助确认

logger.info("[queryAuthRealInfo]-phone:{},OwnerVins:{}",requestBody.getPhone(),JsonUtil.writeValueAsString(vins));
        AuthRealResponseBody responseBody = new AuthRealResponseBody();
        String result = reqRealNamePlatform(requestBody.getPhone());
        logger.info("[reqRealNamePlatform]-result:{}",result);

posted @ 2022-08-03 14:18  爱生活(^_-)  阅读(222)  评论(0)    收藏  举报