admin管理员组

文章数量:1571195

记在一次技术支持过程中,内网程序(无法上网)在调用一个互联网API接口时无法正常访问,在配置正常的nginx正向代理后,仍然无法访问。
由于涉及项目地址就以下举例说明

1.问题情况


web服务器:172.16.8.6 能访问互联网调用API,但是程序不能部署在web服务器
后台服务器:172.16.7.5 无法访问互联网调用API,但是能与web服务器互联,程序只能部署在后台服务器。
目的:后台服务器172.16.7.5 通过程序正常访问互联网来调用API。
互联网API(举例):www.abc:8000/api/c

2.解决思路

刚开始接触到这个技术支持时,感觉只需要在web服务器上,部署一个nginx正向代理即可解决。在我部署nginx正向代理后,通过非IE的浏览器都能正常访问API接口,获取返回值。
nginx普通的正向代理:

	server {
    # 端口
        listen       8000;
        server_name  localhost;
    # DNS解析地址
        resolver 114.114.114.114;
    # 代理参数
    location / {
        # $http_host就是我们要访问的主机名
        # $request_uri就是我们后面所加的参数
        proxy_pass http://$http_host$request_uri;
		proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_buffers 256 4K;
		proxy_max_temp_file_size 0;
		proxy_connect_timeout 30;
		proxy_cache_valid 200 302 10m;
		proxy_cache_valid 301 1h;
		proxy_cache_valid any 1m;
    }
}

随后在程序中的部署是去绑定对应的域名,比如绑定的地址是www.abc:8000/api
绑定后进行访问连接,提示系统访问出错,请联系管理员。
查看程序的后台报错显示(截取部分):

2021/5/6 14:32:56  错误描述: 调用对象 PlatformBLL.OperatorBase的 OperatorHander
PlatformBLL.RepairFund.BankInterFaceBLL.GetInitiateEBillMsgBodyBase出错。
详情:调用服务异常:url=http://www.abc.com:8000/apiBill?t=63442,System.Net.WebException: The remote name could not be resolved: 'abc'
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()

查看到报错信息:

System.Net.WebException: The remote name could not be resolved: 'abc'

显示abc这个域名无法被解析,但是发现除了IE浏览器不能访问,其他浏览器又能访问获取值,便认为是程序调用有问题,便让研发进行查看是否启用IE内核在调用,研发回复与程序没有关系。查看nginx日志后显示又是正常访问API,自己又去抓包,调整User-Agent,将nginx的User-Agent伪装为谷歌浏览器访问API,程序调用还是失败。
再次去分析报错信息,发现自己的思考方向错误了,报错显示的是**The remote name could not be resolved: ‘abc’**无法解析abc这个域名,但是在nginx日志中又显示的是正常访问。所以我这边需要调整nginx配置,让程序不访问域名,访问web服务器的ip地址去跳转到abc。
所以在正向代理的配置中做了如下调整:
已正向代理访问目的API,以反向代理让程序访问主机ip和端口

	server {
    # 端口
        listen       8000;
    # 地址
        server_name  localhost;
    # DNS解析地址
        resolver 114.114.114.114;
		#resolver 8.8.8.8;
		
    # 代理参数
    location / {
        # $http_host就是我们要访问的主机名
        # $request_uri就是我们后面所加的参数
        #proxy_pass http://$http_host$request_uri;
		#proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		
		proxy_pass http://abc:8000/$request_uri;
		proxy_buffers 256 4K;
		proxy_max_temp_file_size 0;
		proxy_connect_timeout 30;
		proxy_cache_valid 200 302 10m;
		proxy_cache_valid 301 1h;
		proxy_cache_valid any 1m;
    }
}
 	server {
    # 端口
        listen       8001;
        server_name  localhost;
	# 跳转地址
		return  http://$http_host:8001$request_uri;
}

配置好后,由于自己想法是通过访问ip的8001端口,默认跳转到8000端口后到abc中去,所以在后台服务器上的代理端口和程序配置访问的端口都是8001:http://abc:8001/
再次去程序中调用API,结果还是报错:

2021/5/6 17:27:40  错误描述: 调用对象 PlatformBLL.OperatorBase的 OperatorHander
PlatformBLL.RepairFund.BankInterFaceBLL.GetInitiateEBillMsgBodyBase出错。
详情:调用服务异常:url=http://172.16.8.6:8001/api/Bill?t=6376063,System.Net.WebException: Cannot handle redirect from HTTP/HTTPS protocols to other dissimilar ones. ---> System.UriFormatException: Invalid URI: Invalid port specified.
 at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
 at System.Uri.CreateUri(Uri baseUri, String relativeUri, Boolean dontEscape)
 at System.Net.HttpWebRequest.CheckResubmit(Exception& e, Boolean& disableUpload)

在对报错信息分析后,发现关键的错误信息:

Invalid URI: Invalid port specified.

无效的URI是由于端口异常导致的无效,然后我再次去分析nginx的配置发现,其他可以不用通过8001端口去调用API,因为已经使用了proxy_pass把acb的域名直接正向代理访问了,让程序可以直接通过web服务器ip进行访问。
最终在后台主机的代理配置和程序中修改访问的端口为8000
http://172.16.8.6:8000/
再次去调用http://172.16.8.6:8000/api/Bill?t=6376063,显示调用成功,能成功对接API。

3.解决步骤

web服务器 172.16.8.6
在web服务器系统防火墙-高级设置-入站规则中开通8000端口,配置nginx正向代理,全配置如下:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	server {
    # 端口
        listen       8000;
    # 地址
        server_name  localhost;
    # DNS解析地址
        resolver 114.114.114.114;
		#resolver 8.8.8.8;
		
    # 代理参数
    location / {
        # $http_host就是我们要访问的主机名
        # $request_uri就是我们后面所加的参数
        #proxy_pass http://$http_host$request_uri;
		#proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		
		proxy_pass http://abc:8000/$request_uri;
		proxy_buffers 256 4K;
		proxy_max_temp_file_size 0;
		proxy_connect_timeout 30;
		proxy_cache_valid 200 302 10m;
		proxy_cache_valid 301 1h;
		proxy_cache_valid any 1m;
    }
}
 	server {
    # 端口
        listen       8001;
        server_name  localhost;
	# 跳转地址
		return  http://$http_host:8001$request_uri;
}

}

后台服务器配置 172.16.8.5

在程序绑定API调用地址:
http://172.16.8.6:8000/

本文标签: 域名内网接口程序Nginx