DNS(Domain Name System,域名系统)也许是我们在网络中最常用到的服务,它把容易记住的域名,如 www.google.com 翻译成人类不易记住的IP地址,如 173.194.127.132,以便在方便人类输入的基础上让计算机能够精确地在网络中找到目标机器。dig(Domain Information Groper)是一个比较常用的 dns 分析及调试工具,一般 Linux 和 Mac 都已默认安装。本文将基于 dig 的使用解释 dns 的基本知识。

解析

如果我们想知道 www.juvenxu.com 被解析到什么 IP 地址,可以用如下命令(我知道可以用ping,但本文主要围绕 dig 讲述):

$ dig www.juvenxu.com +noall +answer

; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com +noall +answer
;; global options: +cmd
www.juvenxu.com. 7803 IN A 98.130.162.53

1
2
3
4
5
$ dig www.juvenxu.com +noall +answer
 
; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com +noall +answer
;; global options: +cmd
www.juvenxu.com. 7803 IN A 98.130.162.53

命令行参数 +noall 和 +answer 只是为了输出更精简。

暂时忽略第3、4行,着重看最后一行,它分为5部分,第1部分是我们查询的域名;第2部分是缓存失效时间ttl(秒),暂且不关心;第3部分是 IN,表示类别 Internet,一般也都是这个类别;第4部分很重要,表示这行记录的种类(type),该行种类是 A(Address),说明这是一个A记录,描述域名对应的地址;第5部分好理解,就是地址了。

我们输入了 dig 命令和想查询的域名,得到了结果 IP 地址,本地的 dig 命令自然不可能知道世界上所有域名对应的 IP 地址(或者说A记录),那是谁告诉它的呢?

$ dig www.juvenxu.com +noall +answer +stats

; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com +noall +answer +stats
;; global options: +cmd
www.juvenxu.com. 6182 IN A 98.130.162.53
;; Query time: 4 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Aug 3 22:27:31 2014
;; MSG SIZE rcvd: 49

1
2
3
4
5
6
7
8
9
$ dig www.juvenxu.com +noall +answer +stats
 
; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com +noall +answer +stats
;; global options: +cmd
www.juvenxu.com. 6182 IN A 98.130.162.53
;; Query time: 4 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Aug  3 22:27:31 2014
;; MSG SIZE  rcvd: 49

加上 +stats 让 dig 打印基本的统计信息,其中第7行告诉我们 SERVER 是 192.168.1.1,53是DNS使用的 UDP(有时候可以是TCP)端口。dig 默认使用 /etc/resolv.conf 配置的域名服务器:

$ cat /etc/resolv.conf
#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
nameserver 192.168.1.1
1
2
3
4
5
6
7
8
9
10
11
$ cat /etc/resolv.conf
#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#
nameserver 192.168.1.1

我们可以指定 dig 使用其他域名服务器帮我们解析域名,例如用 8.8.8.8:

$ dig @8.8.8.8 www.juvenxu.com +noall +answer +stats

; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 www.juvenxu.com +noall +answer +stats
; (1 server found)
;; global options: +cmd
www.juvenxu.com. 19008 IN A 98.130.162.53
;; Query time: 77 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Aug 3 22:35:36 2014
;; MSG SIZE rcvd: 49

1
2
3
4
5
6
7
8
9
10
$ dig @8.8.8.8 www.juvenxu.com +noall +answer +stats
 
; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 www.juvenxu.com +noall +answer +stats
; (1 server found)
;; global options: +cmd
www.juvenxu.com. 19008 IN A 98.130.162.53
;; Query time: 77 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Aug  3 22:35:36 2014
;; MSG SIZE  rcvd: 49

这条命令中的 @8.8.8.8 表示使用 8.8.8.8 解析域名。

有些互联网服务部署在全球各个地方,这个时候服务提供方就希望中国的用户访问中国机房IP,美国的用户访问美国机房IP,这个时候两个地方的域名服务器返回的结果就会不一样,我们可以用类似上述的命令验证这一点。读者可以参考国内外DNS服务器地址列表,用各个国家的服务器 dig 一下知名站点如 google.com 试试。

不过即便如此,192.168.1.1 也好,8.8.8.8 也好,都不可能知道全球所有的域名信息,事实上,全世界数以亿次的域名信息分布在无数的域名服务器上,我们可以看一下维护 www.juvenxu.com 域名信息的服务器是什么:

$ dig www.juvenxu.com ns +noall +answer

; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com ns +noall +answer
;; global options: +cmd

1
2
3
4
$ dig www.juvenxu.com ns +noall +answer
 
; <<>> DiG 9.8.3-P1 <<>> www.juvenxu.com ns +noall +answer
;; global options: +cmd

我们在 dig www.juvenxu.com 后面加了 ns 参数,表示希望得到域名服务器信息(而不是默认的A记录),不过这次查询我们没有得到任何结果。没有关系,这往往表示该域名的上一级域名 (juvenxu.com)的域名服务器管理这个子域名,因此我们 dig juvenxu.com:

$ dig juvenxu.com ns +noall +answer

; <<>> DiG 9.8.3-P1 <<>> juvenxu.com ns +noall +answer
;; global options: +cmd
juvenxu.com. 84372 IN NS ns13.ixwebhosting.com.
juvenxu.com. 84372 IN NS ns14.ixwebhosting.com.

1
2
3
4
5
6
$ dig juvenxu.com ns +noall +answer
 
; <<>> DiG 9.8.3-P1 <<>> juvenxu.com ns +noall +answer
;; global options: +cmd
juvenxu.com. 84372 IN NS ns13.ixwebhosting.com.
juvenxu.com. 84372 IN NS ns14.ixwebhosting.com.

结果有两行记录,和 dig A记录结果一样,各自分成5部分,第1,2,3部分和A记录结果含义一致,第4部分表示表示种类(type)是 NS(Name Server,域名服务器),第5部分自然就是域名服务器的地址了。

现在我们知道 dig 请求域名服务器 192.168.1.1 juvenxu.com 的域名信息,而 ns13.ixwebhosting.com 和 ns14.ixwebhosting.com 保存了 juvenxu.com 的域名信息,那么 192.168.1.1 怎么知道如何联系上 ns13.ixwebhosting.com 或 ns14.ixwebhosting.com 呢?这就涉及到 DNS 的分布式架构了。

整个 DNS 服务是按照树形的结构分布的,最顶级是根域名,根域名服务器保存了所有定级域名服务器的信息,顶级域名包括 com, net, edu, org, cn 等等,各个定级域名服务器又包含了下一级的域名服务器信息,如 com 域名服务器包含了 microsoft.com, amazon.com 这些域的服务器信息,这样一层层往下:

我们可以使用 dig 的 +trace 选项来仔细查看这个过程:

$ dig juvenxu.com +trace

; <<>> DiG 9.8.3-P1 <<>> juvenxu.com +trace
;; global options: +cmd
. 209409 IN NS g.root-servers.net.
. 209409 IN NS b.root-servers.net.
. 209409 IN NS a.root-servers.net.
. 209409 IN NS h.root-servers.net.
. 209409 IN NS d.root-servers.net.
. 209409 IN NS j.root-servers.net.
. 209409 IN NS k.root-servers.net.
. 209409 IN NS f.root-servers.net.
. 209409 IN NS l.root-servers.net.
. 209409 IN NS c.root-servers.net.
. 209409 IN NS e.root-servers.net.
. 209409 IN NS i.root-servers.net.
. 209409 IN NS m.root-servers.net.
;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 13 ms

com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
;; Received 501 bytes from 192.58.128.30#53(192.58.128.30) in 45 ms

juvenxu.com. 172800 IN NS ns13.ixwebhosting.com.
juvenxu.com. 172800 IN NS ns14.ixwebhosting.com.
;; Received 112 bytes from 192.35.51.30#53(192.35.51.30) in 529 ms

juvenxu.com. 86400 IN A 98.130.162.53
;; Received 45 bytes from 98.130.253.162#53(98.130.253.162) in 222 ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ dig juvenxu.com +trace
 
; <<>> DiG 9.8.3-P1 <<>> juvenxu.com +trace
;; global options: +cmd
. 209409 IN NS g.root-servers.net.
. 209409 IN NS b.root-servers.net.
. 209409 IN NS a.root-servers.net.
. 209409 IN NS h.root-servers.net.
. 209409 IN NS d.root-servers.net.
. 209409 IN NS j.root-servers.net.
. 209409 IN NS k.root-servers.net.
. 209409 IN NS f.root-servers.net.
. 209409 IN NS l.root-servers.net.
. 209409 IN NS c.root-servers.net.
. 209409 IN NS e.root-servers.net.
. 209409 IN NS i.root-servers.net.
. 209409 IN NS m.root-servers.net.
;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 13 ms
 
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
;; Received 501 bytes from 192.58.128.30#53(192.58.128.30) in 45 ms
 
juvenxu.com. 172800 IN NS ns13.ixwebhosting.com.
juvenxu.com. 172800 IN NS ns14.ixwebhosting.com.
;; Received 112 bytes from 192.35.51.30#53(192.35.51.30) in 529 ms
 
juvenxu.com. 86400 IN A 98.130.162.53
;; Received 45 bytes from 98.130.253.162#53(98.130.253.162) in 222 ms

dig 直接请求的 192.168.1.1 并不知道 juvenxu.com 的 A记录是什么,它就去让 dig 去问根域名服务器,根域名服务器也不知道,让 dig 去问 com 的域名服务器,com 域名服务器也不知道,就让 dig 去问 ns13.ixwebhosting.com 和 ns14.ixwebhosting.com,而我们知道,这两个域名服务器保存了 juvenxu.com 的 A记录。这种一问一答的解析方式,叫做迭代解析(Iterative resolution)。这种方式下,每个域名服务器只是给出它所知道的最佳答案。

另外一种解析方式是递归解析(recursive resolution),如果我们不给 dig 加上 +trace 参数,dig 就会给域名服务器 192.168.1.1 一个递归解析请求,等于告诉是让 192.168.1.1 直接负责去解析到最终答案,然后直接返回给 dig。通常情况下客户端(dig)对域名服务器发起的递归解析请求,而域名服务器对其他域名服务器的请求(如 192.168.1.1 对根域名服务器)是迭代解析请求。

缓存

如果世界上所有网络设备(PC,服务器,手机,平板电脑……)的每次网络请求都要访问 DNS 根服务器,那这个量就实在是太大了,根服务器肯定受不了。考虑到一个域名和其IP的对应关系其实不会太常变化,因此在各个域名服务器缓存之前请求过的域名 A记录就是个不错的策略。基于此,对于一个域名如 douban.com 来说,域名服务器分成两类,一类是切切实实保存该域名信息的服务器,称为权威域名服务器(Authoritative Name Server),其余的仅仅是缓存其域名信息的服务器,就是缓存域名服务器。

例如,如果我很久以来第一次 dig douban.com,就会得到类似这样的输出:

$ dig douban.com

; <<>> DiG 9.8.3-P1 <<>> douban.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49795
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 10

;; QUESTION SECTION:
;douban.com. IN A

;; ANSWER SECTION:
douban.com. 35 IN A 211.147.4.31

;; AUTHORITY SECTION:
douban.com. 518 IN NS ns3.dnsv4.com.
douban.com. 518 IN NS ns4.dnsv4.com.

;; ADDITIONAL SECTION:
ns3.dnsv4.com. 134679 IN A 221.204.186.6
ns3.dnsv4.com. 134679 IN A 115.236.151.140
ns4.dnsv4.com. 134679 IN A 183.60.57.149
ns4.dnsv4.com. 134679 IN A 183.60.58.173

;; Query time: 19 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Mon Aug 4 10:33:08 2014
;; MSG SIZE rcvd: 246

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ dig douban.com
 
; <<>> DiG 9.8.3-P1 <<>> douban.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49795
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 10
 
;; QUESTION SECTION:
;douban.com. IN A
 
;; ANSWER SECTION:
douban.com. 35 IN A 211.147.4.31
 
;; AUTHORITY SECTION:
douban.com. 518 IN NS ns3.dnsv4.com.
douban.com. 518 IN NS ns4.dnsv4.com.
 
;; ADDITIONAL SECTION:
ns3.dnsv4.com. 134679 IN A 221.204.186.6
ns3.dnsv4.com. 134679 IN A 115.236.151.140
ns4.dnsv4.com. 134679 IN A 183.60.57.149
ns4.dnsv4.com. 134679 IN A 183.60.58.173
 
;; Query time: 19 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Mon Aug  4 10:33:08 2014
;; MSG SIZE  rcvd: 246

这段输出比较长,我们重点看15-17行,即 AUTHORITY SECTION 部分,由于我们长久以来第一次 dig douban.com,因此就近的域名服务器还没有 192.168.1.1 还没有缓存 douban.com 的 A记录,因此它会解析到 douban.com 的权威域名服务器,再返回给我们结果,这个结果是最新的,是“权威”的。

我们回头在看13行A记录的第二部分 ttl,即缓存失效时间,值是35,表示该缓存35秒后失效,换言之,35秒内我们再请求 douban.com 的话,192.168.1.1 会直接返回缓存的A记录:

$ dig douban.com

; <<>> DiG 9.8.3-P1 <<>> douban.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4656
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;douban.com. IN A

;; ANSWER SECTION:
douban.com. 31 IN A 211.147.4.31

;; Query time: 1 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Mon Aug 4 10:41:36 2014
;; MSG SIZE rcvd: 44

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ dig douban.com
 
; <<>> DiG 9.8.3-P1 <<>> douban.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4656
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
 
;; QUESTION SECTION:
;douban.com. IN A
 
;; ANSWER SECTION:
douban.com. 31 IN A 211.147.4.31
 
;; Query time: 1 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Mon Aug  4 10:41:36 2014
;; MSG SIZE  rcvd: 44

这时就没有 AUTHORITY SECTION 了,说明结果来自缓存域名服务器,而不是权威域名服务器。

如果权威域名服务器改变了A记录信息,而缓存服务器还没有过期,我们怎么去主动了解最新的A记录呢?或者说,怎么主动去权威服务器查找A记录信息呢?简单,解析的时候指定域名服务器即可:

$ dig @ns3.dnsv4.com douban.com

; <<>> DiG 9.8.3-P1 <<>> @ns3.dnsv4.com douban.com
; (5 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63971
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;douban.com. IN A

;; ANSWER SECTION:
douban.com. 10 IN A 211.147.4.31

;; AUTHORITY SECTION:
douban.com. 600 IN NS ns4.dnsv4.com.
douban.com. 600 IN NS ns3.dnsv4.com.

;; Query time: 10 msec
;; SERVER: 180.153.10.166#53(180.153.10.166)
;; WHEN: Mon Aug 4 10:43:29 2014
;; MSG SIZE rcvd: 98

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ dig @ns3.dnsv4.com douban.com
 
; <<>> DiG 9.8.3-P1 <<>> @ns3.dnsv4.com douban.com
; (5 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63971
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available
 
;; QUESTION SECTION:
;douban.com. IN A
 
;; ANSWER SECTION:
douban.com. 10 IN A 211.147.4.31
 
;; AUTHORITY SECTION:
douban.com. 600 IN NS ns4.dnsv4.com.
douban.com. 600 IN NS ns3.dnsv4.com.
 
;; Query time: 10 msec
;; SERVER: 180.153.10.166#53(180.153.10.166)
;; WHEN: Mon Aug  4 10:43:29 2014
;; MSG SIZE  rcvd: 98

缓存机制能够减轻域名服务器尤其是根域名服务器和定级域名服务器的压力,让域名解析过程更快,当然和所有缓存一样,副作用也是有的,当权威服务器修改域名信息的时候,缓存服务器的信息就过时了,要等TTL失效后才能解析到最新正确的信息。

dig与dns基本理论——解析和缓存的更多相关文章

  1. dig理解DNS的解析过程 - 阿权的书房

    关于DNS的常识,可以阅读附录的一些参考资料.本文旨在尝试举例用dig命令理解这个过程,并非权威知识,仅供参考.测试域名为阿权的书房的域名 www.aslibra.com 和 www.163.com. ...

  2. DNS BIND配置 配置基本缓存服务器 DNS正向解析 DNS反向解析

    一. 缓存服务器配置 1.DNS:BIND    Berkeley Internet Name Domain    版本bind97: RPM服务器端包的名字  安装bind-libs    bind ...

  3. 使用dig查询dns解析

    原文地址:使用dig查询dns解析 作者:chenwenming 一般来说linux下查询域名解析有两种选择,nslookup或者dig,而在使用上我觉得dig更加方便顺手. 如果是在debian下的 ...

  4. DNS原理及其解析过程【精彩剖析】(转)

      2012-03-21 17:23:10 标签:dig wireshark bind nslookup dns 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否 ...

  5. DNS服务器全面解析--转

    引用地址:http://pangge.blog.51cto.com/6013757/1273087 基础认知篇 DNS服务的概述 DNS是Domain Name System 的缩写,即域名系统.DN ...

  6. linux服务基础之DNS正反向解析、主从同步、子域授权及视图

    关键词: 正向解析 反向解析 主从复制 自域授权 视图 一.DNS基本原理 1.1 什么是DNS?BIND又是什么? DNS:Domain Name Service,它是一个基于应用层的协议,是C/S ...

  7. WEB请求过程(http解析,浏览器缓存机制,域名解析,cdn分发)

    概述 发起一个http请求的过程就是建立一个socket通信的过程. 我们可以模仿浏览器发起http请求,譬如用httpclient工具包,curl命令等方式. curl "http://w ...

  8. DNS原理及其解析过程【精彩剖析】

    DNS原理及其解析过程[精彩剖析] 2012-03-21 17:23:10 标签:dig wireshark bind nslookup dns 原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

  9. 从理论到实践,全方位认识DNS(理论篇)

    对于 DNS(Domain Name System) 大家肯定不陌生,不就是用来将一个网站的域名转换为对应的IP吗.当我们发现可以上QQ但不能浏览网页时,我们会想到可能是域名服务器挂掉了:当我们用别人 ...

随机推荐

  1. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  2. LoRaWAN协议(四)--入网方式概述

    前言 在LoRaWAN中,node最终和服务器能够正常数据交互,需要先入网,入网的本质,也就是获得一些通信相关的参数,有以下几个: NwkSKey AppSKey DevAddr DevEui 其中 ...

  3. hibernate集成

    hibernate是一个优秀的持久化框架负责简化将对象保存到数据库中,或从数据库中读取数据并封装到对象的工作.hibernate通过简单配置和编码即可替代jdbc繁琐的程序代码. 下面是集成hiber ...

  4. Scrum 项目5.0--软件工程

    1.燃尽图: 2.每日立会更新任务板上任务完成情况.燃尽图的实际线,分析项目进度是否在正轨.    每天的例会结束后的都为任务板拍照并发布到博客上     团队贡献分: 蔡舜 : 21 卢晓洵 : 1 ...

  5. 2015年百度之星初赛(1) --- B 找连续数

    找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. P6 EPPM Manual Installation Guide (Oracle Database)

    P6 EPPM Manual Installation Guide (Oracle Database) P6 EPPM Manual Installation Guide (Oracle Databa ...

  7. visual studio 2013 配置开发环境

    https://www.visualstudio.com/explore/xamarin-vs http://sourceforge.net/projects/easyeclipse/files/?s ...

  8. Android开发总是难以入门

    发现自己很难入门,是真的太难,还是自己主观拒绝.

  9. JMS学习(二)- JMS Message Model 组成介绍及消息头详解

    一.前言 从本文起依次详细介绍JMS中的一些重要的概念,主要参考了官方的JMS1.1的文档,该文档很老了,是02年的,那年,JAVA还没有被Oracle收购..本文主要介绍Message及其相关概念, ...

  10. ztree树 叶子节点路径的集合

    1.Question Description: ztree树各个节点都带有路径,如“/根节点”,"/根节点/一级节点",“根节点/一级节点/二级节点‘; 现在想获取所选的最末级节点 ...