JPS/JPS+ 尋路算法

目錄

  • 概念
    • 強迫鄰居(Forced Neighbour)
    • 跳點(Jump Point)
  • JPS 尋路算法(Jump Point Search)
    • 實現原理
    • 示例過程
  • JPS+(Jump Point Search Plus)
    • 預處理
    • 示例過程
  • 總結
  • 參考

概念

JPS(jump point search)算法實際上是對A* 尋路算法的一個改進,因此在閱讀本文之前需要先了解A*算法。A* 算法在擴展節點時會把節點所有鄰居都考慮進去,這樣openlist中點的數量會很多,搜索效率較慢。

若不了解A*算法,可以參考博主以前寫的一篇文章 A* 尋路算法 – KillerAery – 博客園

例如在無遮擋情況下(往往會有多條等價路徑),而我們希望起點到終點實際只取其中一條路徑,而該路徑外其它節點可以沒必要放入openlist(不希望加入沒必要的鄰居)。

其次我們還希望直線方向上中途的點不用放入openlist,如果只放入每段直線子路徑的起點和終點,那openlist又可以少放很多沒必要的節點:

可以看到 JPS 算法搜到的節點總是“跳躍性”的,這是因為這些關鍵性的節點都是需要改變行走方向的拐點,因此這也是 Jump Point 命名的來歷。

在介紹JPS等算法具體實現前,我們必須先掌握下面的概念。

強迫鄰居(Forced Neighbour)

強迫鄰居:節點 x 的8個鄰居中有障礙,且 x 的父節點 p 經過x 到達 n 的距離代價比不經過 x 到達的 n 的任意路徑的距離代價小,則稱 n 是 x 的強迫鄰居。

看定義也許十分晦澀難懂。直觀來說,實際就是因為前進方向(父節點到 x 節點的方向為前進方向)的某一邊的靠後位置有障礙物,因此想要到該邊靠前的空位有最短的路徑,就必須得經過過 x 節點。

可能的情況見圖示,黑色為障礙,紅圈即為強迫鄰居:

(左圖為直線方向情況下的強迫鄰居,右圖為斜方向情況下的強迫鄰居)

跳點(Jump Point)

跳點:當前點 x 滿足以下三個條件之一:

  • 節點 x 是起點/終點。
  • 節點 x 至少有一個強迫鄰居。
  • 如果父節點在斜方向(意味着這是斜向搜索),節點x的水平或垂直方向上有滿足條件a,b的點。

節點y的水平或垂直方向是斜向向量的拆解,比如向量d=(1,1),那麼水平方向則是(1,0),並不會往左搜索,只會看右邊,如果向量d=(-1,-1),那麼水平方向是(-1,0),只會搜索左邊,不看右邊,其他同理。

下圖舉個例子,由於黃色節點的父節點是在斜方向,其對應分解成向上和向右兩個方向,因為在右方向發現一個藍色跳點,因此黃色節點也應被判斷為跳點:

JPS 尋路算法(Jump Point Search)

實現原理

JPS 算法和A* 算法非常相似,步驟大概如下:

  1. openlist取一個權值最低的節點,然後開始搜索。(這些和A*是一樣的)
  2. 搜索時,先進行 直線搜索(4/8個方向,跳躍搜索),然後再 斜向搜索(4個方向,只搜索一步)。如果期間某個方向搜索到跳點或者碰到障礙(或邊界),則當前方向完成搜索,若有搜到跳點就添加進openlist。

跳躍搜索是指沿直線方向一直搜下去(可能會搜到很多格),直到搜到跳點或者障礙(邊界)。一開始從起點搜索,會有4個直線方向(上下左右),要是4個斜方向都前進了一步,此時直線方向會有8個。

  1. 若斜方向沒完成搜索,則斜方向前進一步,重複上述過程。

因為直線方向是跳躍式搜索,所以總是能完成搜索。

  1. 若所有方向已完成搜索,則認為當前節點搜索完畢,將當前節點移除於openlist,加入closelist。
  2. 重複取openlist權值最低節點搜索,直到openlist為空或者找到終點。

下面結合圖片更好說明過程2和3:首先我們從openlist取出綠色的節點,作為搜索的開始,先進行直線搜索,再斜向搜索,沒有找到任何跳點。

斜方向前進一步后,重複直線搜索和斜向搜索過程,仍沒發現跳點。

斜方向前進兩步后,重複直線搜索和斜向搜索過程,仍沒發現跳點。

斜方向前進了三步后(假設當前位置為 x),在水平直線搜索上發現了一個跳點(紫色節點為強迫鄰居)。

於是 x 也被判斷為跳點,添加進openlist。斜方向結束,綠色節點的搜索過程也就此結束,被移除於openlist,放入closelist。

示例過程

下面展示JPS算法更加完整的過程:
假設起點為綠色節點,終點為紅色節點

重複直線搜索和斜向搜索過程,斜方向前進了3步。在第3步判斷出黃色節點為跳點(依據是水平方向有其它跳點),將黃色跳點放入openlist,然後斜方向搜索完成,綠色節點移除於openlist,放入closelist。

對openlist下一個權值最低的節點(即黃色節點)開啟搜索,在直線方向上發現了藍色節點為跳點(依據是紫色節點為強迫鄰居),類似地,放入openlist。

由於斜方向還沒結束,繼續前進一步。最後一次直線搜索和斜向搜索都碰到了邊界,因此黃色節點搜索完成,移除於openlist,放入closelist。

對openlist下一個權值最低的節點(原為藍色節點,下圖變為黃色節點)開啟搜索,直線搜索碰到邊界,斜向搜索無果。斜方繼續前進一步,仍然直線搜索碰到邊界,斜向搜索無果。

由於斜方向還沒結束,繼續前進一步。

最終在直線方向上發現了紅色節點為跳點,因此藍色節點先被判斷為跳點,只添加藍色節點進openlist。斜方向完成,黃色節點搜索完成。

最後openlist取出的藍色節點開啟搜索,在水平方向上發現紅色節點,判斷為終點,算法完成。

回憶起跳點的第三個判斷條件(如果父節點在斜方向,節點x的水平或垂直方向上有滿足條件a,b的點),會發現這個條件判斷是最複雜的。在尋路過程中,它使尋路多次在水平節點上搜到跳點,也只能先添加它本身。其次,這也是算法中需要使用到遞歸的地方,是JPS算法性能瓶頸所在。

JPS+(Jump Point Search Plus)

JPS+ 本質上也是 JPS尋路,只是加上了預處理來改進,從而使尋路更加快速。

預處理

我們首先對地圖每個節點進行跳點判斷,找出所有主要跳點:

然後對每個節點進行跳點的直線可達性判斷,並記錄好跳點直線可達性:

若可達還需記錄號跳點直線距離:

類似地,我們對每個節點進行跳點斜向距離的記錄:

剩餘各個方向如果不可到達跳點的數據記為0或負數距離。如果在對應的方向上移動1步后碰到障礙(或邊界)則記為0,如果移動n+1步後會碰到障礙(或邊界)的數據記為負數距離-n

最後每個節點的8個方向都記錄完畢,我們便完成了JPS+的預處理過程:

以上預處理過程需要有一個數據結構存儲地圖上每個格子8個方向距離碰撞或跳點的距離。

示例過程

做好了地圖的預處理之後,我們就可以使用JPS+算法了。大致思路與JPS算法相同,不過這次有了預處理的數據,我們可以更快的進行直線搜索斜向搜索

在某個搜索方向上有:

  • 對於正數距離 n(意味着距離跳點 n 格),我們可以直接將n步遠的節點作為跳點添加進openlist
  • 對於0距離(意味着一步都不可移動),我們無需在該方向搜索;
  • 對於負數距離 -n(意味着距離邊界或障礙 n 格),我們直接將n步遠的節點進行一次跳點判斷(有可能滿足跳點的第三條件,不過得益於預處理的數據,這步也可以很快完成)。

如下圖示,起始節點通過已記錄的向上距離,直接將3步遠的跳點添加進openlist,而不再像以前需要迭代三步(還每步都要判斷是否跳點):

其它過程也是類似的:

總結

可以看到 JPS/JPS+ 算法里只有跳點才會被加入openlist里,排除了大量不必要的點,最後找出來的最短路徑也是由跳點組成。這也是 JPS/JPS+ 高效的主要原因。

JPS

  • 絕大部分地圖,使用 JPS 算法都會比 A* 算法更快,內存佔用也更小(openlist里節點少了很多)。
  • JPS 在跳點判斷上,要盡可能避免遞歸的深度過大(或者期待一下以後出現避免遞歸的算法),否則在超大型的地圖裡遞歸判斷跳點可能會造成災難。
  • JPS 也可以用於動態變化的地圖,只是每次地圖改變都需要再進行一次 JPS 搜索。
  • JPS 天生擁有合併節點(亦或者說是在一條直線里移除中間不必要節點)的功能,但是仍存在一些可以繼續合併的地方。
  • JPS 只適用於 網格(grid)節點類型,不支持 Navmesh 或者路徑點(Way Point)。

JPS+

  • JPS+ 相比 JPS 算法又是更快上一個檔次(特別是避免了過多層遞歸判斷跳點),內存佔用則是每個格子需要額外記錄8個方向的距離數據。
  • JPS+ 算法由於包含預處理過程,這讓它面對動態變化的地圖有天生的劣勢(幾乎是不可以接受動態地圖的),因此更適合用於靜態地圖。
  • JPS+ 預處理的複雜度為 \(O(n)\) ,n 代表地圖格子數。
算法 性能 內存佔用 支持動態地圖 預處理 支持節點類型
A* 中等 支持 網格、Navmesh、路徑點
JPS 偏小 支持 網格
JPS+ 非常快 中等 不支持 有,\(O(n)\) 網格

綜上,JPS/JPS+ 是A*算法的優秀替代者,絕大部分情況下更快和更小的內存佔用已經足夠誘人。在GDC 2015 關於 JPS+ 算法的演講中,Steve Rabin 給出的數據甚至是比A* 算法快70~350倍。

參考

[1] 從頭理解JPS尋路算法 – 簡書 by ElephantKing

[2] JPS+: Over 100x Faster than A* | GDC 2015

[3] JPS+ with GoalBounding C++實現,和上面GDC2015的演講人是同一個人 Steve Rabin。

[4] 一個在線可視化的JPS實現附說明 A Visual Explanation Of Jump Point Search

[5] JPS 算法原作者論文 github Harabor, Daniel Damir, and Alban Grastien. “Online Graph Pruning for Pathfinding On Grid Maps.” AAAI. 2011.

博主其它相關文章:
遊戲AI 系列文章 – KillerAery – 博客園
遊戲AI之路徑規劃 – KillerAery – 博客園

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

FB行銷專家,教你從零開始的技巧

02 . Ansible高級用法(運維開發篇)

自動化任務簡介

假設我們要在10台linux服務器上安裝一個nginx服務,手動是如何做的?

# 第一步, ssh登錄NUM(1,n)服務器
# 第二步,輸入對應服務器密碼
# 第三步,執行命令: yum install nginx 循環操作n=10
# 第四步,執行命令: service nginx start
# 第五步,退出登錄

自動化任務執行的意義

# 意義一, 提升運維工作效率,減少一份工作成本
# 意義二, 提高準確度.

自動化任務執行的應用

# 應用一, 批量命令執行
# 應用二, 定時程序任務執行
# 應用三, 批量程序應用服務安裝
# 應用四, 批量配置文件同步
# 應用五, 批量代碼部署

ansible配置

ansible是python中的一套模塊,系統中的一套自動化工具,可以用作系統管理,自動化命令等任務

ansible優勢
# 1.ansible是python中的一套完整的自動化執行任務模塊
# 2.ansible的play_book模式,不用yaml配置,對於自動化任務執行一目瞭然.
# 3.自動化場景支持豐富
ansible配置文件
1. inventory
# 該參數表示資源清單inventory文件的位置,資源清單就是一些Ansible需要連接管理的主機列表  
# inventory = /root/ansible/hosts

2. library
# Ansible的操作動作,無論是本地或遠程,都使用一小段代碼來執行,這小段代碼稱為模塊,這個library參數就是指向存放Ansible模塊的目錄  
# library = /usr/share/ansible

3. forks
# 設置默認情況下Ansible最多能有多少個進程同時工作,默認設置最多5個進程并行處理。具體需要設置多少個,可以根據控制主機的性能和被管理節點的數量來確定。  
# forks = 5

4. sudo_user
# 這是設置默認執行命令的用戶,也可以在playbook中重新設置這個參數
# sudo_user = root
# 注意: 新版本已經做了修改,如ansible2.4.1下已經為:
# default_sudo_user = root

5. remote_port
# 這是指定連接被關節點的管理端口,默認是22,除非設置了特殊的SSH端口,不然這個參數是不需要被修改的
# remote_port = 22

6. host_key_checking
# 這是設置是否檢查ssh主機的秘鑰,可以設置為True或者False
# host_key_checking = False

7. timeout
# 這是設置ssh連接的超時間隔,單位是秒
# timeout = 20

8. log_path
# ansible系統默認是不記錄日誌的,如果想把ansible系統的輸出記錄到指定地方,需要設置log_path來指定一個存儲Ansible日誌的文件

9. private_key_file
# 在使用ssh公鑰私鑰登錄系統時使用的秘鑰路徑
# private_key_file=/path/to/file.pem
ansible.cfg
[defaults]
inventory = /tmp/hosts
forks = 5
default_sudo_user = root
remote_port = 22
host_key_checking = Falsetimeout = 20
log_path = /var/log/ansible.log
#private_key_file=/tmp/file.pem

ansible安裝

# 1. 通過系統的方式,yum,apt,get等
# 2. 通過python的方式


# (推薦)python ./setup.py install 
easy_install ansible
pip install ansible	

Ansible基礎操作

當我們將Ansible安裝好以後,可以通過一些命令開始深入了解Ansible了.
我們最先展示的並非那強大的集配置,部署,自動化於一身的playbook.而是如何初始化.

遠程連接概述

在我們開始前要先理解Ansible如何通過SSH與遠程服務器連接是很重要的.
Ansible1.3及之後的版本默認會在本地的OpenSSH可用時會嘗試用其遠程通訊,這會啟用ControlPersist(一個性能特性),Kerberos,和在~/.ssh/config中的配置選項如 Jump Host setup.然而,當你使用Linux企業版6作為主控機(紅帽企業版及其衍生版如CentOS),其OpenSSH版本可能過於老舊無法支持ControIPersist,在這些操作系統中,Ansible將會退回並採用paramiko(由Python實現的高質量OpenSSH庫).如果你希望能夠使用像是Kerberized SSH之類的特性,煩請考慮使用Fedora,OS X,或Ubuntu作為你的主控機直到相關平台上有更新版本的OpenSSH可供使用,或者啟用Ansible的”accelerated mode”.

在Ansible1.2及之前的版本,默認將會使用paramiko,本地OpenSSH必須通過-c ssh或者配置文件中設定.

我們偶爾會遇到不支持SFTP的設備,雖然很少見,但有概率中獎,可以通過ansible配置文件切換至scp模式來與之連接.

說起遠程設備,Ansible會默認假定你使用SSH key(當然也推薦這種)但是密碼一樣可以,通過在需要的地方添加-ask-pass選項來啟用密碼驗證,如果使用了sudo特性,當sudo需要密碼時,也同樣適當的提供了-ask-sudo-pass選項.

也許這是常識,但也值得分享:任何管理系統受益於被管理的機器在主控機附近運行.如果在雲中運行,可以考慮在使用雲中的一台機器來運行Ansible.

作為一個進階話題,Ansible不止支持SSH來遠程連接.連接方式是插件化的而且還有許多本地化管理的選項諸如管理 chroot, lxc, 和 jail containers.一個叫做‘ansible-pull’的模式能夠反轉主控關係並使遠程系統通過定期從中央git目錄檢出 並 拉取 配置指令來實現背景連接通信

第一條命令(公鑰認證)

我們已經安裝ansible了,第一件事就是編輯或者創建/etc/ansible/hosts並在其中加入一個或多個遠程系統,我們的public SSH key必須在這些系統的authorized_keys中.

# 我們現在ansible控制機上主機名解析
tail /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
121.36.43.223	node1
120.77.248.31	node2
116.196.83.113	master

# 將解析過的主機名放到ansible配置文件裏面
tail -2 /etc/ansible/hosts 
node1
node2

# ansible控制機生成公鑰並傳給需要被控制的機器上
ssh-copy-id node1
ssh-copy-id node2
# 因為考慮到安全問題,會有主機秘鑰的檢查,但如果在內網非常信任的服務器就沒必要了.
sed -i 's/# *StrictHostKeyChecking *ask/StrictHostKeyChecking no/g' /etc/ssh/ssh_config

# 然後我們就可以執行第一條命令來查看能ping通控制的所有節點.
ansible all -m ping
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
node2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Ansible會像SSH那樣試圖用你的當前用戶名來連接你的遠程機器.要覆寫遠程用戶名,只需使用’-u’參數. 如果你想訪問 sudo模式,這裏也有標識(flags)來實現:

ansible all -m ping -u bruce

ansible all -m ping -u bruce --sudo

ansible all -m ping -u bruce --sudo --sudo-user batman

(如果你碰巧想要使用其他sudo的實現方式,你可以通過修改Ansible的配置文件來實現.也可以通過傳遞標識給sudo(如-H)來設置.) 現在對你的所有節點運行一個命令:

ansible all -a "/bin/echo hello"
node1 | CHANGED | rc=0 >>
hello

node2 | CHANGED | rc=0 >>
hello

公鑰認證

Ansible1.2.1及其之後的版本都會默認啟用公鑰認證

如果有個主機重新安裝並在“known_hosts”中有了不同的key,這會提示一個錯誤信息直到被糾正為止.在使用Ansible時,你可能不想遇到這樣的情況:如果有個主機沒有在“known_hosts”中被初始化將會導致在交互使用Ansible或定時執行Ansible時對key信息的確認提示.

如果你想禁用此項行為並明白其含義,你能夠通過編輯 /etc/ansible/ansible.cfg or ~/.ansible.cfg來實現:

[defaults]
host_key_checking = False

同樣注意在paramiko 模式中 公鑰認證 相當的慢.因此,當使用這項特性時,切換至’SSH’是推薦做法.

密碼認證

因為我們接下來要將存取的密碼放到主機清單甚至存到Mysql裏面,我們可以裝一個ssh_pass

apt-get install sshpass

我們將之前的公鑰.ssh目錄都刪掉,主機名解析不用管.

注意,刪除.ssh目錄過後記得關閉主機秘鑰檢查.

tail -3 /etc/hosts
121.36.43.223	node1
120.77.248.31	node2
116.196.83.113	master

tail -2  /etc/ansible/hosts 
node1
node2

ansible all -m ping -k
# 並不是真的ping,只是檢查客戶端的22號端口是否提供工作.不指定用戶默認root用戶
# -k 輸入密碼
# -m 指定模塊
SSH password: 
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
node2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
# 如果不想指定用戶名和密碼,避免ansible每次執行到相應主機都會要求輸入密碼.
tail -2 /etc/ansible/hosts 
node1 ansible_ssh_user='root' ansible_ssh_pass='youmen'
node2 ansible_ssh_user='root' ansible_ssh_pass='youmen'  ansible_ssh_port=22

ansible all -m ping
node1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
node2 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Ansible常用模塊

常用模塊

模塊名 作用 用例
command 默認模塊 ansible webserver -a “/sbin/reboot” -f 10
shell 執行shell命令 ansible test -m shell -a “echo $HOSTNAME”
filetransfer 文件傳輸 ansible test -m copy -a “src=/etc/hosts dest=/tmp/hosts”
managingpackages 管理軟件包 ansible test -m yum -a “name=nginx state=present”
user and groups 用戶和組 ansible test -m user -a “name=jeson password=123456”
Deploying 部署模塊 ansible test -m git -a “repo=https://github.com/iopsgroup/imoocc dest=/opt/iops version=HEAD”
managingservices 服務管理 ansible test -m service -a “name=nginx state=started”
BackgroundOperatiions 後台運行 ansible test -B 3600 -a “/usr/bin/running_operation –do-stuff”
gatheringfacts 搜集系統信息 ansible test -m setup

playbook

playbook由YAML語言編寫,YAML參考了其他多種語言,包括: XML,C語言,Python,Perl以及电子郵件格式RFC2822,Clark Evans在2001年5月首次發表了這種語言,另外Ingy dt Net與Oren-Kiki也是這語言的共同設計者.

playbook的優勢

# 1. 功能比adhoc更全
# 2. 控制好依賴
# 3. 展現更直觀
# 4. 持久使用

ansible-playbook執行常用命令參數:

執行方式:ansible-playbook playbook.yml [options]

 -u REMOTE_USER, --user=REMOTE_USER  
# ssh 連接的用戶名
 -k, --ask-pass    
# ssh登錄認證密碼
 -s, --sudo           
# sudo 到root用戶,相當於Linux系統下的sudo命令
 -U SUDO_USER, --sudo-user=SUDO_USER    
# sudo 到對應的用戶
 -K, --ask-sudo-pass     
# 用戶的密碼(—sudo時使用)
 -T TIMEOUT, --timeout=TIMEOUT 
# ssh 連接超時,默認 10 秒
 -C, --check      
# 指定該參數后,執行 playbook 文件不會真正去執行,而是模擬執行一遍,然後輸出本次執行會對遠程主機造成的修改

 -e EXTRA_VARS, --extra-vars=EXTRA_VARS    
# 設置額外的變量如:key=value 形式 或者 YAML or JSON,以空格分隔變量,或用多個-e

 -f FORKS, --forks=FORKS    
# 進程併發處理,默認 5
 -i INVENTORY, --inventory-file=INVENTORY   
# 指定 hosts 文件路徑,默認 default=/etc/ansible/hosts
 -l SUBSET, --limit=SUBSET    
# 指定一個 pattern,對- hosts:匹配到的主機再過濾一次
 --list-hosts  
# 只打印有哪些主機會執行這個 playbook 文件,不是實際執行該 playbook
 --list-tasks   
# 列出該 playbook 中會被執行的 task

 --private-key=PRIVATE_KEY_FILE   
# 私鑰路徑
 --step    
# 同一時間只執行一個 task,每個 task 執行前都會提示確認一遍
 --syntax-check  
# 只檢測 playbook 文件語法是否有問題,不會執行該 playbook 
 -t TAGS, --tags=TAGS   
# 當 play 和 task 的 tag 為該參數指定的值時才執行,多個 tag 以逗號分隔
 --skip-tags=SKIP_TAGS   
# 當 play 和 task 的 tag 不匹配該參數指定的值時,才執行
 -v, --verbose   
# 輸出更詳細的執行過程信息,-vvv可得到所有執行過程信息。
使用場景

yaml語法

  1. playbook配置
---
- hosts: 39.108.140.0
  remote_user: root
  vars:
   touch_file: youmen.file
  tasks:
  - name: touch file
    shell: "touch /tmp/{{touch_file}}"

yaml主要由三個部分組成:

> hosts部分:
# 使用hosts指示使用哪個主機或主機組來運行下面的tasks,
# 每個playbook都必須指定hosts,hosts也可以使用通配符格式。
# 主機或主機組在inventory清單中指定,可以使用系統默認的/etc/ansible/hosts,
# 也可以自己編輯,在運行的時候加上-i選項,指定清單的位置即可。
# 在運行清單文件的時候,--list-hosts選項會显示那些主機將會參与執行task的過程中。

> remote_user:指定遠端主機中的哪個用戶來登錄遠端系統,
# 在遠端系統執行task的用戶,可以任意指定,也可以使用sudo,
# 但是用戶必須要有執行相應task的權限。

> tasks:指定遠端主機將要執行的一系列動作。tasks的核心為ansible的模塊,
# 前面已經提到模塊的用法。tasks包含name和要執行的模塊,name是可選的,
# 只是為了便於用戶閱讀,不過還是建議加上去,模塊是必須的,同時也要給予模塊相應的參數。

執行

ansible-playbook -i /tmp/hosts --list-hosts ./f1.yaml
ansible-playbook ./f1.yaml

# 執行結果返回
# 紅色: 表示有task執行失敗或者提醒的信息
# 黃色: 表示執行了且改變了遠程主機狀態
# 綠色: 表示執行成功

yaml語法和數據結構

yaml語法

YAML格式是類似於JSON的文件格式,以便於人理解和閱讀,同時便於書寫,首先學習了解一下YAML的格式,對我們後面書寫playbook很有幫助.
以下為playbook常用到的YAML格式

# 大小寫敏感
# 使用縮緊表示層級關係(只能空格不能使用tab)
# yaml文件以"---"作為文檔的開始
# 在同一行中,#之後的內容表示註釋,類似於shell,python和ruby.
# YAML中的列表元素以"-"開頭,然後緊跟着一個空格,後面為元素內容,就像這樣
- apple
- orange
等價於JSON的這種格式
[
 "apple",
 "orange"
]

# 同一個列表中的元素應該保持相同的縮進,否則會被當做錯誤處理.
# play中hosts,variables,roles,tasks等對象的表示方法都是鍵值中間以":"分割表示,":"後面還要增加一個空格.
變量定義方式

變量名可以為字母,数字以及下劃線

playbook里的變量

 1. playbook的yaml文件中定義變量賦值
> 2. --exxtra-vars執行參數賦給變量
> 3. 在文件中定義變量
> 4. 註冊變量
# register關鍵字可以存儲指定命令的輸出結果到一個自定義的變量中.
---
- hosts: database
  remote_user: root
  vars:
    touch_file: youmen_file
  tasks:
    - name: get date
      command: date
      register: date_output
    - name: touch
      shell: "touch /tmp/{{touch_file}}"
    - name: echo  date_output
      shell: "echo {{date_output.stdout}}>/tmp/{{touch_file}}"
數據結構

yaml支持的數據結構
字典

{name:jeson}

列表

- Apple
- Mango
- Orange

純量: 数字,布爾,字符串

條件判斷
循環
循環類型 關鍵字
標準循環 with_items
嵌套循環 with_nested
遍歷字典 with_dict
并行遍歷列表 with_together
遍歷列表和索引 with_indexed_items
遍歷文件列表的內容 with_file
遍歷目錄文件 with_fileglog
重試循環 until
查找第一個匹配文件 with_first_found
隨機選擇 with_random_choice
在序列中循環 with_sequence

條件循環語句復用

種類一, 標準循環

---
- hosts: nginx
  tasks:
  - name: add serveral users
    user: name={{ item.name }} state=present groups={{ item.groups }}
    with_items:
      - { name: 'testuser1',groups: 'wheel' }
      - { name: 'testuser2',groups: 'root'  }

種類二, 遍歷字典

---
- hosts: nginx
  remote_user: root
  tasks:
    - name: add serveral users
      user: name={{ item.key }} state=present groups={{ item.value }}
      with_dict:
        { 'testuser3':'wheel','testuser4':'root' }

種類三, 遍歷目錄中內容

---
- hosts: nginx
  remote_user: root
  tasks:
   - file: dest=/tmp/aa state=directory
   - copy: src={{ item }} dest=/tmp/bb owner=root mode=600
     with_fileglob:
       - aa/*n
條件語句結合循環語句使用場景
---
- hosts: nginx
  remote_user: root
  tasks:
    - debug: msg="{{ item.key }} is the winner"
      with_dict: {'jeson':{'english':60,'chinese':30},'tom':{'english':20,'chinese':30}}
      when: item.value.english >= 10
異常

異常處理和相關操作

異常處理

1.忽略錯誤

默認會檢查命令和模塊的返回狀態,遇到錯誤就中斷playbook的執行
加入參數: ignore_errors: yes
Example

- hosts: nginx
  remote_user: root
  tasks:
    - name: ignore false
      command: /bin/false
      ignore_errors: yes
    - name: touch a file
      file: path=/tmp/test22 state=touch mode=0700 owner=root group=root

2. tags標籤處理

---
- hosts: nginx
  remote_user: root
  tasks:
    - name: get process
      shell: touch /tmp/change_test2
      changed_when: false

打標籤

意義: 通過tags和任務對象進行捆綁,控制部分或者指定的task執行

# 打標籤
# 	對一個對象打一個標籤
# 	對一個對象打多個標籤
# 	打標籤的對象包括: 單個task任務,include對象,roles對象等.

標籤使用

-t : 執行指定的tag標籤任務
--skip-tags: 執行 --skip-tags之外的標籤任務
  1. 自定義change狀態
---
- hosts: nginx
  remote_user: root
  tasks:
    - name: get process
      shell: ps -ef |wc -l
      register: process_count
      failed_when: process_count > 3
    - name: touch a file
      file: path=/tmp/test1 state=touch mode=0700 owner=root group=root
roles角色和場景演練

使用roles角色
include的用法

include_tasks/include: 動態的包含tasks任務列表執行

什麼是roles

是一種利用在大型playbook中的劇本配置模式,在這自己特定結構

為什麼需要用到roles

和面向對象開發思想相似
利用於大型的項目任務中,盡可能的將公共的任務,變量等內容獨立

劇本結構和設計思路
ansible官方網站的建議playbook劇本結構如下:

production        # 正式環境的inventory文件
staging           #測試環境用得inventory文件
group_vars/  	  # 機器組的變量文件
      group1        
      group2
host_vars/   	 #執行機器成員的變量
      hostname1     
      hostname2
================================================
site.yml               # 主要的playbook劇本
webservers.yml         # webserver類型服務所用的劇本
dbservers.yml          # 數據庫類型的服務所用的劇本

roles/
      webservers/        #webservers這個角色相關任務和自定義變量
           tasks/
               main.yml
           handlers/
               main.yml
           vars/            
                main.yml
        dbservers/         #dbservers這個角色相關任務和定義變量
            ...
      common/       	  # 公共的
           tasks/        
                main.yml    
           handlers/    
                main.yml    # handlers file.
           vars/            # 角色所用到的變量
                main.yml    # 
===============================================
      templates/    #
            ntp.conf.j2 # 模版文件
      files/        #   用於上傳存放文件的目錄
            bar.txt     
            foo.sh     
      meta/         # 角色的依賴
            main.yml   
場景演練

Nginx工程方式的編譯安裝

# 劇本分解
ansible.cfg
  - files		#	存放上傳文件
    - index.html
    - nginx    # 系統init中,控制nginx啟動腳本
    - nginx-1.12.2.tar.gz  # nginx的安裝包文件

production	  # 線上的主機配置文件
roles		  # roles角色執行
  - apache
  - common
     tasks
       main.yml
     vars
	main.yml
    meta
    nginx
      - handlers   通過notify觸發
        main.yml
      - tasks
	  - basic.yml
	  - main.yml
	 - nginx.yml
      - vars
	= main.yml
    tasks

staging			線下測試環境使用的主機配置文件
  - templates		模板(配置,html)
    - nginx1.conf	nginx的自定義conf文件
webserver.yaml		web服務相關主執行文件

Ansible的核心類介紹

核心類 用途 所在的模塊路徑
DataLoader 用於讀取yaml,json格式的文件 ansible.parsing.dataloader
Play 存儲執行hosts的角色信息 ansible.playbook.play
TaskQueueManager ansible底層用到的任務隊列 ansible.executor.task_queue_manager
PlaybookExecutor 核心累執行playbook劇本 ansible.executor.playbook_executor
CallbackBase 狀態回調,各種成功失敗的狀態 ansible.plugins.callback
InventoryManager 用於導入inventory文件 ansible.inventory.manager
VariableManager 用於存儲各類變量信息 ansible.vars.manager
Host,Group 用於操作單個主機或者主機組信息 ansible.inventory.host
InventoryManager

用來管理主機和主機組信息

from ansible.parsing.dataloader import DataLoader
from ansible.inventory.manager import InventoryManager

# InventoryManager類
loader = DataLoader()
InventoryManager(loader=loader,sources=['youmen_hosts'])

# 1. 添加主機到指定主機組 add_host()  
# 2. 查看主機組資源get_groups_dict()  
# 3. 獲取指定的主機對象get_host()

# VariableManager類
# loader: 實例對象
# inventory: 調用InventoryManager返回的實例對象.
VariableManager(loader=loader,inventory=inventory)

# 查看主機變量方法 get_vars()
# 設置主機變量方法set_host_variable()
# 添加擴展變量extra_vars
ad-hoc模式調用場景

ansible -m command -a "ls /tmp" testgroup -i /etc/ansible/hosts -f 5

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

印度學者:中國築壩正破壞喜馬拉雅生態

摘錄自2018年8月27日中央社報導

印度新德里政策研究中心戰略研究教授切拉尼(Brahma Chellaney)表示,喜馬拉雅生態系統日漸脆弱,雖然在這一地區大規模資源濫採的國家都應受到譴責,「但沒有一個國家像中國,對喜馬拉雅造成如此嚴重的破壞」。

切拉尼撰文寫道,亞洲的未來與喜馬拉雅山的關係緊密,但人類卻大規模建設水壩且肆無忌憚地開採資源,破壞當地生態系統,其中中國透過築壩改造天然河流,卻有愈來愈多工程引水項目集中在國外,而非內部河流。以喜馬拉雅冰川地區來說,目前中國造壩已覆蓋近3/4的青藏高原。

針對中國行徑,切拉尼還指出2點,一是中國想在青藏高原乾旱的北部和西北部製造人造雨,外界擔心此舉會吸走喜馬拉雅其他地區(西藏的降雨集中地)的水分;另一是中國大肆開發礦產資源,如開發銅礦的行動已汙染藏族的Pemako(隱藏的蓮花地)地區。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

載不動聖誕老人 瑞典夏季乾旱 部分馴鹿餓死

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

※推薦評價好的iphone維修中心

考量經濟 梅克爾反對歐盟拉高減碳目標

摘錄自2018年8月27日中央社報導

德國總理梅克爾今天(27日)表示,世界各地極端天候頻傳,充分證明氣候變遷已是事實。不過她反對為保護氣候拉高減少溫室氣體排放門檻,指此舉沒太大意義。

路透社報導,北半球今夏的炙熱高溫,引發外界憂心氣候變遷的現象正加速發生,歐洲數十個國家都呼籲,減少溫室氣體排放量的速度,應要比原訂目標更快。

歐洲聯盟(EU)執委會主管氣候行動與能源事務執委卡尼特(Miguel Arias Canete)呼籲將2030年之前溫室氣體減量目標,從40%提高至45%。

但梅克爾(Angela Merkel)表示,加速減少有害的二氧化碳排放量恐適得其反,況且歐洲各國此際對達成原訂目標都很吃力,再要拉高門檻沒有道理。

她說:「我對這些新提議尤其不怎麼高興。我認為應先堅守既定目標。我不認為一直設定新目標有任何意義。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

德鐵挑戰氣候目標 2030年減碳50%、使用70%綠電

環境資訊中心記者 陳文姿報導

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

世界水資源週上談淹水 WWF:自由流動的河很重要

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

大力發展再生能源,希臘渡假勝地蒂洛斯將成地中海首座綠能島

摘錄自2018年8月21日科技新報報導

希臘小島蒂洛斯(Tilos)可說是愛琴海著名渡假勝地,擁有豐富環境生態與優美的海洋景致,而近期該島將透過裝置量達 200KW 太陽光電與 800KW 風能,進一步成為地中海首座 100% 再生能源供電的綠能島嶼。

蒂洛斯島希望能透過綠能達成電力自給自足。目前技術人員則正最終測試再生能源系統,預計將在 2018 年下旬全面上路,屆時該渡假小島將可透過裝置量達 200KW 太陽能、800KW 風力發電與儲存容量(storage capacity)為 2.4MWh 的儲能系統達到 100% 綠能供電。

該島將採用 NaNiCl2 熔鹽儲能系統,可在日照強和風大情況下儲存綠能多餘電力,並於夜間與旅遊旺季等需求量大、發電量較低時釋出電力並維持電網供電,而為提升微電網管理系統,住家與企業也會安裝智慧電錶來計算用電尖峰的時間。

歐盟執行執委會表示,蒂洛斯將成為地中海第一個電力自主的再生能源島嶼,且由於大多海島都難以跟歐洲大陸電網相連,歐盟也打算將蒂洛斯再生能源計畫應用於其他島嶼。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

法英漁船 英吉利海峽爆發大規模衝突

摘錄自2018年8月29日中廣新聞報導

法國和英國漁民為了扇貝捕撈,累積已久的怨恨,瞬間爆發,總共幾十艘漁船,在英吉利海峽上,先是叫罵,丟擲物品,接著彼此衝撞,英國漁船因為數量不敵法國,落荒而逃。英國漁民現在要求政府派軍艦護漁。

英國與法國漁民在英吉利海峽因為扇貝捕撈,引發衝突,導致關係緊張,由來已久,五年前,雙方達成協議,英國同意不使用大型漁船作業,來換取更多的漁權。不過法國有休漁政策,英國沒有,法國漁船每年5月中到10月不能捕撈,英國漁船則全年都可以作業,法國漁民覺得不公平,更讓他們火大的是,英國捕獲的扇貝,大約三分之一出口,其中多數銷到法國。 

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

對馬克宏很失望 法環境部長請辭 「不想再騙自己」

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

FB行銷專家,教你從零開始的技巧