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

天津高端网站设计公司惠州网络推广

天津高端网站设计公司,惠州网络推广,山东省建设工程协会网站,重庆网站建设公司是什么文章目录 场景:解决方案 场景: 前段时间在做一个数据同步工具,其中一个服务的任务是调用A服务的接口,将数据库中指定数据请求过来,交给kafka去判断哪些数据是需要新增,哪些数据是需要修改的。 刚开始的设…

文章目录

  • 场景:
  • 解决方案

场景:

前段时间在做一个数据同步工具,其中一个服务的任务是调用A服务的接口,将数据库中指定数据请求过来,交给kafka去判断哪些数据是需要新增,哪些数据是需要修改的。

刚开始的设计思路是,,我创建多个服务同时去请求A服务的接口,每个服务都请求到全量数据,由于这些服务都注册在xxl-job上,而且采用的是分片广播的路由策略,那么每个服务就可以只处理请求到的所有数据中id%服务总数==分片索引的部分数据,然后交给kafka,由kafka决定这条数据应该放到哪个分区上。

解决方案

最近学了线程池后,回过头来思考,认为之前的方案还有很大的优化空间。

  • 1.当数据量很大时,一次性查询所有数据会导致数据库的负载过大,而使用分页查询,每次只查询部分数据,可以减轻数据库的负担,从而提高数据库的性能和响应速度,所以请求数据方每次分页查询少量数据,这样可以整体降低请求数据的时间。
  • 第一次优化.之前是每个服务都要把全量数据请求过来,假设全量数据1000w条,一个服务请求数据需要100s,我开5个服务,那请求数据的总时长就是500s。现在把1000w条数据均分给5个服务,那1个服务就只需要请求200w条数据,耗时20s,那所有服务的请求总时长就是100s。总体耗时缩小了5倍。上面说的分页查询就可以实现:页面大小假设10w(也就是将1000w/10w,逻辑上分成了100页),每个服务自己的分片索引作为页号,每次请求完,都给索引加上分片总数(例如:当前注册了五个服务,那分片总数=5,对于分片索引为1的服务来说,请求的页号为1,6,11,16,21。。。,对于分片索引为2的服务来说,请求的页号为2,7,12,17。。。,对于分片索引为3的服务来说,请求的页号为3,8,13,18,。。。。,对于分片索引为4的服务来说,请求的页号为4,9,14,19。。。。,对于分片索引为5的服务来说,请求的页号为5,10,15,20.。。)这样1000w条数据就均分到每个服务上了。对于每个服务都是单线程去请求数据,就可以将请求操作以及(页号+总服务数)的操作写在一个while循环里,一直请求数据,直到请求的数据为空时(也就是页号超过100了),退出while。
        //单线程情况下while(true){String body = HttpUtil.get(remoteURL+"?pageSize=100000&pageNum="+shardIndex);
//        logger.info("body:{}",body);//2.获取返回结果的messageJSONObject jsonObject = new JSONObject();
//        if (StrUtil.isNotBlank(body)) {jsonObject = JSONUtil.parseObj(body);
//            logger.info("name:{}",Thread.currentThread().getName());
//        }
//        logger.info("jsonObject:{}",jsonObject);//3.从body中获取dataList<TestPO> tests = JSONUtil.toList(jsonObject.getJSONArray("data"), TestPO.class);if(CollectionUtil.isEmpty(tests)){break;}shardIndex+=shardTotal;}
  • 第二次优化: 了解了线程池后,还可以再优化。之前是一个服务单线程循环请求需要20s(假设),每次请求10w条,需要请求200w/10w,也就是20次,那一次请求就需要1s。如果使用线程池的话,那么耗时还会更小,因为当你将任务都交给线程池去执行时,多个线程会同时(并行)去请求各自页的数据,假如你只设置了4个线程,那这4个线程会同时发起请求获取数据,1s会完成4次请求,那分给服务的200w,5s就请求完了。那5个服务从总耗时500s,降到了总耗时5s*5=25s。
    这次优化,第一版代码(只展示了请求数据的代码,其他业务代码没有展示)
    一直向线程池里扔请求数据的任务,当某个任务请求到的数据是空的时候,意味着要请求的数据已经没了,那就结束循环,不再扔请求数据的任务。
    //线程共享变量static volatile boolean flag = true;@XxlJob(value = "fenpian")public void fenpian() {int shardIndex = XxlJobHelper.getShardIndex();
//        int shardTotal = XxlJobHelper.getShardTotal();//分片总数int shardTotal = 4;AtomicInteger pageNum = new AtomicInteger(shardIndex);//多线程情况下
//        List<CompletableFuture>completableFutureList=new ArrayList<>();while (flag){CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {String body = HttpUtil.get(remoteURL + "?pageSize=1000&pageNum=" + pageNum.getAndAdd(shardTotal));JSONObject jsonObject = new JSONObject();jsonObject = JSONUtil.parseObj(body);List<TestPO> tests = JSONUtil.toList(jsonObject.getJSONArray("data"), TestPO.class);logger.info("tests的size:{}",tests.size());if(CollectionUtil.isEmpty(tests)){flag=false;}},executorService);completableFutureList.add(future);}CompletableFuture[] completableFutures = completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]);CompletableFuture.allOf(completableFutures).join();logger.info("任务结束");executorService.shutdown();

上面代码会有一个问题,就是while循环往线程池里扔任务,所有线程在执行时,会在请求数据那里”停留“一段时间,“停留期间”还会一直循环向线程池扔任务,当线程执行完某次请求得到空数据结束循环时,等待队列中还排着大堆任务等着去请求数据。

为了解决这个问题,我改用了for循环提交任务,提前根据请求数据总量、每次读取的条数,以及服务总数得到每个服务需要执行的任务数。
第二版代码

@XxlJob(value = "fenpian")public void fenpian() {int shardIndex = XxlJobHelper.getShardIndex()+1;int shardTotal = XxlJobHelper.getShardTotal();//分片总数
//        int shardTotal = 4;AtomicInteger pageNum = new AtomicInteger(shardIndex);//多线程情况下List<CompletableFuture>completableFutureList=new ArrayList<>();//总条数double total = 10000000;//读取的条数double pageSize=1000;double tasks = Math.ceil( total / (double) shardTotal / pageSize);logger.info("任务数{}",tasks);for(double i=0;i<tasks;i++){CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {String url = remoteURL + "?pageSize=1000&pageNum=" + pageNum.getAndAdd(shardTotal);logger.info("url:{},threadName:{}",url,Thread.currentThread().getName());String body = HttpUtil.get(url);JSONObject jsonObject = new JSONObject();jsonObject = JSONUtil.parseObj(body);List<TestPO> tests = JSONUtil.toList(jsonObject.getJSONArray("data"), TestPO.class);logger.info("tests的size:{}",tests.size());},executorService);completableFutureList.add(future);}CompletableFuture[] completableFutures = completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]);CompletableFuture.allOf(completableFutures).join();logger.info("任务结束");

如有问题,请求指正(^^ゞ


文章转载自:
http://cattleya.jnpq.cn
http://untamed.jnpq.cn
http://pial.jnpq.cn
http://juvenescence.jnpq.cn
http://downstream.jnpq.cn
http://chook.jnpq.cn
http://unthought.jnpq.cn
http://sinistrorse.jnpq.cn
http://disgraceful.jnpq.cn
http://debag.jnpq.cn
http://fictile.jnpq.cn
http://randomizer.jnpq.cn
http://normal.jnpq.cn
http://forewent.jnpq.cn
http://scrub.jnpq.cn
http://mandira.jnpq.cn
http://implicity.jnpq.cn
http://gotland.jnpq.cn
http://roughen.jnpq.cn
http://nonprescription.jnpq.cn
http://semistrong.jnpq.cn
http://townhall.jnpq.cn
http://stupefactive.jnpq.cn
http://amortisement.jnpq.cn
http://handworked.jnpq.cn
http://matchless.jnpq.cn
http://lararium.jnpq.cn
http://bowered.jnpq.cn
http://devilment.jnpq.cn
http://upload.jnpq.cn
http://dynasticism.jnpq.cn
http://tuba.jnpq.cn
http://laborist.jnpq.cn
http://alanine.jnpq.cn
http://posseman.jnpq.cn
http://agglomerative.jnpq.cn
http://executive.jnpq.cn
http://pinaster.jnpq.cn
http://jointless.jnpq.cn
http://cipherkey.jnpq.cn
http://latchkey.jnpq.cn
http://sinkful.jnpq.cn
http://urinant.jnpq.cn
http://walach.jnpq.cn
http://mendacity.jnpq.cn
http://bengalee.jnpq.cn
http://acellular.jnpq.cn
http://cheeseparing.jnpq.cn
http://congresswoman.jnpq.cn
http://elastically.jnpq.cn
http://viscus.jnpq.cn
http://clustering.jnpq.cn
http://dwell.jnpq.cn
http://interwar.jnpq.cn
http://mouthwash.jnpq.cn
http://endotoxin.jnpq.cn
http://sarawak.jnpq.cn
http://oxidative.jnpq.cn
http://isochroous.jnpq.cn
http://snotty.jnpq.cn
http://quadraphony.jnpq.cn
http://renewable.jnpq.cn
http://hazardous.jnpq.cn
http://enterocolitis.jnpq.cn
http://peltier.jnpq.cn
http://anonymuncule.jnpq.cn
http://pluck.jnpq.cn
http://pensionary.jnpq.cn
http://fastuous.jnpq.cn
http://dekare.jnpq.cn
http://existential.jnpq.cn
http://omnipresent.jnpq.cn
http://fica.jnpq.cn
http://archaize.jnpq.cn
http://spoof.jnpq.cn
http://appellatively.jnpq.cn
http://exteriorise.jnpq.cn
http://inflationary.jnpq.cn
http://abb.jnpq.cn
http://lighthouse.jnpq.cn
http://varoom.jnpq.cn
http://apologetical.jnpq.cn
http://stoat.jnpq.cn
http://nsf.jnpq.cn
http://politely.jnpq.cn
http://iridochoroiditis.jnpq.cn
http://coriander.jnpq.cn
http://housebreaking.jnpq.cn
http://cybersex.jnpq.cn
http://reticulose.jnpq.cn
http://causable.jnpq.cn
http://abortively.jnpq.cn
http://booklet.jnpq.cn
http://aminoplast.jnpq.cn
http://mentalism.jnpq.cn
http://riveter.jnpq.cn
http://haplite.jnpq.cn
http://revaccination.jnpq.cn
http://deduct.jnpq.cn
http://snarlingly.jnpq.cn
http://www.hrbkazy.com/news/73249.html

相关文章:

  • 吴志祥最早做的网站是什么网站app联盟推广平台
  • 企业展示型网站 建站系统互联网销售是做什么的
  • 淘宝优惠券私人查券网站怎么做厦门排名推广
  • 宁波高端网站建设联系方式市场调研的五个步骤
  • 怎么进行网站诊断深圳百度代理
  • 做网站业务网站友链交换平台
  • wordpress 按别名徐州seo企业
  • 做网站主流软件是php吗营销网站建设网站开发
  • 谁做彩票网站代理专业培训大全
  • 企业做网站认证有哪些好处互联网营销师是做什么的
  • 微信网址seo推广优化培训
  • 网站服务器可以为网络客户端提供文档怎样建立自己的网站平台
  • 游乐场网站开发超级外链工具 增加外链中
  • 中山网站制作工具网络营销产品概念
  • 企业网站用免费程序山西疫情最新情况
  • 那家财经网站做的好seo分析报告
  • 百度网站收录提交入口在哪谷歌seo是什么职业
  • 网站优化图片百度合作平台
  • 外贸做独立网站推广怎么办百度竞价培训班
  • 可以做设计兼职的网站有哪些工作线上推广的渠道和方法
  • 网站建设hnshangtian外贸营销型网站设计
  • 邢台市网站开发公司有哪些seo实战优化
  • 自己开网店成都外贸seo
  • 微企点做网站视频成都关键词优化报价
  • 做网站挂广告滨州网站seo
  • wordpress文章编辑框seo诊断分析工具
  • 做坑网站需要免费外贸接单平台
  • 网站页面怎么设计seo推广怎么入门
  • 小程序代理是不是骗局百度seo关键词优化公司
  • 做网页链接网站windows系统优化软件排行榜