问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

java httpclient 并发量大怎么办

发布网友 发布时间:2022-04-29 18:48

我来回答

2个回答

懂视网 时间:2022-04-22 23:40

并发相信对大家来说都不陌生,这篇文章主要给大家介绍了关于使用async、enterproxy控制并发数量的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面一起学习学习吧。

聊聊并发与并行

并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

并发我们经常提及之,不管是web server,app并发无处不在,操作系统中,指一个时间段中几个程序处于已经启动运行到完毕之间,且这几个程序都是在同一处理机上运行,并且任一个时间点只有一个程序在处理机上运行。很多网站都有并发连接数量的限制,所以当请求发送太快的时候会导致返回值为空或报错。更有甚者,有些网站可能因为你发出的并发连接数量过多而当你是在恶意请求,封掉你的ip。

相对于并发,并行可能陌生了不少,并行指一组程序按独立异步的速度执行,不等于时间上的重叠(同一个时刻发生),通过增加cpu核心来实现多个程序(任务)的同时进行。没错,并行做到了多任务的同时进行

使用enterproxy控制并发数量

enterproxy是朴灵大大为主要贡献的工具,带来一种事件式编程的思维变化,利用事件机制解耦复杂业务逻辑,解决了回调函数耦合性的诟病,将串行等待变成并行等待,提升多异步协作场景下的执行效率

我们如何使用enterproxy控制并发数量?通常如果我们不使用enterproxy和自制的计数器,我们如果抓取三个源:

这种深层嵌套,串行的方式

 var render = function (template, data) {
 _.template(template, data);
 };
$.get("template", function (template) {
 // something
 $.get("data", function (data) {
 // something
 $.get("l10n", function (l10n) {
 // something
 render(template, data, l10n);
 });
 });
});

除去这种过去深层嵌套的方法,我们常规的写法的自己维护一个计数器

(function(){
 var count = 0;
 var result = {};
 
 $.get('template',function(data){
 result.data1 = data;
 count++;
 handle();
 })
 $.get('data',function(data){
 result.data2 = data;
 count++;
 handle();
 })
 $.get('l10n',function(data){
 result.data3 = data;
 count++;
 handle();
 })

 function handle(){
 if(count === 3){
 var html = fuck(result.data1,result.data2,result.data3);
 render(html);
 }
 }
})();

在这里,enterproxy就可以起到这个计数器的作用,它帮你管理这些异步操作是否完成,完成之后,他会自动调用你提供的处理函数,并将抓取到数据当做参数传递过来

var ep = new enterproxy();
ep.all('data_event1','data_event2','data_event3',function(data1,data2,data3){
 var html = fuck(data1,data2,data3);
 render(html);
})

$.get('http:example1',function(data){
 ep.emit('data_event1',data);
})

$.get('http:example2',function(data){
 ep.emit('data_event2',data);
})

$.get('http:example3',function(data){
 ep.emit('data_event3',data);
})

enterproxy还提供了其他不少场景所需的API,可以自行学习下这个API enterproxy

使用async控制并发数量

假如我们有40个请求需要发出,很多网站可能会因为你发出的并发连接数太多而当你是在恶意请求,把你的IP封掉。
所以我们总是需要控制并发数量,然后慢慢抓取完这40个链接。

使用async中mapLimit控制一次性并发数量为5,一次性只抓取5个链接。

 async.mapLimit(arr, 5, function (url, callback) {
 // something
 }, function (error, result) {
 console.log("result: ")
 console.log(result);
 })

我们首先应该知道什么是并发,为什么需要限制并发数量,都有哪些处理方案。然后就可以去文档具体看一下API如何使用。async文档可以很好的学习这些语法。

模拟一组数据,这里返回的数据是假的,返回的延时是随机的。

var concurreyCount = 0;
var fetchUrl = function(url,callback){
 // delay 的值在 2000 以内,是个随机的整数 模拟延时
 var delay = parseInt((Math.random()* 10000000) % 2000,10);
 concurreyCount++;
 console.log('现在并发数是 ' , concurreyCount , ' 正在抓取的是' , url , ' 耗时' + delay + '毫秒');
 setTimeout(function(){
 concurreyCount--;
 callback(null,url + ' html content');
 },delay);
}

var urls = [];
for(var i = 0;i<30;i++){
 urls.push('http://datasource_' + i)
}

然后我们使用async.mapLimit来并发抓取,并获取结果。

async.mapLimit(urls,5,function(url,callback){
 fetchUrl(url,callbcak);
},function(err,result){
 console.log('result: ');
 console.log(result);
})

模拟摘自alsotang

运行输出后得到以下结果

我们发现,并发数从1开始增长,但是增长到5时,就不在增加。然有任务时就继续抓取,并发连接数量始终控制在5个。

完成node简易爬虫系统

因为alsotang前辈的《node包教不包会》教程例子中使用的eventproxy控制的并发数量,我们就来完成一个使用async控制并发数量的node简易爬虫。

爬取的目标就是本站首页(手动护脸)

第一步,首先我们需要用到以下的模块:

  • url : 用于url解析,这里用到url.resolve()生成一个合法的域名

  • async : 一个实用的模块,提供了强大的功能和异步JavaScript工作

  • cheerio : 为服务器特别定制的,快速,灵活,实施的jQuery核心实现

  • superagent : nodejs里一个非常方便的客户端请求代理模块

  • 通过npm安装依赖模块

    第二步,通过require引入依赖模块,确定爬取对象URL:

    var url = require("url");
    var async = require("async");
    var cheerio = require("cheerio");
    var superagent = require("superagent");
    var baseUrl = 'http://www.chenqaq.com';

    第三步:使用superagent请求目标URL,并使用cheerio处理baseUrl得到目标内容url,并保存在数组arr中

    superagent.get(baseUrl)
     .end(function (err, res) {
     if (err) {
     return console.error(err);
     }
     var arr = [];
     var $ = cheerio.load(res.text);
     // 下面和jQuery操作是一样一样的..
     $(".post-list .post-title-link").each(function (idx, element) {
     $element = $(element);
     var _url = url.resolve(baseUrl, $element.attr("href"));
     arr.push(_url);
     });
     // 验证得到的所有文章链接集合
     output(arr);
     // 第四步:接下来遍历arr,解析每一个页面需要的信息
    })

    我们需要一个函数验证抓取的url对象,很简单我们只需要一个函数遍历arr并打印出来就可以:

    function output(arr){
     for(var i = 0;i<arr.length;i++){
     console.log(arr[i]);
     }
    }

    第四步:我们需要遍历得到的URL对象,解析每一个页面需要的信息。

    这里就需要用到async控制并发数量,如果你上一步获取了一个庞大的arr数组,有多个url需要请求,如果同时发出多个请求,一些网站就可能会把你的行为当做恶意请求而封掉你的ip

    async.mapLimit(arr,3,function(url,callback){
     superagent.get(url)
     .end(function(err,mes){
     if(err){
     console.error(err);
     console.log('message info ' + JSON.stringify(mes));
     }
     console.log('「fetch」' + url + ' successful!');
     var $ = cheerio.load(mes.text);
     var jsonData = {
     title:$('.post-card-title').text().trim(),
     href: url,
     };
     callback(null,jsonData);
     },function(error,results){
     console.log('results ');
     console.log(results);
     })
     })

    得到上一步保存url地址的数组arr,限制最大并发数量为3,然后用一个回调函数处理 「该回调函数比较特殊,在iteratee方法中一定要调用该回调函数,有三种方式」

  • callback(null) 调用成功

  • callback(null,data) 调用成功,并且返回数据data追加到results

  • callback(data) 调用失败,不会再继续循环,直接到最后的callback

  • 好了,到这里我们的node简易的小爬虫就完成了,来看看效果吧

    嗨呀,首页数据好少,但是成功了呢。

    参考资料

    Node.js 包教不包会 - alsotang

    enterproxy

    async

    async Documentation

    上面是我整理给大家的,希望今后会对大家有帮助。

    相关文章:

    在js中如何实现登录需要滑动验证

    在js中如何实现判断文件类型大小

    在vue中如何使用cdn优化

    热心网友 时间:2022-04-22 20:48

    java httpclient 并发量大解决办法:
    首先你要增加一个关于异步IO需要的包:

    1、async-http-client包,可以在这里下载:https://oss.sonatype.org/content/repositories/releases/com/ning/async-http-client/1.6.2/
    2、log4j的包,这个不用我说了,都知道在哪里
    3、slf4j-spi 的包,目前用1.5以上的版本比较多。
    4、slf4j-log4j 的包,可以看出,slf4j是在log4j基础上包装的。
    OK,就这几个了,弄好后再看看下面这段代码,通过使用它,性能可以得到明显改善:

    [java] view plain
    AsyncHttpClient client = new AsyncHttpClient();
    try {
    Future<Response> f = client.prepareGet("http://www.google.com.hk/").execute();
    System.out.println(f.get().getResponseBody("Big5"));//谷歌的输出编码集为Big5,反向解析结果的时候使用
    }catch(...) {....}

    这段代码是不是超级简单,可以通过上面描述的三种方式:
    1、直接调用
    2、将GetMethod或PostMethod对象作为共享对象反复使用。
    3、使用AsyncHttpClient
    这三种方法,非别使用一次调用、循环多次调用、并发调用来测试性能,后面两者的性能比第一种方法的性能要高很多。
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    ...二极管 电动车的电瓶因为出于成本考虑,将新旧电瓶混用,因为旧电池内 ... 两个不同容量的蓄电池并联后怎么防止大容量电池向小容量电池放电 工伤后小孩有抚养费吗,会给多少钱 南京工伤死亡子女抚养费标准 邵阳车管所疫情上班吗 2023年验车推迟吗,2023年检车线什么时候上班 全面复工包括黔江车管所不 江宁车管所什么时候复工 疫情期间交警几点下班? 3d和值多少算中奖? java写的web程序 怎么做压力测试呀,就是测试并发率(同一时间最大支持多少用户请求呢)? java的压力测试和并发测试 JAVA如何写一个纯并发的压力测试 coco奶茶公司的奖励制度 现代企业的人才理念是什么呢? 如何在国企改善或建立有效的奖励或惩罚机制? 现在很多公司为了督促员工搞了很多奇葩的奖惩制度,最奇葩的是什么? 企业的奖励方式有哪些 特别奖励制度的方式 风暴英雄 好友组队经验值奖励制度会加英雄经验吗 东方晓鸣 精彩 求:影楼员工奖励制度50条 加分 !!! 特别奖励制度的举例 为什么二极管可以当做开关来使用 当二极管接不同极性的电源时。会有几种情况发生。? 什么情况下能把二极管当成开关? 怎么样才能让腿变细?? 当二极管外加电压时,反向电流很小,且不随什么变化 苹果笔记本在做直播时怎样把声音打开? 抖音里面的小程序怎么删除- 问一问 用java的netty框架写了一个udp服务端,怎么测试它能承受的并发压力 java多线程怎么测试 有什么做压力测试的工具?我想模拟多用户并发操作。(JAVA) Java Web应用如何压力测试?工具有哪些?具体怎么做? java服务使得占用cpu能够达到300%多以上,压力测试甚至400%以上 java spring 定时任务 性能测试怎么做? 什么是VIP?VIP的作用是什么呀? VIP表示什么? 微信象棋残局第360关怎么过? 中国象棋360关怎么过 华为手机如何分上下屏 微信象棋残局360关求破解求破解 JJ象棋沙场点兵第一关到第360关怎么过 微信腾讯中国象棋残局第53关怎么过 图文攻略详解 腾讯天天象棋楚汉争霸59关视频录像视频 帮小女孩取个富有含义的名字 聪明伶俐,独特,好听,富有诗情画意的女孩名字 支付宝没付款成功逃单的人怎么追查 qq二维码怎么制作 关于数据库分页处理的SQL语句(本人用的数据库是SQL2008)