Tomcat 中的 WEB 应用如何使用代理向外部发起请求

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat 中的 WEB 应用如何使用代理向外部发起请求相关的知识,希望对你有一定的参考价值。

一直使用的阿里云ECS,经典网络类型。为什么不采用典型的专有网络 VPC 呢?因为考虑到成本嘛,而且也没有人来专门规划整个网络的,所以就采用最简单的经典网络,每台主机各自为政,都有自己的公网、私网出口,互不影响。

通过这种方式,发现有的服务器根本不需要外网带宽,比如负载均衡后面的服务器,因为负载均衡都是通过内网传输数据的,所以公网带宽完全就闲置起来了,而且暴露在公网中也比较危险。所以我们就开始购入没有公网IP的经典网络ECS。然后就遇到了下面的各种问题。

阿里云没有购买公网的情况下,不分配公网IP,也不能访问外网的资源,只能访问在同一个机房里面的服务器内网IP。这可怎么办呢?我们有些业务服务器是需要和外网进行交互的,比如进行资源加速的时候,是需要和CDN厂商服务器进行连接的,为了解决这个问题。我们在该机房中购买了一台公网带宽比较大的服务器,作为访问外网的代理服务器,安装了HTTP代理服务软件(记住哦,自己架设的代理服务器一定要设置密码,而且必须是强密码,不然一两天之类就会被整崩溃的。)

现在就开始把以前老的应用程序迁移到这台只有内网访问权限的服务器上,现在这台内网服务器上设置全局的HTTP代理信息,刚开始迁移php程序的时候,没任何问题,因为会自动根据系统的代理信息进行连接,但是Java web程序貌似走不通哎。现在重点讲 Java web如何使用代理程序进行连接。

前置条件:Tomcat VM 设置参数: 

-Dhttp.proxyHost=10.0.0.1 -Dhttp.proxyPort=1234

我分析了以下几种情况

  1. 使用jdk里面自带的库进行请求的时候,会自动根据VM参数进行连接。没有使用第三方库,详细代码参见:
技术分享
 1  private static String sendGetByDefault(String url, String param) {
 2         String result = "";
 3         BufferedReader in = null;
 4         try {
 5             String urlNameString = url + "?" + param;
 6             URL realUrl = new URL(urlNameString);
 7             // 打开和URL之间的连接
 8             URLConnection connection = realUrl.openConnection();
 9             // 设置通用的请求属性
10             connection.setRequestProperty("accept", "*/*");
11             connection.setRequestProperty("connection", "Keep-Alive");
12             connection.setRequestProperty("user-agent",
13                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
14             // 建立实际的连接
15             connection.connect();
16             // 获取所有响应头字段
17             Map<String, List<String>> map = connection.getHeaderFields();
18             // 遍历所有的响应头字段
19             for (String key : map.keySet()) {
20                 System.out.println(key + "--->" + map.get(key));
21             }
22             // 定义 BufferedReader输入流来读取URL的响应
23             in = new BufferedReader(new InputStreamReader(
24                     connection.getInputStream()));
25             String line;
26             while ((line = in.readLine()) != null) {
27                 result += line;
28             }
29         } catch (Exception e) {
30             System.out.println("发送GET请求出现异常!" + e);
31             e.printStackTrace();
32         }
33         // 使用finally块来关闭输入流
34         finally {
35             try {
36                 if (in != null) {
37                     in.close();
38                 }
39             } catch (Exception e2) {
40                 e2.printStackTrace();
41             }
42         }
43         return result;
44     }
View Code

   2. 使用Apache提供的第三方库,不会根据VM参数进行连接,maven信息参见:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.1</version>
</dependency>

   详细代码参见:

技术分享
 private static String sendGetByApache(String url, String param) {
        StringBuilder buffer = new StringBuilder();

        DefaultHttpClient client = new DefaultHttpClient();
        try {
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
                String str;
                while ((str = br.readLine()) != null) {
                    buffer.append(str);
                }
                br.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }

        return buffer.toString();
    }
View Code

  3. 使用Unirest库进行请求,不会根据VM代理信息进行连接,maven 信息参见:

<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.4.7</version>
</dependency>     

   详细代码参见:

技术分享
 private static String sendGetByUnirestClient(String url, String param) {
        com.mashape.unirest.http.HttpResponse<String> res;
        try {
            res = Unirest.get("http://baidu.com")
                    .queryString("name", "Mark")
                    .asString();
        } catch (UnirestException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return res.getBody();
    }
View Code

  综上所述,基本上使用第三方库的都不会自动使用系统代理,所以我们要对程序进行一下改造。我们建议使用Unirest,因为他提供多种语言的HTTP请求库,并且风格一致,有利于不同语言之间的协作。

  

以上是关于Tomcat 中的 WEB 应用如何使用代理向外部发起请求的主要内容,如果未能解决你的问题,请参考以下文章

tomcat下载安装和配置

nginx反向代理及tomcat负载均衡

Tomcat如何设置代理

Java Tomcat服务器

Tomcat安装部署和安全加固优化以及反向代理应用

Tomcat安装部署和安全加固优化以及反向代理应用