通过几个详细的例子介绍在面试-开发中经常用到的mvc是什么

这个MVC这种设计模式现在用的特别多,基本上到处都在用,尤其是Java项目,基本都在用,因此理解清楚,学习清楚是非常重要的。

在求职面试过程中,了解并掌握MVC设计模式是非常重要的基础技能之一,就如同数学中的加减法一样,是每个Java开发者必须熟练掌握的基本功。如果不熟悉这个概念,在实际工作中可能会遇到沟通障碍和技术难题,影响项目的进展和工作效率。因此,深入理解和灵活运用MVC设计模式对于任何Java开发者来说都是至关重要的。

但是,要真正透彻理解MVC设计模式,并非仅停留在会用、会写代码的层面。只有当你完全理解其内在原理和运作机制后,在回答问题或进行实际开发时,才能清晰地表述并有效地应用它。你可能能够编写出遵循MVC模式的代码,但如果不能深入理解其背后的逻辑,就难以向他人准确无误地解释清楚,更别提在复杂项目中灵活运用了。

那么,当我们探讨MVC是否有用时,答案是肯定的。MVC不仅是一种广泛应用于软件开发的设计模式,更是我们分析程序结构、设计程序架构的一种重要理念。当你充分掌握MVC之后,在编写程序的过程中就能按照这种理念,有步骤、有条理地组织和调整代码结构。这样做的好处在于,你的程序将会变得更加清晰有序,具有良好的层次感和可维护性,避免因代码混乱而带来的各种问题。总之,对MVC设计模式的理解和熟练运用对于提高编程效率和保证软件质量具有不可忽视的价值。

为了说明mvc录制了一个视频,希望能对您有帮助, 能力有限,哪里缺漏或者不合适的地方请您谅解

程序在具有层次感后,各个部分的功能职责更加明确和独立。每个模块专注于自己的功能实现,这样不仅使得编写、测试阶段变得更加简单和高效,同时也便于其他开发人员阅读和理解代码逻辑。当每个部分的边界清晰且相对独立时,无论是对代码进行单元测试还是集成测试,都能够更有针对性地进行,从而提高测试覆盖率和质量。

反之,若将所有功能混杂在一个庞大复杂的模块中,会导致代码难以梳理和维护。一旦需要修改或调整某个功能,可能会因为高度耦合的关系而影响到整个系统,即所谓的“牵一发而动全身”。采用MVC(或者可能是你想要表达的MVVM等设计模式)来组织代码结构,则能够有效地避免这一问题。通过分离视图、模型和控制器(或数据绑定、视图模型等),各部分能更好地各司其职,降低相互之间的依赖性,使得在面对需求变更时,只需针对相关部分进行改动,大大提高了程序的可维护性和扩展性。

MVC(Model-View-Controller)作为一种经典的设计模式,理解起来确实需要一定的耐心和实践。为了更好地帮助大家掌握这一概念,我们特别录制了一段详细解读MVC的视频教程,并已上传至B站平台。在这段长达30多分钟的视频中,我通过大量生动易懂的比喻和实例解析,深入浅出地阐述了MVC的核心思想。

具体来说,MVC将应用程序分为三个核心部分:

Model(模型):负责处理业务逻辑和数据存储,是应用的数据层。它与数据库或其他数据源交互,提供对数据的操作和管理功能。

View(视图):负责展示用户界面和数据表现,它是模型数据的可视化结果。视图只关注如何呈现数据,并能根据模型状态的变化自动更新显示内容。

Controller(控制器):充当模型和视图之间的协调者,响应用户的输入事件,并调用模型进行相应的操作,同时确保视图反映出这些操作的结果。控制器接收并处理请求,维护程序的状态流转。

通过观看视频教程,您将会从理论到实践全方位理解MVC模式的工作原理,从而能够在实际编程中有效地利用这一设计模式,使代码结构更加清晰、可维护性更强,并且在面对复杂的项目需求时,能够更从容地应对挑战。无论是面试还是日常开发工作,扎实掌握MVC都将大有裨益。

快速排除一个不熟悉的复杂代码中的问题方法

在工作和学习的过程中,我们难以避免会遇到一些项目出现故障,比如代码编译不通过或者运行时出现问题。尤其是在面对非自己编写的代码,或者对某些代码不够熟悉的情况下,如何能够快速地让代码顺利运行并定位问题显得尤为重要。如果遇到的代码完全是由自己编写且逻辑清晰易懂,同时又有充足的时间,那么可以采取逐行审查的方式,细致地跟踪代码执行流程,逐步排查错误,这是解决此类问题的一个有效方法。
但当您收到代码时,一般都是别人代码,通常能解决的问题,别人自己就解决了, 求助别人的一定是不好解决的代码。这个时候我们可以借助网络资源,寻找与当前问题代码功能相似且已知能正常运行的示例代码。这套代码应尽可能精简,以便于分析和理解其内部工作机制。平时积累丰富的代码库是十分必要的,尤其是那些简洁、实用的小型源代码或内容较少但结构完整的框架代码,它们在关键时刻往往能发挥重要作用。
处理方法的详细过程已经录制为视频, https://www.bilibili.com/video/BV1iF4m1T7aP/

当你拥有一个丰富多样的代码库时,在需要的时候就可以迅速从中挑选出适合的基础项目框架或空项目骨架。然后,我们可以将待解决问题的原有代码逐步分解,并将其功能模块移植到这个基础框架中,通过对比和调试,找出问题所在并进行修复,最终实现项目的正常运行。
我们看一下下图是程序中问题的现状
file
对于上面截图中问题, 若是直接去解决, 就要详细分析源代码, 若是自己写的代码还好, 别人写的要了解一些时间了。 因此我们有上面的办法。
在移植代码的过程中,我们首先要确保选取那些不会带来风险、不影响程序正常运行的部分进行迁移。一旦这部分代码被移植到模拟真实环境的项目中后,应立即进行编译并在此环境下运行,以验证其功能的正确性。

这里强调的是采用模拟真实部署环境的方式来运行项目,因为有时候在特定的开发环境中或者开发人员本地配置下能够顺利运行的代码,在正式部署时可能会由于环境变量、依赖版本等因素的不同而无法正常工作。因此,我们的目标是在尽可能接近正式部署环境的前提下让项目成功运行。

当一个空项目按照正式部署的方式成功运行起来,并且各项功能均显示正常时,我们就迈出了第一步。接下来,我们需要将那些相对稳定、问题较小的静态资源或其他组件逐步引入进来,进行编译和测试。如果在引入这些组件后项目仍能无误运行,那么我们就完成了第二阶段的工作。

在第二步中,我们将开始引入相关的依赖包。首先仅导入依赖包而不包含源代码,理论上原有的功能应该不会受到影响。然而,由于许多项目存在复杂的依赖关系,不同版本间的依赖可能相互覆盖或缺失,导致在添加新的依赖包后可能出现类缺失、编译失败等问题。因此,我们必须逐个将依赖包加入到空项目中,经过编译和运行测试,查看是否存在问题,从而确保项目的稳定性和兼容性。

在我们面对此类项目时,确实会遇到这样的情况:当账号信息或部分代码模块被迁移过来后,虽然能顺利编译和运行,但随着版本的升级或其他改动,新的问题就会接踵而至。这就需要我们不断地调整、调试,确保项目的稳定运行。

在项目进行到一定阶段,我们会对项目中多余的或者过时的依赖包进行清理,这是因为过多的或冲突的依赖包可能会在未来引发各种编译、运行时的问题。通过剔除冗余依赖,可以有效防止潜在的风险和冲突。

将依赖包调整妥当并确认无误后,接下来可能涉及配置文件和日志文件的迁移。由于配置文件即使未被正确读取也不会影响程序的基础运行,我们可以逐步引入并对比原有空项目与新引入资源之间的差异,针对性地进行调整优化,每一步都确保运行无误,这种步步为营的方式实则是最节省时间的方法。

在某些情况下,直接修改源代码可能耗时较长,并且要求对目标代码有深入的理解。然而,在实际工作中,有时我们可能无法及时找到相关人员或他们正忙于其他事务。这时,按照上述步骤,逐块儿地迁移和测试代码就显得尤为高效且可靠。

在完成资源配置和初步代码迁移后,我们将开始着手迁移核心的项目源代码。优先处理那些看似没有问题的部分,经过快速浏览判断哪些代码相对安全,然后逐步将其迁移到新环境中,每次迁移后都要立即编译并观察效果。如果出现编译错误,则要分析原因,可能是遗漏了某些类或资源,此时应迅速补充并重新编译,直到成功编译并通过运行验证。

运行过程中,可能会发现新的问题或是重复代码的情况,这就要求我们具备一定的经验,能够理解代码的具体功能和作用。只有真正了解每一行代码的意义,才能准确地找出问题所在并进行有效的修复或整合。

最后,针对老项目中不再适用或与其他部分存在重复的代码进行剔除或调整,再进行编译和测试,循环往复,逐步完善整个项目。这个过程我已制作成视频分享出来,供大家参考学习。这种方法确实非常实用,不仅有助于解决当前的问题,也为今后遇到类似情境提供了高效的解决方案。

另外, 这个过程的详细方法,已经录制为视频, 放到b站,可以参考如下链接
https://www.bilibili.com/video/BV1iF4m1T7aP/

使用IPVS实现Kubernetes入口流量负载均衡

新搭建的Kubernetes集群如何承接外部访问的流量,是刚上手Kubernetes时常常会遇到的问题。 在公有云上,官方给出了比较直接的答案,使用LoadBalancer类型的Service,利用公有云提供的负载均衡服务来承接流量, 同时在多台服务器之间进行负载均衡。而在私有环境中,如何正确的将外部流量引入到集群内部,却暂时没有标准的做法。 本文将介绍一种基于IPVS来承接流量并实现负载均衡的方法,供大家参考。

IPVS

IPVS是LVS项目的一部分,是一款运行在Linux kernel当中的4层负载均衡器,性能异常优秀。 根据这篇文章的介绍,使用调优后的内核,可以轻松处理每秒10万次以上的转发请求。目前在中大型互联网项目中, IPVS被广泛的使用,用于承接网站入口处的流量。

Kubernetes Service

Service是Kubernetes的基础概念之一,它将一组Pod抽象成为一项服务,统一的对外提供服务,在各个Pod之间实现负载均衡。 Service有多种类型,最基本的ClusterIP类型解决了集群内部访问服务的需求,NodePort类型通过Node节点的端口暴露服务, 再配合上LoadBalancer类型所定义的负载均衡器,实现了流量经过前端负载均衡器分发到各个Node节点暴露出的端口, 再通过iptables进行一次负载均衡,最终分发到实际的Pod上这个过程。

在Service的Spec中,externalIPs字段平常鲜有人提到,当把IP地址填入这个字段后,kube-proxy会增加对应的iptables规则, 当有以对应IP为目标的流量发送到Node节点时,iptables将进行NAT,将流量转发到对应的服务上。一般情况下, 很少会遇到服务器接受非自身绑定IP流量的情况,所以externalIPs不常被使用,但配合网络层的其他工具,它可以实现给Service绑定外部IP的效果。

今天我们将使用externalIPs配合IPVS的DR(Direct Routing)模式实现将外部流量引入到集群内部,同时实现负载均衡。

环境搭建

为了演示,我们搭建了4台服务器组成的集群。一台服务器运行IPVS,扮演负载均衡器的作用,一台服务器运行Kubernetes Master组件, 其他两台服务器作为Node加入到Kubernetes集群当中。搭建过程这里不详细介绍,大家可以参考相关的文档。

所有服务器在172.17.8.0/24这个网段中。服务的VIP我们设定为172.17.8.201。整体架构入下图所示:

ipvs-kubernetes

接下来让我们来配置IPVS和Kubernetes。

使用externalIPs暴露Kubernetes Service

首先在集群内部运行2个nginx Pod用作演示。

$ kubectl run nginx --image=nginx --replicas=2

再将它暴露为Service,同时设定externalIPs字段

$ kubectl expose deployment nginx --port 80 --external-ip 172.17.8.201

查看iptables配置,确认对应的iptables规则已经被加入。

$ sudo iptables -t nat -L KUBE-SERVICES -n
Chain KUBE-SERVICES (2 references)
target     prot opt source               destination
KUBE-SVC-4N57TFCL4MD7ZTDA  tcp  --  0.0.0.0/0            10.3.0.156           /* default/nginx: cluster IP */ tcp dpt:80
KUBE-MARK-MASQ  tcp  --  0.0.0.0/0            172.17.8.201         /* default/nginx: external IP */ tcp dpt:80
KUBE-SVC-4N57TFCL4MD7ZTDA  tcp  --  0.0.0.0/0            172.17.8.201         /* default/nginx: external IP */ tcp dpt:80 PHYSDEV match ! --physdev-is-in ADDRTYPE match src-type !LOCAL
KUBE-SVC-4N57TFCL4MD7ZTDA  tcp  --  0.0.0.0/0            172.17.8.201         /* default/nginx: external IP */ tcp dpt:80 ADDRTYPE match dst-type LOCAL
KUBE-SVC-NPX46M4PTMTKRN6Y  tcp  --  0.0.0.0/0            10.3.0.1             /* default/kubernetes:https cluster IP */ tcp dpt:443
KUBE-NODEPORTS  all  --  0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL

配置IPVS实现流量转发

首先在IPVS服务器上,打开ipv4_forward

$ sudo sysctl -w net.ipv4.ip_forward=1

接下来加载IPVS内核模块。

$ sudo modprobe ip_vs

将VIP绑定在网卡上。

$ sudo ifconfig eth0:0 172.17.8.201 netmask 255.255.255.0 broadcast 172.17.8.255

再使用ipvsadm来配置IPVS,这里我们直接使用Docker镜像,避免和特定发行版绑定。

$ docker run --privileged -it --rm --net host luizbafilho/ipvsadm
/ # ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
/ # ipvsadm -A -t 172.17.8.201:80
/ # ipvsadm -a -t 172.17.8.201:80 -r 172.17.8.11:80 -g
/ # ipvsadm -a -t 172.17.8.201:80 -r 172.17.8.12:80 -g
/ # ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.17.8.201:http wlc
  -> 172.17.8.11:http             Route   1      0          0
  -> 172.17.8.12:http             Route   1      0          0

可以看到,我们成功建立了从VIP到后端服务器的转发。

验证转发效果

首先使用curl来测试是否能够正常访问nginx服务。

$ curl http://172.17.8.201
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

接下来在172.17.8.11上抓包来确认IPVS的工作情况。

$ sudo tcpdump -i any port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
04:09:07.503858 IP 172.17.8.1.51921 > 172.17.8.201.http: Flags [S], seq 2747628840, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1332071005 ecr 0,sackOK,eol], length 0
04:09:07.504241 IP 10.2.0.1.51921 > 10.2.0.3.http: Flags [S], seq 2747628840, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1332071005 ecr 0,sackOK,eol], length 0
04:09:07.504498 IP 10.2.0.1.51921 > 10.2.0.3.http: Flags [S], seq 2747628840, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1332071005 ecr 0,sackOK,eol], length 0
04:09:07.504827 IP 10.2.0.3.http > 10.2.0.1.51921: Flags [S.], seq 3762638044, ack 2747628841, win 28960, options [mss 1460,sackOK,TS val 153786592 ecr 1332071005,nop,wscale 7], length 0
04:09:07.504827 IP 10.2.0.3.http > 172.17.8.1.51921: Flags [S.], seq 3762638044, ack 2747628841, win 28960, options [mss 1460,sackOK,TS val 153786592 ecr 1332071005,nop,wscale 7], length 0
04:09:07.504888 IP 172.17.8.201.http > 172.17.8.1.51921: Flags [S.], seq 3762638044, ack 2747628841, win 28960, options [mss 1460,sackOK,TS val 153786592 ecr 1332071005,nop,wscale 7], length 0
04:09:07.505599 IP 172.17.8.1.51921 > 172.17.8.201.http: Flags [.], ack 1, win 4117, options [nop,nop,TS val 1332071007 ecr 153786592], length 0

可以看到,由客户端172.17.8.1发送给172.17.8.201的封包,经过IPVS的中转发送给了172.17.8.11这台服务器, 并经过NAT后发送给了10.2.0.3这个Pod。返回的封包不经过IPVS服务器直接从172.17.8.11发送给了172.17.8.1。 说明IPVS的DR模式工作正常。重复多次测试可以看到流量分别从172.17.8.11172.17.8.12进入,再分发给不同的Pod, 说明负载均衡工作正常。

与传统的IPVS DR模式配置不同的是,我们并未在承接流量的服务器上执行绑定VIP,再关闭ARP的操作。 那是因为对VIP的处理直接发生在iptables上,我们无需在服务器上运行程序来承接流量,iptables会将流量转发到对应的Pod上。

使用这种方法来承接流量,仅需要配置externalIPs为VIP即可,无需对服务器做任何特殊的设置,使用起来相当方便。

总结

在本文中演示了使用IPVS配合externalIPs实现将外部流量导入到Kubernetes集群中,并实现负载均衡的方法。 希望可以帮助大家理解IPVS和externalIPs的工作原理,以便在恰当的场景下合理使用这两项技术解决问题。 实际部署时,还需要考虑后台服务器可用性检查,IPVS节点主从备份,水平扩展等问题。在这里就不详细介绍了。

在Kubernetes中还有许多与externalIPs类似的非常用功能,有些甚至是使用Annotation来进行配置,将来有机会再进一步分享。

最后插播下广告,为了实现私有环境下的Kubernetes集群自动化部署和运维,我们为Archon系统增加了PXE管理物理机的支持, 相应的配置案例在这里。如果使用过程中有任何问题,欢迎跟我们联系。

 

来源:  https://www.kubernetes.org.cn/1904.html

简化Kubernetes应用部署工具-Helm简介

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:

  1. 管理、编辑与更新大量的K8s配置文件
  2. 部署一个含有大量配置文件的复杂K8s应用
  3. 分享和复用K8s配置和应用
  4. 参数化配置模板支持多个环境
  5. 管理应用的发布:回滚、diff和查看发布历史
  6. 控制一个部署周期中的某一些环节
  7. 发布后的验证

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文简单介绍了Helm的用途、架构与实现。

Helm产生原因

利用Kubernetes部署一个应用,需要Kubernetes原生资源文件如deployment、replicationcontroller、service或pod 等。而对于一个复杂的应用,会有很多类似上面的资源描述文件,如果有更新或回滚应用的需求,可能要修改和维护所涉及的大量资源文件,且由于缺少对发布过的应用版本管理和控制,使Kubernetes上的应用维护和更新等面临诸多的挑战,而Helm可以帮我们解决这些问题。

Helm架构

Helm基本架构如下:

Helm用途:

做为Kubernetes的一个包管理工具,Helm具有如下功能:

  • 创建新的chart
  • chart打包成tgz格式
  • 上传chart到chart仓库或从仓库中下载chart
  • 在Kubernetes集群中安装或卸载chart
  • 管理用Helm安装的chart的发布周期

Helm有三个重要概念:

  • chart:包含了创建Kubernetes的一个应用实例的必要信息
  • config:包含了应用发布配置信息
  • release:是一个chart及其配置的一个运行实例

Helm组件

Helm有以下两个组成部分:

Helm Client是用户命令行工具,其主要负责如下:

  • 本地chart开发
  • 仓库管理
  • 与Tiller sever交互
  • 发送预安装的chart
  • 查询release信息
  • 要求升级或卸载已存在的release

Tiller Server是一个部署在Kubernetes集群内部的server,其与Helm client、Kubernetes API server进行交互。Tiller server主要负责如下:

  • 监听来自Helm client的请求
  • 通过chart及其配置构建一次发布
  • 安装chart到Kubernetes集群,并跟踪随后的发布
  • 通过与Kubernetes交互升级或卸载chart

简单的说,client管理charts,而server管理发布release。

Helm实现

Helm client

  • Helm client采用go语言编写,采用gRPC协议与Tiller server交互。

Helm server

  • Tiller server也同样采用go语言编写,提供了gRPC server与client进行交互,利用Kubernetes client 库与Kubernetes进行通信,当前库使用了REST+JSON格式。
  • Tiller server 没有自己的数据库,目前使用Kubernetes的ConfigMaps存储相关信息

说明:配置文件尽可能使用YAM格式

 

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,Kubernetes中文社区

来源: https://www.kubernetes.org.cn/2700.html

DNS BIND之ACL、View、ZONE介绍

BIND主配置文件由named进程运行时首先读取,文件名为named.conf,默认在/etc目录下。该文件只包括Bind的基本配置,并不包含任何DNS的区域数据。named.conf配置文件由语句与注释组成,每一条主配置语句均有自己的选项参数。这些选项参数以子语句的形式组成,并包含在花括号内,作为主语句的组成部分。每一条语句,包括主语句和子语句,都必须以分号结尾。注释符号可以使用类似于C语言中的块注释"/*"和"*/"符号对,以及行注释符"//"或"#"。BIND 9支持的主配置语句及功能如下表:

配置名  称功    能
acl定义一个访问控制列表,用于以后对列表中的IP进行访问控制
controls定义有关本地域名服务器操作的控制通道,这些通道被rndc用来发送控制命令
include把另一个文件中的内容包含进来做为主配置文件的内容
key定义一个密匙信息,用于通过TSIG进行授权和认证的配置中
logging设置日志服务器,以及日志信息的发送位置
options设置DNS服务器的全局配置选项
server定义了与远程服务器交互的规则
trusted-keys定义信任的 DNSSED密匙
view定义一个视图
zone定义一个区域

其中:logging是有关日志配置的主语句,可以有众多的子语句,指明了日志记录的位置、日志的内容、日志文件的大小和日志的级别等内容,上一节我们已经讲过。
1.options语句
options语句设定可以被整个BIND使用的全局选项。这个语句在每个配置文件中只有一处,如果出现多个options语句,则第一个options的配置有效,并且会产生一个警告信息。如果没有options语句,每个子语句使用默认值。2.controls语句

controls主语句定义有关本地域名服务器操作的控制通道,这些通道被rndc用来发送控制命令。在上节的例子named.conf配置文件中有以下语句,现解释如下:

controls {
inet 127.0.0.1 port 953    //在127.0.0.1接口的953号端口进行监听
allow { 127.0.0.1; }    //只接受127.0.0.1的连接,即只有在本机使用rndc,才能对named进行控制
keys { "rndckey"; };     //使用名为rndckey的密钥才能访问
};

3.include语句
include主语句表示把另一个文件的内容包含进来,作为named.conf文件的配置内容,其效果与把那个文件的内容直接输入named.conf时一样。之所以这样做,一是为了简化一些分布式的named.conf文件的管理,此时,每个管理员只负责自己所管辖的配置内容。二是为了安全,因为可以把一些密钥放在其他文件,不让无关的人查看。
4.key语句
key主语句定义一个密匙,用于TSIG授权和认证。它主要在与其他DNS服务器或rndc工具通信时使用,可以通过运行rndc-confgen命令产生。

key "rndckey" {             //定义一个密钥,名为rndckey
algorithm hmac-md5;  //采用hmac-md5算法,这也是目前唯一支持的加密算法
secret "TKuaJSEo58zohJBfrdF7dQ==";       //密钥的具体数据
};

5.server语句
server主语句定义了与远程服务器交互的规则,例如,决定本地DNS服务器是作为主域名服务器还是辅域名服务器,以及与其他DNS服务器通信时采用的密钥等。语句可以出现在配置文件的顶层,也可以出现在视图语句的内部。如果一个视图语句包括了自己的server语句,则只有那些视图语句内的server语句才起作用,顶层的server语句将被忽略。如果一个视图语句内不包括server语句,则顶层server语句将被当做默认值。
6.trusted-keys语句
trusted-keys语句定义DNSSEC安全根的trusted-keys。DNSSEC指由RFC2535定义的DNS sercurity。当一个非授权域的公钥是已知的,但不能安全地从DNS服务器获取时,需要加入一个trusted-keys。这种情况一般出现在singed域是一个非signed域的子域的时候,此时加了trusted key后被认为是安全的。trusted-keys语句能包含多重输入口,由键的域名、标志、协议算法和64位键数据组成。
下面就ACL、VIEW、ZONE做一下介绍:1.view语句

view语句定义了视图功能。视图是BIND 9提供的强大的新功能,允许DNS服务器根据客户端的不同有区别地回答DNS查询,每个视图定义了一个被特定客户端子集见到的DNS名称空间。这个功能在一台主机上运行多个形式上独立的DNS服务器时特别有用。

视图(view)语句的定义:
view view_name [class] {
match-clients { address_match_list } ;
match-destinations { address_match_list } ;
match-recursive-only { yes_or_no } ;
[ view_option; ...]
zone-statistics yes_or_no ; ]
[ zone_statement; ...]
};

视图是BIND9强大的新功能,允许名称服务器根据询问者的不同有区别的回答DNS查询。特别是当运行拆分DNS设置而不需要运行多个服务器时特别有用。每个视图定义了一个将会在用户的子集中见到的DNS名称空间。

配置实例:

view "internal" {
match-clients { 10.0.0.0/8; };
// 应该与内部网络匹配.
// 只对内部用户提供递归服务.
// 提供example.com zone 的完全视图
//包括内部主机地址.
recursion yes;
zone "example.com" {
type master;
file "example-internal.db";
};
};
view "external" {
match-clients { any; };
// 拒绝对外部用户提供递归服务
// 提供一个example.com zone 的受限视图
// 只包括公共可接入主机
recursion no;
zone "example.com" {
type master;
file "example-external.db";
};
};

2.acl语句
acl主配置语句用于定义一个命名的访问列表,里面包含了一些用IP表示的主机,这个访问列表可以在其他语句使用,表示其所定义的主机。其格式如下:
acl acl-name {
address_match_list
};
address_match_list表示IP地址或IP地址集。其中,none、any、localhost和localnets这4个内定的关键字有特别含义,分别表示没有主机、任何主机、本地网络接口IP和本地子网IP。一个具体的例子如下所示。

acl "someips" {             //定义一个名为someips的ACL
10.0.0.1; 192.168.23.1; 192.168.23.15;      //包含3个单个IP
};
acl "complex" {             //定义一个名为complex的ACL
"someips";                //可以包含其他ACL
10.0.15.0/24;                 //包含10.0.15.0子网中的所有IP
!10.0.16.1/24;                //非10.0.16.1子网的IP
{10.0.17.1;10.0.18.2;};   //包含了一个IP组
localhost;                //本地网络接口IP(含实际接口IP和127.0.0.1)
};
zone "example.com" {
type slave;
file "slave.example.com";
allow-notify {"complex";};    //在此处使用了前面定义的complex访问列表
};

3.zone语句zone语句的定义:
zone zone_name [class] [{
type ( master | slave | hint | stub | forward ) ;
[ allow-notify { address_match_list } ; ]
[ allow-query { address_match_list } ; ]
[ allow-transfer { address_match_list } ; ]
[ allow-update { address_match_list } ; ]
[ update-policy { update_policy_rule [...] } ; ]
[ allow-update-forwarding { address_match_list } ; ]
[ alsonotify
{ ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
[ check-names (warn|fail|ignore) ; ]
[ dialup dialup_option ; ]
[ file string ; ]
[ forward (only|first) ; ]
[ forwarders
{ ip_addr [port ip_port] ; [ ip_addr [port ip_port] ; ... ] }; ]
[ ixfr-base string ; ]
[ ixfr-tmp-file string ; ]
[ maintain-ixfr-base yes_or_no ; ]
[ masters [port ip_port] { ip_addr [port ip_port] [key key]; [...] } ; ]
[ max-ixfr-log-size number ; ]
[ max-transfer-idle-in number ; ]
[ max-transfer-idle-out number ; ]
[ max-transfer-time-in number ; ]
[ max-transfer-time-out number ; ]
[ notify yes_or_no | explicit ; ]
[ pubkey number number number string ; ]
[ transfer-source (ip4_addr | *) [port ip_port] ; ]
[ transfer-source-v6 (ip6_addr | *) [port ip_port] ; ]
[ notify-source (ip4_addr | *) [port ip_port] ; ]
[ notify-source-v6 (ip6_addr | *) [port ip_port] ; ]
[ zone-statistics yes_or_no ; ]
[ sig-validity-interval number ; ]
[ database string ; ]
[ min-refresh-time number ; ]
[ max-refresh-time number ; ]
[ min-retry-time number ; ]
[ max-retry-time number ; ]
}];

zone语句定义了DNS服务器所管理的区,也就是哪一些域的域名是授权给该DNS服务器回答的。一共有5种类型的区,由其type子语句指定,具体名称和功能如下所示。
Master(主域):主域用来保存某个区域(如www.wzvtc.cn)的数据信息。
Slave(辅域):也叫次级域,数据来自主域,起备份作用。
Stub:Stub区与辅域相似,但它只复制主域的NS记录,而不是整个区数据。它不是标准DNS的功能,只是BIND提供的功能。
Forward(转发):转发域中一般配置了 forward和forwarders子句,用于把对该域的查询请求转由其他DNS服务器处理。
Hint:Hint域定义了一套最新的根DNS服务器地址,如果没有定义,DNS服务器会使用内建的根DNS服务器地址。
配置实例:

zone "." IN {           //定义一个名为"."的区,查询类为IN
type hint;              //类型为hint
file "named.root";      //区文件是named.root
};
zone  "1.10.10.in-addr.arpa" IN {     //定义一个名为1.10.10.in-addr.arpa的区,查询类为IN
type master;                    //类型为master
file "named.1.10.10";       //区文件是named.1.10.10
allow-update  { none; };    //不允许任何客户端对数据进行更新
};

说明:在每一个zone语句中,都用file子语句定义一个区文件,这个文件里存放了域名与IP地址的对应关系。对于ACL、VIEW、ZONE的应用,DNS服务器有一个高级的功能,能够实现不同的用户访问同一个域名,把域名解析成不同的IP地址,使用户能够访问离他最近的服务器上的数据,这就是DNS服务器的视图功能。使用DNS服务器的视图功能可以增加网站的响应速度。例如,当我们网站的数据同步在两台web服务器上时,一台是电信服务器,一台是网通服务器,那么我们肯定希望全国访问我们网站的用户在打开网站的时候,能够自动实现,电信用户访问电信服务器,网通用户访问网通服务器。配置这种情况的前提是,web服务器必须要有一个电信的IP地址和一个网通的IP地址。DNS服务器的这种解析功能通常也被称之为智能解析。

DNS服务器的视图通常在配置文件中是使用view实现的。把要使用某些IP地址作单独访问的zone区域,统一放在一个命名的view段落中,并且在view中定义请求的IP地址或IP地址段,把IP地址写入match-clients选项中。如果像上面说的,区分电信和网通路线的话,那么可以使用两个acl访问控制列表写上电信或网通IP地址,定义电信网通路线,把acl名字写入view段落match-clients选项中。如下所示:

acl telecomip{ tele_IP; ... };
acl netcomip{ net_IP; ... };
view telecom {
match-clients { telecomip; };
zone "ZONE_NAME" IN {
type master;
file "ZONE_NAME.telecom";
};
};
view netcom {
match-clients { netcomip; };
zone "ZONE_NAME" IN {
type master;
file "ZONE_NAME.netcom";
};
};
view default {
match-clients { any; };
zone "ZONE_NAME" IN {
type master;
file "ZONE_NAME.netcom";
};
};

需要注意的是:
(1)、如果使用了视图的功能,那么配置文件中的所有zone区域都要必须写在视图里面,如,配置文件里默认要配置的三个区域,根、127.0.0.1、1.0.0.127.in-addr.arpa都要写入视图。
(2)、在acl中定义IP地址,IP地址的写法可以是单个IP地址也可以是一个IP地址段加掩码,如:192.168.0.0/24。
(3)、视图是根据配置文件从上往下匹配的,所以希望优先访问的资源记录文件,区域应该尽量写前面。
(4)、如果定义的若干个视图的IP地址不全的话,那么可以在最后定义一个默认视图,match-clients选项中的IP地址写上any,代表如果此次访问的IP地址上面没有一个能匹配到,则在此处归类。