为什么必须配置hosts文件映射-hostname问题整理

[TOC]

1. 一些问题

先来思考一下以下几个问题:

  • hostname和域名的区别是什么?
  • 为什么kafka服务端server.properties中如果配置了hostname,则客户端的/etc/hosts就必须配置服务端的ip和hostname的映射?
  • 为什么storm集群环境必须配置集群所有机器的ip和hostname的映射?

2. 基本概念

要回答以上几个问题,我们先来弄清楚几个基本概念。

2.1 hostname

  • hostname也就是主机名,表示在一个特定网络范围内的一个计算机的名字
  • 每个主机都会有自己的hostname,在一个特定的网络范围内唯一
  • 每个主机都会有自己的ip地址,在一个特定的网络范围内唯一

比如xx系统的一个联机服务节点,运行在生产核心区的一台虚机上,该虚机的主机名是dcsapp17,也就是其hostname是dcsapp17。

2.2 域名

  • 域名是因特网范围内某一个服务器的名字,是用来解决IP地址不可读不好记的问题
  • 每个域名都对应一个具体的主机
  • 域名本身有自己的命名系统和层级规范,但其本质是为了按照一种通用的约定,标识因特网中的一台主机

例如baidu.com这个域名,就代表了百度的一台服务器,通过ping可以看到其代表主机信息

ping baidu.com
PING baidu.com (123.125.114.144): 56 data bytes
64 bytes from 123.125.114.144: icmp_seq=0 ttl=48 time=25.982 ms
64 bytes from 123.125.114.144: icmp_seq=1 ttl=48 time=25.990 ms

大型网站在多服务器负载均衡的情况下,一个域名可能会以对应多个ip地址,但是DNS一定会将其解析成某一个IP地址

2.3 域名解析

  • 当我们希望往某个域名发送请求的时候,需要将域名映射为实际的ip地址,这个过程称之为域名解析
  • 专门用来做域名解析的服务,称之为DNS服务,相应的有DNS服务器
  • 根据DNS服务器服务范围的不同,可以分为互联网DNS服务器和局域网DNS服务器
  • 局域网不一定需要DNS服务器,只要当前主机的/etc/hosts中配置了其他主机的ip地址和hostname的映射,则当前主机就可以通过主机名或者域名来访问对应的机器

域名解析的过程

请求某个域名下的一个url,域名解析的过程大致为:

  1. 检查缓存中有没有这个域名对应的解析过的ip地址,如果有则返回。缓存的时间、大小都可以配置
  2. 如果缓存没有,OS检查本地的hosts文件中有没有对应的映射关系,如果有,则以配置的hosts映射为准,返回
  3. 如果hosts里没有,则查找本地DNS服务器缓存,是否有对应的解析过的ip地址,如果有,返回(根据策略配置,可能还会缓存到本机)
  4. 如果没有,则会到配置的首选DNS服务器上去查询解析,查询到,则返回
  5. 如果首选DNS服务器上仍然没有,则根据规则,进行一层层DNS查询转发,直到找到

解析过程还有很多细节,根据不同的策略配置会有不同的路径,但是整体上类似

无论请求的url中是域名还是hostname,其本质都是使用别名替代了原有的ip地址,在请求路由的时候,要么是hosts映射文件,要么是各种级别的DNS服务器,总要将别名解析为具体的ip地址,才可以将请求发送到目的地。

3. 应用中的hostname

我们发布的每一个网络服务,其底层通讯通常都是基于TCP/IP协议:OS在本地监听某个端口,客户端主机可以通过服务所在的ip和端口请求建立链接并交换数据:

  • 在启动监听的时候,以java网络应用程序为例,无论是原生的ServerSocket还是netty中的的nio,都是指定端口即可
  • 当客户端请求连接的时候,需要提供服务端的ip地址和端口;即使某些API支持通过hostname建立链接,其内部一定还是通过hosts映射或者dns解析出目标ip并发起建链请求

越来越多的开源通讯组件如dubbo、storm、kafka等在设计时,一般都会考虑如下几个原则:

  • 基于服务注册发现机制,即服务提供者都是将自己的元信息注册到服务注册中心,然后客户端访问注册中心,从而获取服务提供者的主机信息,进而再请求与服务提供者建立链接
  • 在服务注册发现时,推荐使用hostname而不是ip地址,原因是hostname更具有可读性且在云环境下如果需要,可以保证在不更改hostname的情况下替换ip地址,从而客户端应用无需修改配置
  • 客户端从注册中心获取到hostname之后,需要通过dns或者本地hosts映射文件,将hostname解析成ip地址,进而请求建立链接和后续服务

接下来我们看看kafka、storm在设计的时候是怎么做的。

3.1 kafka中的hostname

kafka中的broker的监听配置如下

# The address the socket server listens on. It will get the value returned from 
# java.net.InetAddress.getCanonicalHostName() if not configured.
#   FORMAT:
#     listeners = listener_name://host_name:port
#   EXAMPLE:
#     listeners = PLAINTEXT://your.host.name:9092
listeners=PLAINTEXT://172.21.132.66:49092

# Hostname and port the broker will advertise to producers and consumers. If not set, 
# it uses the value for "listeners" if configured.  Otherwise, it will use the value
# returned from java.net.InetAddress.getCanonicalHostName().
#advertised.listeners=PLAINTEXT://your.host.name:9092
  • listeners:kafka的连接协议名、主机名和端口,如果没有配置,将使用java.net.InetAddress.getCanonicalHostName()的返回值作为主机名
  • advertised.listeners:生产者和消费者使用的主机名和端口,如果没有配置,将使用listeners的配置,如果listeners也没有配置,将使用java.net.InetAddress.getCanonicalHostName()的返回值

以上的配置,在kafka broker启动的时候,会将配置的信息注册到zookeeper并在集群中维护自己的元信息。当客户端与broker建立链接时,broker会将此处配置的信息返回给客户端,然后客户端会根据需要向某个broker节点发起建链请求。

因此,如果这里配置的hostname,则返回给客户端的broker信息便是hostname;如果配置的是ip地址,则返回给客户端的broker信息便是ip地址。如果客户端拿到的是hostname,则在建立链接的时候,便要将hostname解析成ip地址,假设此时hosts映射文件或者dns服务器中没有相关的解析配置,则客户端无法建立链接。

这里需要指出的是,无论是生产者还是消费者,我们配置的bootstrap.servers都是引导地址,而不是客户端真正建立长链接的地址。也就是说,客户端会根据引导地址去broker询问集群的所有broker信息,拿到返回的broker服务信息之后,再向指定的broker发起链接请求。因此bootstrap.servers无论配置的是ip还是hostname,都是只作为引导信息发起查询请求而已。

3.2 storm中的hostname

storm是比较流行的流式计算引擎,在storm集群中,每个负责执行计算任务的节点称为Supervisor节点,每个Supervisor启动的时候,将自己注册到zookeeper,当任务分发时,Supervisor从zk中获取到自己的上下游Supervisor节点并与之建立链接,形成流式计算任务序列,一个任务在一个计算节点处理完则被发送到下一个任务处理节点。

在storm中,Supervisor启动时,也是先读取配置文件,当配置文件不存在时,使用netAddress.getLocalHost().getCanonicalHostName()的返回值作为hostname并将其注册到zookeeper。

部分hostname解析逻辑如下:

protected String hostnameImpl () throws UnknownHostException  {
    if (localConf == null) {
        return memoizedLocalHostname();
    }
    Object hostnameString = localConf.get(Config.STORM_LOCAL_HOSTNAME);
    if (hostnameString == null || hostnameString.equals("")) {
        return memoizedLocalHostname();
    }
    return (String)hostnameString;
}
    
protected String localHostnameImpl () throws UnknownHostException {
    return InetAddress.getLocalHost().getCanonicalHostName();
}

因此在storm中,需要在集群的每个节点的hosts中配置彼此的hostname和ip的映射,以在需要的时候完成hostname解析。

4. 问题解答

综上,我们可以回答文章开头的问题:

  • hostname和域名的区别是什么?
    • hostname和域名都是为了解决ip地址不方便阅读和记忆的问题,前者在局域网内唯一,后者在因特网内唯一
    • 在发起链接请求时,需要根据hosts配置或者不同层级的dns服务器将hostname或者域名解析为具体的ip地址
  • 为什么kafka服务端server.properties中如果配置了hostname,则客户端的/etc/hosts就必须配置服务端的ip和hostname的映射?
    • kafka broker将配置的hostname作为服务器的元信息存储在zk和broker集群
    • 客户端通过引导地址访问broker之后,broker返回给客户端的是用户配置的服务信息,如果配置的是hostname,则客户端拿到的就是hostname;如果配置的是ip地址,则客户端拿到的就是ip地址
    • 客户端向服务端发起建链请求,需要将hostname解析成具体的ip地址。在没有局域网dns服务其的情况下,hosts映射文件就是一个本地的dns服务
  • 为什么storm集群环境必须配置集群所有机器的ip和hostname的映射?
    • storm的计算节点在启动时候会注册到zk,如果配置文件包含"storm.local.hostname",那么就使用配置的主机名;否则通过调用InetAddress.getLocalHost().getCanonicalHostName()获取主机名
    • storm的计算节点在请求和其他计算节点建立链接的时候,先通过zk获取到主机名,然后发起建立链接的请求。如果拿到的是hostname,则需要hosts映射或者dns服务将其解析成ip地址

需要说明的是,只要hostname能够被解析成ip地址即可,当前在生产环境有时候必须配置hsotname,是因为没有提供局域网dns服务器。随着后续dns服务器的配套完善,就不一定非要配置hosts映射文件了。

如有问题欢迎及时指正

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335