目录
这篇文章记录一下,多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录。
(1)问题描述
今天工作中,遇到了一个问题,具体情况是这样的:
- 我们系统对外提供了一个WebService的接口,这个接口的主要作用就是用于转发调用其他的webservice接口,首先系统里面会配置好需要转发的接口地址,其它系统来调用的时候,根据接口编码查询到真正转发调用的地址。
看着是不是很简单,但是调用过程中,居然报错了,报的是连接超时,查看日志,发现webservice接口配置的地址,和真正转发调用出去的地址居然不一致,可以确定的是,我们的地址没有配置错,就很奇怪,怎么多出一个没见过的地址????
打个比方:我们系统里面配置的地址是【http://127.0.0.1:7777/wsDemo/demoInvokeService?wsdl】,错误日志里面,提示连接超时的接口地址居然是【http://127.0.0.1:8888/wsDemo/demoInvokeService?wsdl】(当然这里我只是以不同端口为案例),两个地址居然不一样,搞了一晚上,找到问题了。
(2)问题复现
出现上面问题的原因是:nginx负载均衡的时候,webservice接口地址会变成nginx代理的IP和端口,我们是内网环境,访问IP和端口都是需要开通权限,由于我们只开通了【127.0.0.1:7777】(这里举个例子,并不是真实IP)这个的权限,然而经过代理之后,webservice真正调用的地址是【127.0.0.1:8888/】(这里举个例子,并不是真实IP),我们没有访问这个地址的权限,所以就连接超时了。
下面举个案例,复现一下实际情况。
- 本地编写一个webservice接口的案例。
案例可以从我这篇文章里面,复制代码。
【【WebService笔记02】使用CXF框架实现WebService接口的发布和调用_朱友斌的博客-CSDN博客_cxf调用webservice使用xml】
注意:我这里对外发布的接口地址是:【http://127.0.0.1:9090/wsDemo/demoInvokeService】。
- 编写调用端代码,注意这里的wsdl调用地址改成代理地址。
package org.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class ClientInvokeWebService {
public static void main(String[] args) throws Exception {
// 1、创建 CXF 客户端工厂 Bean 对象
JaxWsDynamicClientFactory jaxWsDynamicClientFactory = JaxWsDynamicClientFactory.newInstance();
// 2、创建客户端对象
// 调用的接口地址,注意: 接口地址后缀需要添加【?wsdl】
String wsdl = "http://127.0.0.1:7777/wsDemo/demoInvokeService?wsdl";
Client client = jaxWsDynamicClientFactory.createClient(wsdl);
for (int i = 0; i < 20; i++) {
Thread.sleep(1000);
System.out.println("等待.....i=" + i);
}
// 3、调用接口方法
Object[] ret = client.invoke("demoInvoke", "<xml>data</xml>这是接口的请求入参");
// 4、接收接口的返回参数
if (ret == null || ret.length == 0) {
System.out.println("接口返回参数为空");
} else {
System.out.println("输出接口出参: " + ret[0].toString());
}
}
}
- 启动一个nginx服务,端口号是8888,用于代理访问真实的webservice接口地址。
nginx的配置文件如下所示:
#user nobody;
worker_processes 1;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream wsDemo {
server 127.0.0.1:9090;
}
server {
listen 8888;
# 路由配置信息
location /wsDemo/ {
root html;
index index.html index.htm;
proxy_set_header Host $host:$server_port;
proxy_pass http://wsDemo;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- 再次启动一个nginx服务,端口号是777,用于代理访问前一个nginx的代理地址。
配置文件和上面一致,但是监听的端口改成7777即可。
- 然后启动两个nginx代理服务,分别访问真实的webservice接口地址,第一个nginx代理地址,第二个nginx代理地址。
- 【http://127.0.0.1:9090/wsDemo/demoInvokeService?wsdl】真实的webservice接口地址。
- 【http://127.0.0.1:8888/wsDemo/demoInvokeService?wsdl】第一个nginx代理地址。
- 【http://127.0.0.1:7777/wsDemo/demoInvokeService?wsdl】第二个nginx代理地址。
问题来了,我们转发调用的接口地址是第二个nginx的地址,但是底层实际是调用的第一个nginx的代理地址,由于我们系统没有访问第一个nginx的IP权限,所以接口调用超时了,这就是两次负载均衡导致的webservice接口地址不一致的问题。
模拟调用情况:
这里为了模拟这种情况,我是在程序循环20秒的期间,将8888端口的nginx服务停止了,所以才能够模拟超时调用的情况。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134618.html