//最新版本参见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. C# 如何合并Excel工作表

    文档合并.拆分是实现文档管理的一种有效方式.在工作中,我们可能会遇到需要将多个文档合并的情况,那如何来实现呢,本文将进一步介绍.关于拆分Excel工作表,可参见这篇文章--C#如何拆分EXCEL工作表 ...

  2. Spring Boot 2.0.1 入门教程

    简介 Spring Boot是Spring提供的一套基础配置环境,可以用来快速开发生产环境级别的产品.尤其适合开发微服务架构,省去了不少配置麻烦.比如用到Spring MVC时,只需把spring-b ...

  3. combination sum、permutation、subset(组合和、全排列、子集)

    combination sum I.permutation I.subsets  I 是组合和.全排列.子集的第一种情况,给定数组中没有重复的元素. combination sum II.permut ...

  4. JavaScript中对象数组 根据某个属性值进行排序

    将下列对象数组,通过工资属性,由高到低排序 var BaiduUsers = [], WechatUsers = []; var User = function(id, name, phone, ge ...

  5. 登录以及发送微信消息itchat 库

    项目地址点这里 itchat   itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单. 使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人. 当然,该api的 ...

  6. apache压力测试工具的apache bench和JMeter的安装

    Apache压力测试工具的安装 1,apache bench的安装 apache  bench工具集成在http的软件包内,可以直接安装apache就可以. 当有些时候,我们不需要用到所有的软件包,我 ...

  7. jsonp学习

    使用 JSONP 实现跨域通信:http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/

  8. Redis实际开发中常见问题

    首先redis作为缓存,一般作为缓存有2个用途,快速访问和减少IO频率,所谓减少IO频率就是等缓存积累到一定大小然后一次刷入磁盘进行持久化. 一般的设计就是客户端往数据库里更新或者读写数据,redis ...

  9. 使用ssh keys实现免验证登陆远程服务

    使用ssh keys实现免验证登陆远程服务========================Created 星期四 10 五月 2018 引言------------------程序员或者服务器运维人员 ...

  10. Maven打包详细流程

    方法一:cmd 控制台打包(比较不推荐) 首先安装maven插件百度下载一个,配置环境变量什么的~在cmd控制台能mvn version能有数据出现. 打包只需要到项目的根目录下~在cmd敲入mvn ...