用Windows powershell,加windows的dns伺服器。從調整dns伺服器解析ip時間段的角度,解決網站負載平衡問題。
win2012r2中,用powershell管理dns伺服器的,命令列表
PS C:\Users\admin> get-command * -module DnsServer
CommandType Name ModuleName
----------- ---- ----------
Alias Export-DnsServerTrustAnchor DnsServer
Function Add-DnsServerConditionalForwarderZone DnsServer
Function Add-DnsServerDirectoryPartition DnsServer
Function Add-DnsServerForwarder DnsServer
Function Add-DnsServerPrimaryZone DnsServer
Function Add-DnsServerResourceRecord DnsServer
Function Add-DnsServerResourceRecordA DnsServer
Function Add-DnsServerResourceRecordAAAA DnsServer
Function Add-DnsServerResourceRecordCName DnsServer
Function Add-DnsServerResourceRecordDnsKey DnsServer
Function Add-DnsServerResourceRecordDS DnsServer
Function Add-DnsServerResourceRecordMX DnsServer
Function Add-DnsServerResourceRecordPtr DnsServer
Function Add-DnsServerRootHint DnsServer
Function Add-DnsServerSecondaryZone DnsServer
Function Add-DnsServerSigningKey DnsServer
Function Add-DnsServerStubZone DnsServer
Function Add-DnsServerTrustAnchor DnsServer
Function Add-DnsServerZoneDelegation DnsServer
Function Clear-DnsServerCache DnsServer
Function Clear-DnsServerStatistics DnsServer
Function ConvertTo-DnsServerPrimaryZone DnsServer
Function ConvertTo-DnsServerSecondaryZone DnsServer
Function Disable-DnsServerSigningKeyRollover DnsServer
Function Enable-DnsServerSigningKeyRollover DnsServer
Function Export-DnsServerDnsSecPublicKey DnsServer
Function Export-DnsServerZone DnsServer
Function Get-DnsServer DnsServer
Function Get-DnsServerCache DnsServer
Function Get-DnsServerDiagnostics DnsServer
Function Get-DnsServerDirectoryPartition DnsServer
Function Get-DnsServerDnsSecZoneSetting DnsServer
Function Get-DnsServerDsSetting DnsServer
Function Get-DnsServerEDns DnsServer
Function Get-DnsServerForwarder DnsServer
Function Get-DnsServerGlobalNameZone DnsServer
Function Get-DnsServerGlobalQueryBlockList DnsServer
Function Get-DnsServerRecursion DnsServer
Function Get-DnsServerResourceRecord DnsServer
Function Get-DnsServerRootHint DnsServer
Function Get-DnsServerScavenging DnsServer
Function Get-DnsServerSetting DnsServer
Function Get-DnsServerSigningKey DnsServer
Function Get-DnsServerStatistics DnsServer
Function Get-DnsServerTrustAnchor DnsServer
Function Get-DnsServerTrustPoint DnsServer
Function Get-DnsServerZone DnsServer
Function Get-DnsServerZoneAging DnsServer
Function Get-DnsServerZoneDelegation DnsServer
powershell 傳教士 原創文章 2015-11-25改允許轉載,但必須保留名字和出處,否則追究法律責任
Function Import-DnsServerResourceRecordDS DnsServer
Function Import-DnsServerRootHint DnsServer
Function Import-DnsServerTrustAnchor DnsServer
Function Invoke-DnsServerSigningKeyRollover DnsServer
Function Invoke-DnsServerZoneSign DnsServer
Function Invoke-DnsServerZoneUnsign DnsServer
Function Register-DnsServerDirectoryPartition DnsServer
Function Remove-DnsServerDirectoryPartition DnsServer
Function Remove-DnsServerForwarder DnsServer
Function Remove-DnsServerResourceRecord DnsServer
Function Remove-DnsServerRootHint DnsServer
Function Remove-DnsServerSigningKey DnsServer
Function Remove-DnsServerTrustAnchor DnsServer
Function Remove-DnsServerZone DnsServer
Function Remove-DnsServerZoneDelegation DnsServer
Function Reset-DnsServerZoneKeyMasterRole DnsServer
Function Restore-DnsServerPrimaryZone DnsServer
Function Restore-DnsServerSecondaryZone DnsServer
Function Resume-DnsServerZone DnsServer
Function Set-DnsServer DnsServer
Function Set-DnsServerCache DnsServer
Function Set-DnsServerConditionalForwarderZone DnsServer
Function Set-DnsServerDiagnostics DnsServer
Function Set-DnsServerDnsSecZoneSetting DnsServer
Function Set-DnsServerDsSetting DnsServer
Function Set-DnsServerEDns DnsServer
Function Set-DnsServerForwarder DnsServer
Function Set-DnsServerGlobalNameZone DnsServer
Function Set-DnsServerGlobalQueryBlockList DnsServer
Function Set-DnsServerPrimaryZone DnsServer
Function Set-DnsServerRecursion DnsServer
Function Set-DnsServerResourceRecord DnsServer
Function Set-DnsServerResourceRecordAging DnsServer
Function Set-DnsServerRootHint DnsServer
Function Set-DnsServerScavenging DnsServer
Function Set-DnsServerSecondaryZone DnsServer
Function Set-DnsServerSetting DnsServer
Function Set-DnsServerSigningKey DnsServer
Function Set-DnsServerStubZone DnsServer
Function Set-DnsServerZoneAging DnsServer
Function Set-DnsServerZoneDelegation DnsServer
Function Show-DnsServerCache DnsServer
Function Show-DnsServerKeyStorageProvider DnsServer
Function Start-DnsServerScavenging DnsServer
Function Start-DnsServerZoneTransfer DnsServer
Function Step-DnsServerSigningKeyRollover DnsServer
Function Suspend-DnsServerZone DnsServer
Function Sync-DnsServerZone DnsServer
Function Test-DnsServer DnsServer
Function Test-DnsServerDnsSecZoneSetting DnsServer
Function Unregister-DnsServerDirectoryPartition DnsServer
Function Update-DnsServerTrustPoint DnsServer
手冊在:
https://technet.microsoft.com/library/jj649850(v=wps.630).aspx
------------------------------具體問題-------------------------------------------------
guest問:dns輪詢壓力不均的問題
最近一直對DNS輪詢有一個疑問,我在一個網域名稱下掛了十多個IP,實現簡單的負載平衡功能。
但明顯發現這種輪詢不是很均勻,有一台伺服器上的壓力始終很高,其他的比較接近,但將此台壓力高的從dns列表上去掉後,列表中的下一台壓力又會高起來,
此時再把先前那一台加回dns列表,壓力就又轉回到第一台上去了。已經排除了攻擊的可能。這個問題一直困擾了我很久,不知是bind的bug還是我設定ttl或是其他什麼的原因,不知有沒有高人對這方面有所研究的?
user1答:
DNS 輪詢機制會受到多方面的影響,如:A記錄的TTL時間長短的影響;別的 DNS 伺服器 Cache 的影響;windows 用戶端也有一個 DNS Cache。
這些都會影響 DNS 輪詢的效果。因此 DNS 的輪詢機制並不能做為一個 load balancing 的解決方案,只能作為一個 load distribution 方案。
user2答:
絕大部分網民用的上網系統為WINDOWS系統,在WINDOWS系統上預設開啟dns cache服務,這就造成在一個TTL周期內DNS輪詢是無效的。
所以為了減小dns cache對輪詢效果的影響,通行的做法是減小TTL的值如60-300。(TTL太小也是有害的,故而需要謹慎對待)
-------------------------問題分析過程------------------------------------
1 user1,user2說的很好,所以我引用了。ttl不宜太小正常即可。
2 我把這個過程比喻成,【呼啦超】那麼多的食客來問你,你家的飯店的分店咋走,然後進你家的分店,去吃喝。
你家飯店假設有n家分店,每家最大接待能力不同,當前擁有的客人數不同,剩餘的接待能力不同。
3 由於上兩個人說的問題,導致了這樣的結果,你不可能知道未來啥時候有食客來查分店地址(時間),因為有緩衝,你也不可能知道未來食客具體有多少人(使用者數量)。你也不可能知道查了ip的食客中,有多少會來吃。
4 所以說必須有一個【每分店剩餘接待能力反饋】!
即有一個值,伺服器串連失敗,取值失敗,則返回-1。-1太多則警示。
值為0,則代表分店客滿,0太多則警示。我ps指令碼就會跳過這家分店。
正常的值為0----1之間的數,表示這家分店的接の客能力。每個伺服器有了這個數值供給,剩下就好辦了。
5 為什麼用win的dns?
答:
5.1 主要因為有powershell。
我記得bind無法用命令添加a記錄等,並立即生效。這樣的話拍馬也趕不上powershell了!你要搞個程式去修改dns地區檔案,然後reload分區。這樣效能很差吧。
powershell命令管理dns是記憶體操作。主要用到的命令就這四個:
Add-DnsServerResourceRecordA,Add-DnsServerResourceRecordCName,Get-DnsServerResourceRecord,Remove-DnsServerResourceRecord
5.2 win的dns效能無問題:我記得bind是多進程的程式,可以用多核跑,無效能制約。而win2000中說win的dns比bind效率高。
dns還都是10年前都成熟的東西。退一萬步來講,win的dns玩一千個以下的ip解析,不會有效能問題。
5.3 可以用win做主dns伺服器,linux+bind做緩衝。win放內網,linux放外網,只從外網dns緩衝取資料。
-------------------------我給出的,問題解題流程------------------------------------
1 用任務計劃,每1---n分鐘定期調用powershell指令碼解題。這裡假設都是1分鐘。
指令碼運行後,把自己的pid放入環境變數,然後繼續運行。
指令碼重新運行後,從環境變數中尋找前一個指令碼的pid,殺死前一個指令碼。然後重複上一步,避免指令碼死結。
2 用一個ps程式,從每家分店取回來,每家分店的(剩餘)接待能力。
即有一個值,伺服器串連失敗,取值失敗,則返回-1。-1太多則警示。
值為0,則代表分店客滿,0太多則警示。我ps指令碼就會跳過這家分店。
正常的值為0----1之間的數,表示這家分店的接の客能力。
powershell 傳教士 原創文章 2015-11-25改允許轉載,但必須保留名字和出處,否則追究法律責任
3 從這n家分店返回的接客能力中,總是挑2家最閑(數值最大)分店,把這2個新的a記錄寫入dns,然後刪除所有舊的a記錄。
設【取接待能力時間】為α秒,這裡暗含著等待60-α-2秒。α如果較大則應增加任務計劃分鐘數。
結論:
我這個方法就是用dns來搞均衡,
我這個方法就是要告訴你,怎麼搞的很均衡。
就是用我發明的填坑法,永遠只填最大的兩個坑!永遠把最閒置伺服器的ip,放入dns伺服器,解析給客戶!
-------------------------解題具體指令碼------------------------------------
#Requires -RunAsAdministrator
# 更換dns的a記錄,到最大接待能力2台機的ip子上。
[string]$網域名稱 = "aaaaxxxx.com"
[string]$主機名稱 = "ppp"
[int32]$伺服器客滿值 = 3
[int32]$伺服器無響應值 = 2
$記錄檔儲存位置 = 'd:\aaa.txt'
$分店01 = @{'ip' = '1.2.3.4';'接待能力' = 0}
$分店02 = @{'ip' = '2.2.3.4';'接待能力' = 0}
$分店03 = @{'ip' = '3.2.3.4';'接待能力' = 0}
$分店04 = @{'ip' = '4.2.3.4';'接待能力' = 0}
$分店05 = @{'ip' = '5.2.3.4';'接待能力' = 0}
$分店06 = @{'ip' = '6.2.3.4';'接待能力' = 0}
$分店07 = @{'ip' = '7.2.3.4';'接待能力' = 0}
$分店08 = @{'ip' = '8.2.3.4';'接待能力' = 0}
$分店09 = @{'ip' = '9.2.3.4';'接待能力' = 0}
$分店10 = @{'ip' = '10.2.3.4';'接待能力' = 0}
$各分店集合 = $分店01,$分店02,$分店03,$分店04,$分店05,$分店06,$分店07,$分店08,$分店09,$分店10
if ($env:dnschanger_pid -ne $null)
{
$temp001 = Get-Process -id $env:dnschanger_pid
if ($temp001 -ne $null)
{
Stop-Process $temp001 -Force
}
}
[System.Environment]::SetEnvironmentvariable("dnschanger_pid","$PID", "user")
function 擷取分店接待能力
{
<#
這個函數返回一個值。
若伺服器串連失敗,或取值失敗,則返回-1。-1太多則警示。
值為0,則代表分店客滿,0太多則警示。我ps指令碼就會跳過這家分店。
正常的傳回值為0----1之間的數,表示這家分店的接の客能力。
#>
}
function 伺服器客滿警示
{
}
function 伺服器無響應警示
{
}
# 無響應返回 -1,客滿返回0,正常返回0----1間的值
$分店01.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店02.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店03.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店04.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店05.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店06.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店07.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店08.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店09.'接待能力' = 擷取分店接待能力 "aaa" 123
$分店10.'接待能力' = 擷取分店接待能力 "aaa" 123
$各分店接待能力集合 = $分店01.'接待能力',$分店02.'接待能力',$分店03.'接待能力',$分店04.'接待能力',$分店05.'接待能力',$分店06.'接待能力',$分店07.'接待能力',$分店08.'接待能力',$分店09.'接待能力',$分店10.'接待能力'
[system.array]::Sort($各分店接待能力集合)
$分組 = Group-Object -InputObject $各分店接待能力集合
if (($分組[0].name -eq -1) -and ($分組[0].Count -gt $伺服器無響應值) )
{
伺服器無響應警示
$err_msg = '伺服器無響應!'
Write-Error $err_msg
$日期 = Get-date -Format F
Add-Content -Value $("$日期 $err_msg") -LiteralPath $記錄檔儲存位置
exit 1
}
if (($分組[0].name -eq 0) -and ($分組[0].Count -gt $伺服器客滿值) )
{
伺服器客滿警示
$err_msg = '客滿分店太多!'
Write-Error $err_msg
$日期 = Get-date -Format F
Add-Content -Value $("$日期 $err_msg") -LiteralPath $記錄檔儲存位置
exit 2
}
# -----------------------------------------
$狀元 = $各分店接待能力集合[-1]
$榜眼 = $各分店接待能力集合[-2]
foreach ($temp011 in $各分店集合)
{
if ($temp011.'接待能力' -eq $狀元)
{
[string]$ip1 = $temp011.'ip'
}
if ($temp011.'接待能力' -eq $榜眼)
{
[string]$ip2 = $temp011.'ip'
}
}
#Import-Module -name DnsServer
$舊的dns記錄 = Get-DnsServerResourceRecord -ZoneName $網域名稱 -Name $主機名稱 -RRType "A"
$舊的ip = $舊的dns記錄.RecordData.IPv4Address.IPAddressToString
Add-DnsServerResourceRecord -A -ZoneName $網域名稱 -Name $主機名稱 -IPv4Address $ip1 -TimeToLive 01:00:00
Add-DnsServerResourceRecord -A -ZoneName $網域名稱 -Name $主機名稱 -IPv4Address $ip2 -TimeToLive 01:00:00
#Add-DnsServerResourceRecord -CName -ZoneName $網域名稱 -Name $主機名稱 -HostNameAlias "Host34.lab.com" -TimeToLive 01:00:00
foreach ($temp002 in $舊的ip)
{
Remove-DnsServerResourceRecord -ZoneName $網域名稱 -Name $主機名稱 -RRType "A" -RecordData $temp002 -Force
}
利用dns解析來實現網站的負載平衡
當網站的訪問量大了就會考慮負載平衡,這也是每一個架構師的基本功了,其基本地位就相當於相聲裡的說學逗唱,活好不好就看這個了 :)
傳統的負載平衡思路是單點的,不管你是硬體的還是軟體的基本都是這樣的原理
對於一般的需求來說,這樣的架構基本就可以解決問題了。而且維護起來也相對簡單。嗯,大多數公司也都是這麼乾的。
傳統思路的局限性
就如同上圖所示,傳統思路也存在非常明顯的局限性。也就是網站的響應速度很大程度上局限於負載平衡節點的能力,而且一旦負載平衡節點本身掛掉的話,整個網站就完全癱瘓了。後端的服務可以水平擴充,但是對於單個節點來說就算你再增大機器的配置也是有極限的,而且這也不符合互連網技術的發展規律。
CDN是怎麼做的
作為互連網上承載大部分流量的一大基礎設施,CDN對負載分流的解決思路很具有啟發性
從上圖可以看到,使用者的訪問被分流了,所有的請求不再是聚集到一個節點上,而是被分擔在了各個合適的節點上,這樣即使存在單點故障,也僅僅只會影響到一部分使用者,況且我們還可以使用其他手段做容錯移轉。
同樣的做法也可以借鑒到傳統的BS架構中,我們也可以把使用者的請求直接分流到不同的伺服器上,而不必經過一個統一的節點中轉。這個分流是通過什麼做到的呢?答案就是 DNS!
你知道DNS是怎麼工作的嗎?
大部分人可能天天都用著DNS卻不知道它的基本原理,你可能知道我們訪問互連網需要查詢dns伺服器,就是下面的這個玩意
我們只需要問它網域名稱所對應的ip地址就行了。但事情真的這麼簡單嗎?它是怎麼知道這個網域名稱所對應的ip地址呢?
其實dns系統是一個典型的樹狀架構,上圖所示的dns伺服器其實應該叫dns緩衝查詢服務器,它是為了減輕互連網上dns查詢的負載所設計的。如果你的請求沒有命中緩衝,那麼這個快取服務器就會自己進行一次標準查詢,然後再把結果緩衝起來,簡單來說就是從根伺服器開始一級一級的問。我們以前經常談到根伺服器的重要性其實就體現在這裡了,它保留了對所有網域名稱的起始解釋權
神奇的解釋權機制(SOA)
上面講到根伺服器擁有一切網域名稱的起始解釋權,但是如果你去問根伺服器它是不會直接告訴你最終答案的。因為如果它要儲存所有的記錄,那它也太累了,這個負載和開銷是驚人的。那它會告訴你什麼呢?它會告訴你應該去問誰,也就是它授權下一級伺服器來解答你的問題。擬人化這個過程
我: root, root 告訴我, segmentfault.com 怎麼走?
root: 呵呵,你可以去問.com的dns伺服器,地址是xxxxxx
我: .com, .com 告訴我,segmentfault.com 怎麼走?
.com: 呵呵,你可以去問segmentfault.com的dns伺服器(dnspod之類的),地址是xxxxxx
我: dnspod, dnspod 告訴我,segmentfault.com 怎麼走?
dnspod: 拿著 xxxxxx,走你
DNS負載平衡的基本原理
瞭解了上述過程,我們得到兩個基本結論
dns系統本身是一個分布式的網路,它是相對可靠的,起碼比你網站本身可靠的多
dns的最終解釋是可以受我們自己控制的
有了這兩條結論,剩下的事情就簡單了,我們只需要在最終解釋的查詢結果上做文章就可以了。簡單來說,就是將你的所有伺服器位址,按照自己需求制定的頻次,返回給使用者。
以github.com為例,我們首先擷取它的SOA伺服器(因為dns緩衝查詢服務器會緩衝結果,如果你直接去查詢網域名稱,會每次返回一樣的結果),.com的dns網域名稱伺服器也是13台,它們是[a-m].gtld-servers.net,我們隨便選一台來找找github.com的SOA
OK,我們擷取了四個SOA伺服器ns[1-4].p16.dynect.net,再隨便選一個來問問github.com對應的記錄吧,順便試幾次看看最終的ip地址會不會變化
我們這裡查詢了兩次,注意ANSWER SECTION部分返回了兩個結果,一次是192.30.252.129,一次是192.30.252.128。
這就是利用dns實現了負載平衡,你的最終訪問會到達不同的ip地址。
有哪些DNS服務商支援負載平衡呢?
這是一種比較進階的服務,一般網域名稱註冊商的dns伺服器不會支援,目前我已知支援它的服務商有
AWS Route 53
NSONE
Dyn
dnspod
其中1和4是我們已經在使用的,效果比較理想。
總結
其實DNS可以玩的花樣遠不止這些,還可以做容錯移轉,也可以按地區解析等等。網域名稱從互連網誕生之初就開始存在了,但是對它的研究以及衍生出來的使用方法才剛剛開始發掘,隨著大家對互連網利用的提升,這類技術肯定會越來越多。