一解决方法:
问题的主要原因出在:跨程序集反射。
即我们需反射的A.dll的程序集引用B.dll程序集,而在反射工具项目中却不存在对B.dll程序集的引用。因此我们只需在反射工具项目中添加对B.dll的引用即可,或者将B.dll拷贝到反射工具的执行目录下。
二解决方法:
删除项目中的bin文件夹,
在项目属性中,修改目平台,从Any CPU改为x86,
再重新生成就可以了,具体是什么原因还不清楚
最后还要注意 AutoMapper 的版本;版本不同,语法会报错
将多个数据的请求放入一个对象或者数组中,后续方法无法访问的问题
1.既然是多个请求,尽量将每个请求的数据分开处理,这样处理性能更优
2.如果数据的渲染较为类似,可以把渲染方法提出来,处理数据后可以调用同一个方法进行渲染
一解决方法:
问题的主要原因出在:跨程序集反射。
即我们需反射的A.dll的程序集引用B.dll程序集,而在反射工具项目中却不存在对B.dll程序集的引用。因此我们只需在反射工具项目中添加对B.dll的引用即可,或者将B.dll拷贝到反射工具的执行目录下。
二解决方法:
删除项目中的bin文件夹,
在项目属性中,修改目平台,从Any CPU改为x86,
再重新生成就可以了,具体是什么原因还不清楚
最后还要注意 AutoMapper 的版本;版本不同,语法会报错
转载于:https://www.cnblogs.com/zishen/p/4976439.html
3个请求同时进来以至于同一个文件夹被意外创建了2此,这个应该如何避免呀
解决方法:
队列。锁。
不同请求之间没有同一个上下文,无法锁约束
可以使用对象锁
注册个singleton服务,或者用个static object
注册个单例服务,里面用锁或者信号量或者原子
多进程的就分布式锁
IHttpContextAccessor是在从Http请求发起的Scope,需要注入HttpContext时使用的
直接在FileService里加一个static object(),创建文件夹前lock然后检查文件夹是否存在
目录
生产中,我们经常会把接口api 提供给第三方的使用者,但是 如果当调用者出现故障疯狂的调用我们的接口,或者 同一个请求发了多次,第一种 情况 会造成 服务器大量的链接被占用,造成服务挂掉,正常的服务无法提供给其他人, 第二种情况会造成 业务上很大的困扰,比如 减库存或者转账多加多减得情况,
解决调用频率太高的问题
我使用的是 redis 作为解决调用频率的问题
首先 我们将 需要 进行 访问频率的url列出来,给他们限制住 访问的间隔时间,然后在 拦截器中 使用redis 去判断每一次进来的请求 是否 符合 间隔时间 的要求,
Integer milliSecond = Integer.parseInt(repeatMap.get(currUrl));
logger.info("当前url={}进行防重校验,{}毫秒禁止重复请求!", currUrl, milliSecond);
//用户ID
String tUserId = userInfo.getUserId();
Map<String, String> currThreadMap = new HashMap<String, String>();
// 系统当前毫秒数
Long currTime = System.currentTimeMillis();
Long expireTime = currTime + new Long(milliSecond);
Long count = jedisTemplate.STRINGS.setnx(Constants.INSTALLMENT_KEY + Constants.REPEAT_KEY + tUserId, expireTime.toString());
if (count == 1L) {
logger.info("防重校验通过,不是重复提交!");
currThreadMap.put(LOCK, tUserId);
} else {
logger.info("防重校验失败,是重复提交,需校验超时时间!");
String cacheExpTime = jedisTemplate.STRINGS.get(Constants.INSTALLMENT_KEY + Constants.REPEAT_KEY + tUserId);
if (StringUtils.isNotEmpty(cacheExpTime)) {
if (currTime > Long.valueOf(cacheExpTime)) {
logger.info("redis锁已超时,当前请求可以重新获取锁,currTime={}, cacheExpTime={}", currTime, cacheExpTime);
Long newExpTime = System.currentTimeMillis() + new Long(milliSecond);
String oldExpTime = jedisTemplate.STRINGS.getSet(Constants.INSTALLMENT_KEY + Constants.REPEAT_KEY + tUserId,
newExpTime.toString());
if (!cacheExpTime.equals(oldExpTime)) {
logger.info("锁已经被其他线程获取,当前线程拒绝执行请求");
setResponse(response, ResCode.REQUEST_PROCESS);
return false;
}
logger.info("当前线程已经获得锁,可以执行请求");
currThreadMap.put(LOCK, tUserId);
} else {
logger.info("redis锁未超时,当前请求拒绝执行,currTime={}, cacheExpTime={}", currTime, cacheExpTime);
setResponse(response, ResCode.REQUEST_PROCESS);
return false;
}
} else {
logger.info("redis缓存时间为空,锁已解除,重新获取锁");
expireTime = currTime + new Long(milliSecond);
count = jedisTemplate.STRINGS.setnx(Constants.INSTALLMENT_KEY + Constants.REPEAT_KEY + tUserId, expireTime.toString());
if (count == 0L) {
logger.info("锁已经被其他线程获取,当前线程拒绝执行请求");
setResponse(response, ResCode.REQUEST_PROCESS);
return false;
}
logger.info("当前线程已经获得锁,可以执行请求");
currThreadMap.put(LOCK, tUserId);
}
}
threadMap.set(currThreadMap);
threadMap 是 一个 ThreadLocal,用于最后将 失效的 redis key清除
解决同一个请求的问题
我们使用是 zookpeer 的临时节点
String path = publicKey[1] + "_" + params.get("platform") + "_" + params.get("outUserId");
boolean lock = zkClient.getEphemeralLock(path);
if (!lock) {
logger.info("当前存在并发问题,获取锁失败,请求打回,path={}", publicKey[1]);
throw new RequestException(OutApiResCode.REQUEST_CONCURRENT_WAINING.getCode(), "请求提交频率过高!");
}
这一步可以在 验证参数的时候 使用,如果是 同一个 outUserId 那么就会有拦截的功能