目前开发平台使用的是webapi做服务层,客户端使用的是asp.net MVC,每次请求都要去调用webapi,其中客户端使用的是httpClient来调用api,其中写了一个公共的post方法:
当做测试的时候发现TCP连接数很高,之前看到dudu的一篇文章中也介绍使用静态唯一实例,不销毁HttpClient对象,重用TCP连接,可是从面相对象的思想来考虑,每次我都会添加不同的httpHeader,那么发生并发的时候肯定会照成线程不安全,这种情况下怎么来重用TCP连接?
可以使用 SendAsync(HttpRequestMessage request); ,在HttpRequestMessage中添加请求头。
感谢站长
加锁呗,(java)
private volatile static HttpClient httpClient;
private static HttpClient getClient() {
if (httpClient == null) {
synchronized (HttpTookit.class) {
if (httpClient == null) {
HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams httpConnectionManagerParams = new HttpConnectionManagerParams();
httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(15);
httpConnectionManagerParams.setConnectionTimeout(60000);
httpConnectionManagerParams.setSoTimeout(60000);
httpConnectionManager.setParams(httpConnectionManagerParams);
HttpClientParams params = new HttpClientParams();
params.setContentCharset(CHARSET_NAME);
httpClient = new HttpClient(params, httpConnectionManager);
}
}
}
return httpClient;
}
不能加锁的,并发是必须允许的
你想用多个HttpClient又不想让多个TCP。这个是悖论,不可能的。
官方推荐是一个域使用一个HttpClient。
按你所说,你的header一直变动是不应该的,资源条件应该放在url里面,数据应该放在content里面,你header来回变动是做什么用的呢?即使变动也无非是header变动。
你在找一种能让你的错误的使用方法变得不出错的办法……
我服务器IP是没有变化的,但是其中Head保存的是票据,如果票据过期了,头里面要携带票据的
@侯文成: 你的意思是Reponse回复的时候带Header么?发送的时候,Header你尽管改,没有问题的。假设这样一个场景,你Header目前是h1,你r1在请求的时候用的是h1,此时,r2要请求,计划也用h1,但是,同时你r3要用h2请求,导致你的r2用的不是h1而是和r3一样都用的是h2。你的意思是担心这样的问题么?
你同一个域下,一个请求应该是可以一直或者在将来的持续一段时间内都生效可重复的,否则幂等性就没有了。票据正常也是放在Auth里面的,也是放在头中,所以,你的操作没有问题。只是,你的票据不应该每次都变的吧,如果每次都变,你并发都做没办法并发。
如果过期——说明,不变是常态,但是在一定情况下会变,这种情况,你直接改就可以了呀。
httpHeader是数据,这跟连接没有什么关系。
http会封装tcp连接,以及长短连接(服务器没设置够时间等于零)。
意思是说将http使用(相对)长连接,至于你header等等数据,你该怎么用还怎么用。
因为我为了重用TCP连接,使用的是静态唯一变量,虽然是请求的同一台API服务器,我需要不同的业务使用不同的HttpHeader,dudu站长的是正解
让服务端开启keepalive,客户端同样夹带这个头
这个肯定是要加的,不过最终的问题与这个无关,主要是不能销毁HttpClient
请问能贴下你的代码吗?
您好,请问您的并发量去到多少呢?我测试了一下,并发了超过10个,就会非常慢。