dnscache --源码笔记
//最新版本参见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 --源码笔记的更多相关文章
- Zepto源码笔记(一)
最近在研究Zepto的源码,这是第一篇分析,欢迎大家继续关注,第一次写源码笔记,希望大家多指点指点,第一篇文章由于首次分析原因不会有太多干货,希望后面的文章能成为各位大大心目中的干货. Zepto是一 ...
- redis源码笔记(一) —— 从redis的启动到command的分发
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/redis1 本博客同步在http://www.cnblog ...
- AsyncTask源码笔记
AsyncTask源码笔记 AsyncTask在注释中建议只用来做短时间的异步操作,也就是只有几秒的操作:如果是长时间的操作,建议还是使用java.util.concurrent包中的工具类,例如Ex ...
- Java Arrays 源码 笔记
Arrays.java是Java中用来操作数组的类.使用这个工具类可以减少平常很多的工作量.了解其实现,可以避免一些错误的用法. 它提供的操作包括: 排序 sort 查找 binarySearch() ...
- Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目
以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...
- Tomcat8源码笔记(七)组件启动Server Service Engine Host启动
一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...
- Tomcat8源码笔记(六)连接器Connector分析
根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...
- Tomcat8源码笔记(五)组件Container分析
Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...
- Tomcat8源码笔记(四)Server和Service初始化
上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...
随机推荐
- Spring Kafka和Spring Boot整合实现消息发送与消费简单案例
本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...
- LeetCode刷题之合并排序链表
合并两个有序链表并返回一个新的列表.新列表应该由连接在一起的节点前两个列表 给定实例:Input: 1->2->4, 1->3->4Output: 1->1->2- ...
- jQuery学习小结
1.jQuery hide() 和 show() 通过 jQuery,您可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素: $("#hide").clic ...
- .net找List1和List2的差集
有个需求是找两个自定义类泛型集合的差集: class Person { public string Name{get; set;} public string Country{get; set;} } ...
- Testng基本问题
Testng testng.xml suite属性说明: suite verbose="4" 命令行信息打印等级 1~5 parallel 是否多线程并发运行测试:可选值(fals ...
- AngularJS之备忘与诀窍
译自:<angularjs> 备忘与诀窍 目前为止,之前的章节已经覆盖了Angular所有功能结构中的大多数,包括指令,服务,控制器,资源以及其它内容.但是我们知道有时候仅仅阅读是不够的. ...
- 使用Swashbuckle构建RESTful风格文档
本次和大家分享的是Swagger to WebApi的nuget包Swashbuckle:因为项目需要统一api文档的风格,并要支持多种开发语言(C#,java,python),所以首先想到的是swa ...
- 谈谈Javascript异步代码优化
关于 微信公众号:前端呼啦圈(Love-FED) 我的博客:劳卜的博客 知乎专栏:前端呼啦圈 前言 在实际编码中,我们经常会遇到Javascript代码异步执行的场景,比如ajax的调用.定时器的使用 ...
- 安装ie时,报:此安装不支持您的操作系统的当前语言
打开注册表(win的"运行"栏键入 regedit 再按 OK )的HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Nls/ ...
- Servlet线程
一,servlet容器如何同时处理多个请求. Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求.线程池实际上是等待执行代码的一组线程叫做工作者线程(Wor ...