多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

有目标就不怕路远。年轻人.无论你现在身在何方.重要的是你将要向何处去。只有明确的目标才能助你成功。没有目标的航船.任何方向的风对他来说都是逆风。因此,再遥远的旅程,只要有目标.就不怕路远。没有目标,哪来的劲头?一车尔尼雷夫斯基

导读:本篇文章讲解 多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

(1)问题描述

(2)问题复现


这篇文章记录一下,多次负载均衡之后,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】。

多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

  • 编写调用端代码,注意这里的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即可。

多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

问题来了,我们转发调用的接口地址是第二个nginx的地址,但是底层实际是调用的第一个nginx的代理地址,由于我们系统没有访问第一个nginx的IP权限,所以接口调用超时了,这就是两次负载均衡导致的webservice接口地址不一致的问题。

模拟调用情况:

多次负载均衡之后,WebService接口调用地址,和实际调用的接口地址不一致问题记录

这里为了模拟这种情况,我是在程序循环20秒的期间,将8888端口的nginx服务停止了,所以才能够模拟超时调用的情况。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134618.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!