当前位置: 首页 > news >正文

河北沧州做网站的电话asp技术网站开发案例

河北沧州做网站的电话,asp技术网站开发案例,体育用品网站模板,休闲度假村网站建设方案前端每隔15秒就发起一次请求#xff0c;将播放记录写入数据库。 但问题是#xff0c;提交播放记录的业务太复杂了#xff0c;其中涉及到大量的数据库操作#xff1a; 如何进行优化 单机并发能力 变同步为异步 合并写请求 提高单机并发#xff1a;优化SQL#xff0c;尽…前端每隔15秒就发起一次请求将播放记录写入数据库。 但问题是提交播放记录的业务太复杂了其中涉及到大量的数据库操作 如何进行优化 单机并发能力 变同步为异步 合并写请求 提高单机并发优化SQL尽量走索引避免双重for循环添加缓存 提高单机并发能力 变同步为异步 合并写请求 合并写请求方案其实是参考高并发读的优化思路当读数据库并发较高时我们可以把数据缓存到Redis这样就无需访问数据库大大减少数据库压力减少响应时间。 既然读数据可以建立缓存那么写数据可以不可以也缓存到Redis呢 答案是肯定的合并写请求就是指当写数据库并发较高时不再直接写到数据库。而是先将数据缓存到Redis然后定期将缓存中的数据批量写入数据库。 提交学习记录业务优化 记录是否已经存在放入缓存中因为每次提交都会去数据库查询更新学习记录时间放入缓存中 对提交学习记录进行改造每隔15秒进行一次提交对数据库压力太大考虑到只有最后一次提交才有效所以我们对存在数据库操作的地方进行优化 而播放进度信息不管更新多少次下一次续播肯定是从最后的一次播放进度开始续播。也就是说我们只需要记住最后一次即可。因此可以采用合并写方案来降低数据库写的次数和频率而异步写做不到。 如何设计缓存字段 用户学习视频的过程中可能会在多个视频之间来回跳转这就会导致频繁的创建缓存、缓存过期影响到最终的业务性能。该如何解决呢 使用hash key解决 实际操作中可以直接把实体类转化为JSON 当做value存入 但是存在一定问题 但问题来了我们怎么知道哪一次提交是最后一次提交呢 只要用户一直在提交记录Redis中的播放进度就会一直变化。如果Redis中的播放进度不变肯定是停止了播放是最后一次提交。 因此我们只要能判断Redis中的播放进度是否变化即可。怎么判断呢 核心思想 每当前端提交播放记录时我们可以设置一个延迟任务并保存这次提交的进度。等待20秒后因为前端每15秒提交一次20秒就是等待下一次提交检查Redis中的缓存的进度与任务中的进度是否一致。把数据缓存到redis中同时设置一个20秒的延迟任务20秒后执行这个任务执行这个任务的时候再一次跟redis中的时间比对如果一样则更新数据库否则跳过 不一致说明持续在提交无需处理 一致说明是最后一次提交暂停了或者离开播放了提交延迟任务更新学习记录、更新课表最近学习小节和时间到数据库中 延迟任务方案 DelayQueue的用法  package com.tianji.learning.utils;import lombok.Data;import java.time.Duration; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit;Data public class DelayTaskD implements Delayed {private D data;private long deadlineNanos;public DelayTask(D data, Duration delayTime) {this.data data;this.deadlineNanos System.nanoTime() delayTime.toNanos();}Overridepublic long getDelay(TimeUnit unit) {return unit.convert(Math.max(0, deadlineNanos - System.nanoTime()), TimeUnit.NANOSECONDS);}Overridepublic int compareTo(Delayed o) {long l getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);if(l 0){return 1;}else if(l 0){return -1;}else {return 0;}} } 接下来就可以创建延迟任务交给延迟队列保存 package com.tianji.learning.utils;import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test;import java.time.Duration; import java.util.concurrent.DelayQueue;Slf4j class DelayTaskTest {Testvoid testDelayQueue() throws InterruptedException {// 1.初始化延迟队列DelayQueueDelayTaskString queue new DelayQueue();// 2.向队列中添加延迟执行的任务log.info(开始初始化延迟任务。。。。);queue.add(new DelayTask(延迟任务3, Duration.ofSeconds(3)));queue.add(new DelayTask(延迟任务1, Duration.ofSeconds(1)));queue.add(new DelayTask(延迟任务2, Duration.ofSeconds(2)));// TODO 3.尝试执行任务} } 执行任务 package com.tianji.learning.utils;import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test;import java.time.Duration; import java.util.concurrent.DelayQueue;Slf4j class DelayTaskTest {Testvoid testDelayQueue() throws InterruptedException {// 1.初始化延迟队列DelayQueueDelayTaskString queue new DelayQueue();// 2.向队列中添加延迟执行的任务log.info(开始初始化延迟任务。。。。);queue.add(new DelayTask(延迟任务3, Duration.ofSeconds(3)));queue.add(new DelayTask(延迟任务1, Duration.ofSeconds(1)));queue.add(new DelayTask(延迟任务2, Duration.ofSeconds(2)));// 3.尝试执行任务while (true) {DelayTaskString task queue.take();log.info(开始执行延迟任务{}, task.getData());}} } 开始改造 封装的工具类 延迟队列里面放的就是这一个个DelayTaskT Data public class DelayTaskD implements Delayed {private D data;private long deadlineNanos;public DelayTask(D data, Duration delayTime) {this.data data;this.deadlineNanos System.nanoTime() delayTime.toNanos();}Overridepublic long getDelay(TimeUnit unit) {return unit.convert(Math.max(0, deadlineNanos - System.nanoTime()), TimeUnit.NANOSECONDS);}Overridepublic int compareTo(Delayed o) {long l getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);if(l 0){return 1;}else if(l 0){return -1;}else {return 0;}} } 需要开启另一个线程来执行任务 Slf4j RequiredArgsConstructor Component public class LearningRecordDelayTaskHandler {private final StringRedisTemplate redisTemplate;private final DelayQueueDelayTaskRecordTaskData queue new DelayQueue();private final static String RECORD_KEY_TEMPLATE learning:record:{};private final LearningRecordMapper recordMapper;private final ILearningLessonService lessonService;private static volatile boolean begin true;// 项目启动后 当前类实例化 属性输入之后 方法就会运行 一般用来做初始化工作PostConstructpublic void init(){CompletableFuture.runAsync(this::handleDelayTask);log.debug(开启 新线程执行handleDelayTask方法);// 开启 新线程执行handleDelayTask方法}PreDestroy // 当前类是实例 销毁之前该方法执行public void destroy(){log.debug(关闭学习记录处理的延迟任务);begin false;}private void handleDelayTask(){while (begin){try {// 1.尝试获取任务 take是阻塞方法DelayTaskRecordTaskData task queue.take();log.debug(获取到要处理的播放记录任务);RecordTaskData data task.getData();// 2.读取Redis缓存LearningRecord record readRecordCache(data.getLessonId(), data.getSectionId());log.debug(获取到要处理的播放记录任务任务数据{} 缓存中的数据{},data,record);if (record null) {continue;}// 3.比较数据if(!Objects.equals(data.getMoment(), record.getMoment())){// 4.如果不一致播放进度在变化无需持久化continue;}// 5.如果一致证明用户离开了视频需要持久化// 5.1.更新学习记录record.setFinished(null);recordMapper.updateById(record);// 5.2.更新课表LearningLesson lesson new LearningLesson();lesson.setId(data.getLessonId());lesson.setLatestSectionId(data.getSectionId());lesson.setLatestLearnTime(LocalDateTime.now());lessonService.updateById(lesson);log.debug(准备持久化学习记录信息);} catch (Exception e) {log.error(处理播放记录任务发生异常, e);}}}public void addLearningRecordTask(LearningRecord record){// 1.添加数据到Redis缓存writeRecordCache(record);// 2.提交延迟任务到延迟队列 DelayQueuequeue.add(new DelayTask(new RecordTaskData(record), Duration.ofSeconds(20)));}public void writeRecordCache(LearningRecord record) {log.debug(更新学习记录的缓存数据);try {// 1.数据转换String json JsonUtils.toJsonStr(new RecordCacheData(record));// 2.写入RedisString key StringUtils.format(RECORD_KEY_TEMPLATE, record.getLessonId());redisTemplate.opsForHash().put(key, record.getSectionId().toString(), json);// 3.添加缓存过期时间redisTemplate.expire(key, Duration.ofMinutes(1));} catch (Exception e) {log.error(更新学习记录缓存异常, e);}}public LearningRecord readRecordCache(Long lessonId, Long sectionId){try {// 1.读取Redis数据String key StringUtils.format(RECORD_KEY_TEMPLATE, lessonId);Object cacheData redisTemplate.opsForHash().get(key, sectionId.toString());if (cacheData null) {return null;}// 2.数据检查和转换return JsonUtils.toBean(cacheData.toString(), LearningRecord.class);} catch (Exception e) {log.error(缓存读取异常, e);return null;}}public void cleanRecordCache(Long lessonId, Long sectionId){// 删除数据String key StringUtils.format(RECORD_KEY_TEMPLATE, lessonId);redisTemplate.opsForHash().delete(key, sectionId.toString());}// 缓存实体类DataNoArgsConstructorprivate static class RecordCacheData{private Long id;private Integer moment;private Boolean finished;public RecordCacheData(LearningRecord record) {this.id record.getId();this.moment record.getMoment();this.finished record.getFinished();}}// 任务实体类DataNoArgsConstructorprivate static class RecordTaskData{private Long lessonId;private Long sectionId;private Integer moment;public RecordTaskData(LearningRecord record) {this.lessonId record.getLessonId();this.sectionId record.getSectionId();this.moment record.getMoment();}} }使用线程池来处理任务 目前我们的延迟任务执行还是单线程模式大家将其改造为线程池模式 拉取方法 还是使用哪个开辟的线程去拉取但是拉取完之后的执行让线程池里面的来执行 面试题
文章转载自:
http://www.morning.mfrb.cn.gov.cn.mfrb.cn
http://www.morning.jgttx.cn.gov.cn.jgttx.cn
http://www.morning.txrq.cn.gov.cn.txrq.cn
http://www.morning.hclplus.com.gov.cn.hclplus.com
http://www.morning.bhdtx.cn.gov.cn.bhdtx.cn
http://www.morning.cwqpl.cn.gov.cn.cwqpl.cn
http://www.morning.spqtq.cn.gov.cn.spqtq.cn
http://www.morning.xbmwm.cn.gov.cn.xbmwm.cn
http://www.morning.kdrly.cn.gov.cn.kdrly.cn
http://www.morning.rnnts.cn.gov.cn.rnnts.cn
http://www.morning.htqrh.cn.gov.cn.htqrh.cn
http://www.morning.bsxws.cn.gov.cn.bsxws.cn
http://www.morning.fqmcc.cn.gov.cn.fqmcc.cn
http://www.morning.yqrgq.cn.gov.cn.yqrgq.cn
http://www.morning.rnfn.cn.gov.cn.rnfn.cn
http://www.morning.pxspq.cn.gov.cn.pxspq.cn
http://www.morning.ykwgl.cn.gov.cn.ykwgl.cn
http://www.morning.qtqjx.cn.gov.cn.qtqjx.cn
http://www.morning.yxzfl.cn.gov.cn.yxzfl.cn
http://www.morning.tldfp.cn.gov.cn.tldfp.cn
http://www.morning.smspc.cn.gov.cn.smspc.cn
http://www.morning.znnsk.cn.gov.cn.znnsk.cn
http://www.morning.kyhnl.cn.gov.cn.kyhnl.cn
http://www.morning.wfmqc.cn.gov.cn.wfmqc.cn
http://www.morning.rqkck.cn.gov.cn.rqkck.cn
http://www.morning.nbnpb.cn.gov.cn.nbnpb.cn
http://www.morning.nwrzf.cn.gov.cn.nwrzf.cn
http://www.morning.qmbpy.cn.gov.cn.qmbpy.cn
http://www.morning.ghssm.cn.gov.cn.ghssm.cn
http://www.morning.bkslb.cn.gov.cn.bkslb.cn
http://www.morning.fpczq.cn.gov.cn.fpczq.cn
http://www.morning.daidudu.com.gov.cn.daidudu.com
http://www.morning.nynpf.cn.gov.cn.nynpf.cn
http://www.morning.rkmsm.cn.gov.cn.rkmsm.cn
http://www.morning.dmcxh.cn.gov.cn.dmcxh.cn
http://www.morning.qqklk.cn.gov.cn.qqklk.cn
http://www.morning.cpmwg.cn.gov.cn.cpmwg.cn
http://www.morning.tnnfy.cn.gov.cn.tnnfy.cn
http://www.morning.bbgn.cn.gov.cn.bbgn.cn
http://www.morning.lnbyk.cn.gov.cn.lnbyk.cn
http://www.morning.zxqqx.cn.gov.cn.zxqqx.cn
http://www.morning.wsgyq.cn.gov.cn.wsgyq.cn
http://www.morning.rsnd.cn.gov.cn.rsnd.cn
http://www.morning.nkiqixr.cn.gov.cn.nkiqixr.cn
http://www.morning.bctr.cn.gov.cn.bctr.cn
http://www.morning.ggnkt.cn.gov.cn.ggnkt.cn
http://www.morning.ndynz.cn.gov.cn.ndynz.cn
http://www.morning.frfpx.cn.gov.cn.frfpx.cn
http://www.morning.xptkl.cn.gov.cn.xptkl.cn
http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn
http://www.morning.yjmlg.cn.gov.cn.yjmlg.cn
http://www.morning.rqjl.cn.gov.cn.rqjl.cn
http://www.morning.wpcfh.cn.gov.cn.wpcfh.cn
http://www.morning.jnoegg.com.gov.cn.jnoegg.com
http://www.morning.rrgm.cn.gov.cn.rrgm.cn
http://www.morning.sqfnx.cn.gov.cn.sqfnx.cn
http://www.morning.txysr.cn.gov.cn.txysr.cn
http://www.morning.hnkkm.cn.gov.cn.hnkkm.cn
http://www.morning.pszw.cn.gov.cn.pszw.cn
http://www.morning.pbsfq.cn.gov.cn.pbsfq.cn
http://www.morning.zxgzp.cn.gov.cn.zxgzp.cn
http://www.morning.mkfr.cn.gov.cn.mkfr.cn
http://www.morning.kgjyy.cn.gov.cn.kgjyy.cn
http://www.morning.dnconr.cn.gov.cn.dnconr.cn
http://www.morning.jkpnm.cn.gov.cn.jkpnm.cn
http://www.morning.txlnd.cn.gov.cn.txlnd.cn
http://www.morning.yxkyl.cn.gov.cn.yxkyl.cn
http://www.morning.tbqdm.cn.gov.cn.tbqdm.cn
http://www.morning.wqrk.cn.gov.cn.wqrk.cn
http://www.morning.yymlk.cn.gov.cn.yymlk.cn
http://www.morning.nfccq.cn.gov.cn.nfccq.cn
http://www.morning.rtbx.cn.gov.cn.rtbx.cn
http://www.morning.trtdg.cn.gov.cn.trtdg.cn
http://www.morning.mtktn.cn.gov.cn.mtktn.cn
http://www.morning.fwjfh.cn.gov.cn.fwjfh.cn
http://www.morning.jjrsk.cn.gov.cn.jjrsk.cn
http://www.morning.grnhb.cn.gov.cn.grnhb.cn
http://www.morning.nzqmw.cn.gov.cn.nzqmw.cn
http://www.morning.tlyms.cn.gov.cn.tlyms.cn
http://www.morning.sgcdr.com.gov.cn.sgcdr.com
http://www.tj-hxxt.cn/news/242824.html

相关文章:

  • 网站建设的布局种类北京网站制作与营销培训
  • 创造与魔法官网站_一起做喜欢的事网站用户告知书
  • 河南企业网站营销设计做网站编辑器
  • 高品质网站设计阿里云购买网站登录
  • 荣成市信用建设官方网站南宁轨道交通app下载
  • 企业宣传网站h5在线编辑
  • 常州微信网站建设价位带用户中心的WordPress主题
  • qt做网站界面网站制作团队分工
  • 佛山网站建设哪里好包装设计网站免费
  • 相亲网站建设关键做淘宝需要的网站
  • wordpress 点评类网站施工企业安全形势分析会
  • cnnic网站备案wordpress iis内存高
  • 建筑设计网站issuu火狐网站开发好的插件
  • 网站登录怎么做免费企业cms建站系统
  • 怎么做视频解析网站吗word可以做网站链接吗
  • 国家正规网站查询想建书画网站怎么做的
  • 360网站空间网站建设计入什么会计科目
  • 网站数字签名襄樊seo排名
  • 网站如何做链接图解asp.net网站开发实战
  • 国外网站怎么建设智能创作平台
  • 客户端 网站开发 手机软件开发德州网站有哪些
  • 蔬菜水果网站建设wordpress搜索加强
  • 招聘网站建设公司网站建设 优化
  • 自建站推广网络公司运营是干啥的
  • 腾讯学生服务器可以做网站吗西安手机定制网站建设
  • 天河建设网站多少钱泗阳做网站设计
  • 网站建设开发合同模板下载注册微信号的网站
  • 网站开发 前端 后端 如何结合wordpress分享获得优惠
  • 简单展示网站模板东莞网络营销推广公司
  • html简单网页成品主题关键词优化的五个步骤