SpringCloud开发人员怎么解决服务冲突和实例乱窜

小编给大家分享一下Spring Cloud开发人员怎么解决服务冲突和实例乱窜,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

为立山等地区用户提供了全套网页设计制作服务,及立山网站建设行业解决方案。主营业务为成都网站设计、做网站、成都外贸网站建设公司、立山网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

一、背景

在这一篇文章《Spring Cloud开发人员解决服务冲突和实例乱窜的示例分析》中提到使用服务的元数据来实现隔离和路由,有朋友问到能不能直接通过IP来实现?本文就和大家一起来讨论一下这个问题

二、可行性分析

要实现通过IP来隔离和路由的话有一个非常关键的点需要解决,就是怎样实现IP可辨识,意思就是如何区分那个IP服务器上的,那个IP开发人员本机

Spring Cloud开发人员怎么解决服务冲突和实例乱窜

如上图所示其实我们还是能找到规律可以辨识的,所以这个是可以行的!

  • 开发人员本机IP- 其实就是客户端IP,也就是原始请求方的IP172.16.20.2

  • 服务器IP- 可以理解为服务器上的服务所在机器的IP(有点绕):172.16.20.1

三、路由规则逻辑

主要实现以下目标:

  1. 普通用户访问服务器上的页面时,请求的所有路由只调用服务器上的实例

  2. 开发A访问时,请求的所有路由优先调用开发A本机启动的实例,如果没有则调用服务器上的实例

  3. 开发B访问时同上,请求的所有路由优先调用开发B本机启动的实例,如果没有则调用服务器上的实例

在找到IP的辨识规律后,推导出下面3个路由规则来实现上面的目标

  1. 优先匹配原始请求方的IP的服务实例

  2. 再者匹配上游服务所在机器IP的服务实例

  3. 上面2个逻辑都匹配不到的话使用轮询的方式找一个实例

  具体的自定义负载均衡的对象怎么写我这里就不详细描述了,可以参考我上一篇文章《Spring Cloud开发人员解决服务冲突和实例乱窜的示例分析》

四、获取原始请求方的IP

获取原IP的代码片段如下,只需要在网关上增加一个过滤器获取IP,然后添加到header里面一直传递下去就可以了

/**
 * 获取Ip地址
 */
private String getIpAddr(HttpServletRequest request){
    String ip = request.getHeader("X-Forwarded-For");
    if (isEmptyIP(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
        if (isEmptyIP(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            if (isEmptyIP(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
                if (isEmptyIP(ip)) {
                    ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                    if (isEmptyIP(ip)) {
                        ip = request.getRemoteAddr();
                        if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                            // 根据网卡取本机配置的IP
                            try {
                                ip = InetAddress.getLocalHost().getHostAddress();
                            } catch (UnknownHostException e) {
                                log.error("InetAddress.getLocalHost()-error", e);
                            }
                        }
                    }
                }
            }
        }
    } else if (ip.length() > 15) {
        String[] ips = ip.split(",");
        for (int index = 0; index < ips.length; index++) {
            String strIp = ips[index];
            if (!isEmptyIP(ip)) {
                ip = strIp;
                break;
            }
        }
    }
    return ip;
}

private boolean isEmptyIP(String ip) {
    if (StrUtil.isEmpty(ip) || UNKNOWN_STR.equalsIgnoreCase(ip)) {
        return true;
    }
    return false;
}

把原IP添加到headerHTTP_X_FORWARDED_FOR里面传递给下游服务

RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String sourceIp = getIpAddr(request);
ctx.getZuulRequestHeaders().put("HTTP_X_FORWARDED_FOR", sourceIp);

五、获取服务器所在机器的IP

直接使用JDK自带的InetAddress就可以了

String localIp = InetAddress.getLocalHost().getHostAddress()

以上是“Spring Cloud开发人员怎么解决服务冲突和实例乱窜”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


当前标题:SpringCloud开发人员怎么解决服务冲突和实例乱窜
文章来源:http://hbruida.cn/article/jdjhcg.html