//最新版本参见https://github.com/karlseguin/dnscache地址 或者  https://github.com/netroby/dnscache   

package dnscache
// Package dnscache caches DNS lookups

import (
  "net"
  "sync"
  "time"
)
//一个域名可能对应多个ip
type Resolver struct {
  lock sync.RWMutex   //锁--读写锁
  cache map[string][]net.IP  //map中key 为address ,value为域名对应的ip结合集合
}
//参数 refreshRate   设置刷新周期
func New(refreshRate time.Duration) *Resolver {
  resolver := &Resolver {
    cache: make(map[string][]net.IP, 64),
  }
  if refreshRate > 0 {//当刷新周期大于零  开启一个协程来自动解析域名,再次填充cache
    go resolver.autoRefresh(refreshRate)
  }
  return resolver
}
//解析域名对应的ip集合  如果在当前缓存中不存在  ,重新解析并返回
func (r *Resolver) Fetch(address string) ([]net.IP, error) {
  r.lock.RLock()
  ips, exists := r.cache[address]
  r.lock.RUnlock()
  if exists { return ips, nil }

  return r.Lookup(address)
}
//解析域名对应的ip集合中第一个ip
func (r *Resolver) FetchOne(address string) (net.IP, error) {
  ips, err := r.Fetch(address)
  if err != nil || len(ips) == 0 { return nil, err}
  return ips[0], nil
}
//解析域名对应的ip集合第一个ip的String方法
func (r *Resolver) FetchOneString(address string) (string, error) {
  ip, err := r.FetchOne(address)
  if err != nil || ip == nil { return "", err }
  return ip.String(), nil
}
//解析当前cache中所有的域名 并且处于阻塞中2秒  。每一个域名对应一个ip集合 并存储在cache中
func (r *Resolver) Refresh() {
  i := 0
  r.lock.RLock()//获取读锁
  addresses := make([]string, len(r.cache)) //创建一个slice  初始容量为 cache大小  用来存储当前的域名
  for key, _ := range r.cache {
    addresses[i] = key
    i++
  }
  r.lock.RUnlock()

  for _, address := range addresses {
    r.Lookup(address)
    time.Sleep(time.Second * 2)
  }
}
//通过net包 解析域名对应的ip集合
func (r *Resolver) Lookup(address string) ([]net.IP, error) {
  ips, err := net.LookupIP(address)
  if err != nil { return nil, err }

  r.lock.Lock()
  r.cache[address] = ips
  r.lock.Unlock()
  return ips, nil
}
//参数 rate   刷新周期
func (r *Resolver) autoRefresh(rate time.Duration) {
  for {
    time.Sleep(rate) //睡眠rate周期  并且处于阻塞中
    r.Refresh()
  }
}

dnscache --源码笔记的更多相关文章

  1. Zepto源码笔记(一)

    最近在研究Zepto的源码,这是第一篇分析,欢迎大家继续关注,第一次写源码笔记,希望大家多指点指点,第一篇文章由于首次分析原因不会有太多干货,希望后面的文章能成为各位大大心目中的干货. Zepto是一 ...

  2. redis源码笔记(一) —— 从redis的启动到command的分发

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/redis1 本博客同步在http://www.cnblog ...

  3. AsyncTask源码笔记

    AsyncTask源码笔记 AsyncTask在注释中建议只用来做短时间的异步操作,也就是只有几秒的操作:如果是长时间的操作,建议还是使用java.util.concurrent包中的工具类,例如Ex ...

  4. Java Arrays 源码 笔记

    Arrays.java是Java中用来操作数组的类.使用这个工具类可以减少平常很多的工作量.了解其实现,可以避免一些错误的用法. 它提供的操作包括: 排序 sort 查找 binarySearch() ...

  5. Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目

    以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...

  6. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

  7. Tomcat8源码笔记(六)连接器Connector分析

    根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...

  8. Tomcat8源码笔记(五)组件Container分析

    Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...

  9. Tomcat8源码笔记(四)Server和Service初始化

    上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...

随机推荐

  1. html的meta标签

    meta是一个空元素,没有结束标签:meta元素可以附带8个属性,其中4个是通用属性-–dir,lang,xml:lang和title,其他4个是meta特有的属性: schema,name,cont ...

  2. 二叉树的建立以及遍历的多种实现(python版)

    二叉树是很重要的数据结构,在面试还是日常开发中都是很重要的角色. 首先是建立树的过程,对比C或是C++的实现来讲,其涉及到了较为复杂的指针操作,但是在面向对象的语言中,就不需要考虑指针, 内存等.首先 ...

  3. Java语言概论

    第1章 ■    Java的发展简史及特点 ■    J2SDK的下载与安装 ■    Java应用程序的编写 ■    Eclipse的下载及使用 ■    正确安装使用J2SDK ■    使用记 ...

  4. 双机热备ROSE HA工作原理

    双机热备ROSE HA工作原理 当双机热备软件启动后,ROSE HA首先启动HA Manager管理程序,根据高可靠性系统的配置结构初始化,然后启动必要的服务和代理程序来监控和管理系统服务.HA代理程 ...

  5. [C#网络应用编程]1、对进程的操作

    在.net中,Process类提供了对进程进行管理的各种方法. 一.获取进程集合的方法: Process[] myProcesses = Process.GetProcesses();  //获取本地 ...

  6. DDD实战进阶第一波(九):开发一般业务的大健康行业直销系统(实现经销商上下文仓储与领域逻辑)

    上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...

  7. Msys+MinGW编译VLC

      说明:本文只是对官方文档进行简单的翻译总结,旨在帮助一些英文不太好的朋友.官方文档请见wiki.videolan.org/Win32CompileMSYSNew. Msys是MinGW的一个辅助工 ...

  8. Mysql分页查询性能分析

    [PS:原文手打,转载说明出处,博客园] 前言 看过一堆的百度,最终还是自己做了一次实验,本文基于Mysql5.7.17版本,Mysql引擎为InnoDB,编码为utf8,排序规则为utf8_gene ...

  9. Python绘图之matplotlib基本语法

    Matplotlib 是一个 Python 的 2D绘图库,通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等.当然他也是可以画出3D图形的 ...

  10. jieba库分词

    (1)团队简介的词频统计 import jieba import collections s="制作一个购票小程序,这个购票小程序可以根据客户曾经的购票历史" s+="和 ...