shi0299 2013-11-07 05:47 采纳率: 0%
浏览 1021

httpcilent连接发数问题

​我这边服务器有两个项目,分别是websphere和tomcat部署起来的。两个项目中都有涉及远程发送报文的功能。现在tomcat 部署的那个项目出现了变更,发送地址需要代理之后才能连接并发送成功。我在代码里加入了client.getHostConfiguration().setProxy("")这个方法添加代理。但现在问题出现了,因为两个项目的里都是实时的定时任务,有可能会一个时间点多个任务线程同步执行。当tomcat里执行连接并发数时,websphere里的任务就连接不上它自己的远程地址了,应该是因为tomcat里的项目设置了代理,发生了冲突。因为websphere里的远程地址必须在非代理下才能连接。怎么解呢?

  • 写回答

1条回答 默认 最新

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-11-23 22:49
    关注

    所有内容均由人工智能模型输出,其内容的准确性和完整性无法保证,不代表我的态度或观点。

    该回答引用ChatGPT-3.5,仅为您提供参考,不保证完全正确
    在这种情况下,你可以考虑在代码中为不同的任务使用不同的HttpClient实例,以确保它们之间的配置不会相互干扰。每个HttpClient实例都可以设置自己的代理配置,以满足各自的需求。以下是一个简单的示例代码,展示如何创建和使用多个HttpClient实例:

    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HostConfiguration;
    import org.apache.commons.httpclient.HttpException;
    import org.apache.commons.httpclient.methods.GetMethod;
    
    public class MultipleHttpClientExample {
        public static void main(String[] args) {
            // 创建一个 HttpClient 实例,用于 Tomcat 项目
            HttpClient tomcatClient = new HttpClient();
            tomcatClient.getHostConfiguration().setProxy("your_tomcat_proxy_host", your_tomcat_proxy_port);
    
            // 创建另一个 HttpClient 实例,用于 WebSphere 项目
            HttpClient websphereClient = new HttpClient();
            // websphereClient 不设置代理,使用默认的非代理配置
    
            // 在需要发送请求的地方使用相应的 HttpClient 实例
            try {
                // Tomcat 项目发送请求的代码
                GetMethod tomcatMethod = new GetMethod("your_tomcat_url");
                tomcatClient.executeMethod(tomcatMethod);
                // 处理 tomcatMethod 的响应
    
                // WebSphere 项目发送请求的代码
                GetMethod websphereMethod = new GetMethod("your_websphere_url");
                websphereClient.executeMethod(websphereMethod);
                // 处理 websphereMethod 的响应
            } catch (HttpException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 关闭 HttpClient 实例
                tomcatClient.getHttpConnectionManager().closeIdleConnections(0);
                websphereClient.getHttpConnectionManager().closeIdleConnections(0);
            }
        }
    }
    

    在这个示例中,我们创建了两个不同的HttpClient实例,分别用于 Tomcat 项目和 WebSphere 项目。每个实例都可以设置自己的代理配置。在实际使用中,你需要根据你的具体需求修改代码,并确保在不同的任务中使用不同的HttpClient实例。


    该回答引用NewBing,仅为您提供参考,不保证完全正确
    你好,这是 Bing。我尝试了一下搜索你的问题,发现了一些可能有用的信息。


    根据这篇文章,你可以使用 HttpClient 的 setProxy 方法来为每个请求设置不同的代理,而不是使用 getHostConfiguration().setProxy 方法来为整个客户端设置代理。这样就可以避免代理设置的冲突。例如:

    // 创建一个 HttpClient 实例
    HttpClient client = new HttpClient();
    
    // 创建一个 GET 方法
    GetMethod get = new GetMethod("http://www.example.com");
    
    // 设置代理
    client.getParams().setBooleanParameter(ConnRoutePNames.DEFAULT_PROXY, true);
    HttpHost proxy = new HttpHost("proxy.example.com", 8080);
    client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
    
    // 执行方法并处理响应
    int statusCode = client.executeMethod(get);
    if (statusCode == HttpStatus.SC_OK) {
      String response = get.getResponseBodyAsString();
      // 处理响应
    }
    get.releaseConnection();
    

    源: 与必应的对话, 2023/11/23
    (1) HttpClient用法--这一篇全了解(内含例子)-CSDN博客. https://blog.csdn.net/w372426096/article/details/82713315.
    (2) Apache HttpClient 详解 - 掘金. https://juejin.cn/post/7052900785381703694.
    (3) 使用 HttpClient 发出 HTTP 请求 - .NET | Microsoft Learn. https://learn.microsoft.com/zh-cn/dotnet/fundamentals/networking/http/httpclient.
    (4) Angular - HttpClient. https://angular.io/api/common/http/HttpClient.
    (5) Make HTTP requests with the HttpClient - .NET | Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient.


    该回答引用文心大模型3.5,仅为您提供参考,不保证完全正确
    您的问题是关于Java的HttpClient设置代理后引起的并发问题。由于您不能确定何时一个任务线程会尝试同时连接到Tomcat和Websphere,因此您需要确保每个线程都有其自己的HttpClient实例。HttpClient实例是线程安全的,并且应该为每个任务提供独立的实例。这样可以避免由于一个任务的代理设置影响其他任务的问题。


    以下是一个简单的例子,说明如何在每次任务执行时创建新的HttpClient实例:

    public class MyTask implements Runnable {
        private final String url;
    
        public MyTask(String url) {
            this.url = url;
        }
    
        @Override
        public void run() {
            try {
                HttpClient client = HttpClientBuilder.create().build();
                HttpGet httpGet = new HttpGet(url);
                HttpResponse response = client.execute(httpGet);
                // 处理响应...
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在这个例子中,每个任务都会创建一个新的HttpClient实例,这样它们就不会共享相同的代理设置。


    另一种可能的解决方案是,为不同的任务使用不同的HttpClient实例,并为每个实例设置不同的代理。但是,这可能会使代码变得更复杂,并可能导致更多的资源浪费。因此,我建议为每个任务创建新的HttpClient实例。


    该回答引用讯飞星火认知大模型,仅为您提供参考,不保证完全正确
    你可以尝试使用线程局部变量(ThreadLocal)来解决这个问题。将代理设置存储在每个线程的局部变量中,这样每个线程都有自己的代理设置,不会相互干扰。以下是一个简单的示例:

    public class ProxyConfig {
        private static final ThreadLocal<String> PROXY_HOST = new ThreadLocal<>();
        private static final ThreadLocal<Integer> PROXY_PORT = new ThreadLocal<>();
    
        public static void setProxy(String host, int port) {
            PROXY_HOST.set(host);
            PROXY_PORT.set(port);
        }
    
        public static String getProxyHost() {
            return PROXY_HOST.get();
        }
    
        public static Integer getProxyPort() {
            return PROXY_PORT.get();
        }
    
        public static void clearProxy() {
            PROXY_HOST.remove();
            PROXY_PORT.remove();
        }
    }
    

    在你的定时任务中,使用这个类来设置和获取代理信息:

    // 设置代理
    ProxyConfig.setProxy("proxy.example.com", 8080);
    
    // 获取代理信息
    String proxyHost = ProxyConfig.getProxyHost();
    int proxyPort = ProxyConfig.getProxyPort();
    
    // 使用代理连接远程地址
    client.getHostConfiguration().setProxy(proxyHost, proxyPort);
    

    这样,每个线程都有自己的代理设置,不会相互干扰。在任务执行完成后,记得清除代理设置:

    // 清除代理设置
    ProxyConfig.clearProxy();
    

    该回答引用通义千问大模型,仅为您提供参考,不保证完全正确
    在你的Tomcat项目中,你可以尝试在每次建立HTTP客户端连接后立即关闭它。这是因为,在没有明确关闭的情况下,HTTP客户端将保持与服务器之间的TCP/IP连接处于活动状态,并且在达到操作系统设定的最大值后,不能再建立新的连接。


    下面是一个示例:

    CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
        // 执行请求
    } finally {
        httpClient.close();
    }
    

    另一种解决方案是在Tomcat项目中配置不同的HTTP客户端实例用于不同的远程地址,其中一个是通过代理服务器访问,另一个则直接访问。你可以使用Apache HttpClient的ConnectionManager来实现这一点。


    以下是一个示例:

    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(20);
    
    HttpHost proxy = new HttpHost("your_proxy_host", your_proxy_port, "http");
    RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
    
    CloseableHttpClient directHttpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setDefaultRequestConfig(config)
            .build();
    
    HttpHost directTarget = new HttpHost(your_direct_target_host, your_direct_target_port, "http");
    HttpGet directGet = new HttpGet("/");
    directGet.setHeader("Host", directTarget.getHostName());
    CloseableHttpResponse directResponse = directHttpClient.execute(directTarget, directGet);
    

    请注意,这只是一个基本示例,你需要根据具体情况进行调整。例如,你可能需要确保在完成所有操作后正确地关闭连接管理器,以及在系统启动时初始化连接管理器等。

    评论

报告相同问题?

悬赏问题

  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退
  • ¥20 win系统的PYQT程序生成的数据如何放入云服务器阿里云window版?
  • ¥50 invest生境质量模块