公司有一个微服务做认证管理,有一部分功能是负责做一些资源的限制,举个例子
有A、B、C个服务,A服务负责认证和资源的数量的管理,B、C服务负责实际资源的管理,
BC服务中的资源进行新增或删除都会先请求A服务进行申请资源,A服务对具体资源进行校验,逻辑比较简单,总大小 - 已使用的资源如果是正数则申请成功,将结果响应给请求的服务并将本次申请的大小和之前已使用的大小相加进行保存,如果申请不成功则直接返回结果给请求的服务, BC服务根据A服务返回的结果进行处理,如果正常则入库否则返回错误信息给客户端
问题的发现:
用户在使用过程中出现的问题,将BUG提交到对应平台
目前出现的问题:
BC服务实际存储值与A服务已使用的值对应不上,例如 A服务关于镜像限制项已使用的资源为90,但B服务上实际存储的镜像资源可能为80或者110,出现问题的原因是本身这个流程就是一个不可靠的,不可靠的原因可能有以下几点
1. B服务删除镜像没有请求A服务做处理
2. C或其他服务也可能调用该接口对镜像的限制项的数量做更改,在A服务的角度是感知不到是哪个服务做调用(前期接口没有考虑到,只对限制项做处理,并没有验证,也有可能不好处理因为服务与限制项是多对多的关系)
3. ...
问题出现后做了什么:
1. 问题分析
对问题进行分析,由于没有记录相关日志,只能暂时分析出上面列出的问题
2. 接口日志
将接口的日志单独做处理,将该接口的日志存放在一个.txt文件中,待服务运行一段时间数量再次对应不上后对应两边服务进行排查具体原因
3. 可靠的方式
尝试更换一种可靠的方式做这部分功能
接口日志
public static void logToPath(String o ){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
RandomAccessFile rw =null;
String path = System.getProperty("user.dir")+"/resource.txt";
System.out.println(path);
try {
rw = new RandomAccessFile(path, "rw");
rw.seek(rw.length());
rw.write((format.format(new Date()) + o + "\r\n" ).getBytes(CharsetUtil.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (rw != null) {
rw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
解决方案
1. 由于是已经上线的项目不能大改,所以只能在BC服务申请资源时额外查询A服务已使用和BC服务的实际已使用是否一致,如果不一致则进行同步,后面对比日志查看是否能找到原因,目前先这样进行解决