我维护着一个有一堆可下载文件的网站。它目前托管在美国的一台服务器上,但我最近在德国购买了一台新服务器。我想镜像下载到德国的服务器上,并有一个在第一个服务器上的PHP脚本(托管网站)检测哪个文件镜像使用基于用户的位置。例如,如果用户在加拿大,他们应该从我目前在美国的服务器上下载文件。如果他们在法国,他们应该从德国获得文件,而不是从大西洋彼岸下载。那么,我如何才能确定他们离哪个国家更近呢?
我知道MaxMind GeoIP,并安装了它,但这只给了我一个国家,而AFAIK,没有办法自动确定我的两个镜像国家中的哪个离给定的国家最近。我想我可以做的是按大洲来做:让亚洲、欧洲、非洲和澳大利亚的用户从德国获得内容,让北美和南美的访问者从美国获得文件。如果有人能想出更好的解决方案,我愿意接受建议。
好吧,我想我还是按照我最初的想法,按大洲来检查吧。对于其他希望做这类事情的人来说,这将是一个很好的起点。当我在欧洲拥有多面镜子时,问题就会出现,但欧洲大陆的想法目前必须奏效。
6条答案
按热度按时间oknwwptz1#
到目前为止,在提议的解决方案中似乎有很多开发人员的开销。如果这是我必须在自己的应用程序中解决的问题,我可能会选择在这个应用程序上重新发明轮子,从而节省几个小时的工作。
确定最近镜像(使用邮政编码)
1.以数组形式维护可用的镜像服务器的邮政编码列表。
1.确定用户代理的邮政编码(例如,用户输入或PHP库)
1.计算两个邮政编码之间的距离(如PHP库)
1.根据返回的距离继续选择镜像
请记住,距离越近并不一定意味着响应时间越快。然而,在您的场景中,假设两个镜子都打开了,一个国家的镜子显然会比另一个国家的镜子快。继续阅读我认为更“可靠”的解决方案。
资源与链接
“特立独行”的方法
在我看来,小牛也是我们今天都在使用的这些伟大的库和框架的创新者、问题解决者和发明者。有时会被错误地与“黑客”想法联系在一起,但我们接受补充:)
1.在接受$_GET或$_POST请求的任一镜像服务器上创建您自己的API服务。
1.此API服务将获取给定的IP地址并对其执行ping()操作,计算响应时间,然后取平均值,将其返回给请求接口(例如,客户端通过其连接的前端门户和/或服务器尝试确定最近的镜像)。平均响应最低的服务器应该是响应最快的服务器,尽管不一定是最接近的服务器。对你来说,哪个更重要?有关不依赖于本地执行外壳命令(例如,独立于平台)的有效ping()函数,请参阅Ping site and return result in PHP。
1.最后一步,获取请求客户端的IP地址,并将其传递给后台任一镜像服务器上运行的API服务。我们都知道如何获得知识产权,但没有你想象的那么好。如果您是负载均衡的或在代理之后,您可能希望首先检查是否有任何头通过(HTTP_FORWARD、HTTP_FORWARD_FOR、HTTP_X_FORWARD、HTTP_X_FORWARD_FOR、HTTP_CLIENT_IP)。如果是这样的话,这很可能是用户代理的“真实”IP地址。
此时(步骤3),您将比较每个镜像在对用户代理执行ping操作时的平均响应时间。然后继续选择用户代理应该从哪个镜像下载。然后,您将创建的服务流类似于以下内容:
1.用户代理访问门户
1.门户使用后台ajax/jQuery请求(或传统的POST和重定向)将用户代理的IP地址转发给在两个镜像上单独运行的API服务。
1.运行在镜像上的API服务ping它收到的IP地址,并返回配置为获取的响应总数的平均值。
1.门户读取返回的平均值并进行比较。
希望对大家有帮助,编码愉快!
zphenhs42#
如果您只有两个镜像,那么在浏览器中启动从每个服务器下载50K文件的AJAX请求。这个值足够小,不足以代表用户的巨大延迟,但足以使计时器测量差异显著--当然,您应该稍微玩弄一下这个数字。
然后,一旦你有了“最佳时间”,设置一个JS cookie,并在需要下载时重定向到首选镜像。测量可以从后台的下载页面开始,因此用户可能不会注意到延迟(当他们选择他们想要的文件时)。
你甚至可以在每个AJAX操作中回复‘服务器负载’,不仅根据响应时间,而且根据当前负载选择最好的服务器。因此,英国用户将使用美国服务器,即使最近的服务器在德国,如果后者的负载明显高于第一个服务器。
vzgqcmou3#
我不记得有哪一家图书馆能做到这一点。但是,如果我有一个想法,那可能会对你有所帮助,而不是建立一个系统。
使用此distance calculator计算两个IP之间的距离。或者找出两个IP地址(一个服务器)和(一个访客)的经纬度,并计算距离。下面是一个伪代码来实现这一点
kt06eoxx4#
执行Traceroute(将Traceroute客户端配置为不解析主机名并且超时较小)。
根据跳数和Traceroute客户端的位置(我假设它与PHP脚本相同),在美国和德国之间进行选择。
地理距离与网络距离、网络速度或带宽成本无关。
我建议您使用$_SERVER[“REMOTE_ADDR”]并在geo ip database中查找它来获得国家代码,而不是Traceroute(因为它是一个黑客的小代码解决方案)。如果国家代码不是美洲大陆上的国家之一,为了避免跨越拥挤的互联网 Backbone.js ,可以退回到德国(此外,您可以将国家代码设置为来自欧洲)。
一旦您建立了地理IP数据库,我建议您将范围内的IP地址从点格式转换为整数格式,以加快速度和方便查询。
从我使用上述地理IP数据库的经验来看,它很少错过,这无关紧要。
wkftcu5l5#
像你所说的那样,使用一些类似Geoip的库,并使用经纬度来比较镜子和用户之间的距离,不是更容易吗?
我认为它不那么复杂,而且很容易实现,适用于N面镜子,您不需要询问Zip或其他类型的数据来进行参考
jv4diomz6#
我来派对已经很晚了,但这不是最简单的解决办法,我只是想看看哪一种更快。