消息隊列
消息隊列作用
1.程序解耦
允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。
2.冗餘:
消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據丟失風險。
許多消息隊列所採用的"插入-獲取-刪除"範式中,在把一個消息從隊列中刪除之前,需要你的處理系統明確的指出該消息已經被處理完畢,從而確保你的數據被安全的保存直到你使用完畢。
3.峯值處理能力:
在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量並不常見。如果爲以能處理這類峯值訪問爲標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因爲突發的超負荷的請求而完全崩潰。
4.可恢復性:
消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復後被處理。
5.順序保證:
大部分消息隊列本來就是排序的,並且能保證數據會按照特定的順序來處理。(Kafka保證一個Partition內的消息的有序性)
6.緩衝:
有助於控制和優化數據流經過系統的速度,解決生產消息和消費消息的處理速度不一致的情況。
7.異步通信:
消息隊列提供了異步處理機制,允許用戶把一個消息放入隊列,但並不立即處理它。想向隊列中放入多少消息就放多少,然後在需要的時候再去處理它們。
消息隊列產品
RabbitMQ:
Erlang編寫的消息隊列產品,企業級消息隊列軟件,支持消息負載均衡,數據持久化等。
ZeroMQ :
saltstack軟件使用此消息,速度最快。
Redis:
key-value的系統,也支持隊列數據結構,輕量級消息隊列
Kafka:
由Scala編寫,目標是爲處理實時數據提供一個統一、高通量、低等待的平臺
rabbitMQ
安裝rabbitMQ
1.安裝rabbitMQ:
yum -y install erlang rabbitmq-server
2.啓動rabbitmq服務端
systemctl start rabbitmq-server
3.開啓rabbitmq的管理後臺頁面
rabbitmq-plugins enable rabbitmq_management
5.創建rabbitmq的後臺管理用戶
rabbitmqctl add_user 用戶名 密碼
6.設置用戶管理員身份
rabbitmqctl set_user_tags 用戶名 administrator
7.爲用戶設置讀寫所有隊列權限
rabbitmqctl set_permissions -p "/" 用戶名 ".*" ".*" ".*"
8.重啓服務端
systemctl restart rabbitmq-server
9.查看端口
netstat -tunlp
tcp 0 0 0.0.0.0:15672 0.0.0.0:* LISTEN 16762/beam
python操作rabbitMQ
1.安裝pika模塊
pip3 instlal pika==0.11.1
2.編寫生產者
import pika
credentials = pika.PlainCredentials("用戶名","密碼")
# 創建憑證,使用rabbitmq用戶密碼登錄
#connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
# 無密碼登錄
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',credentials=credentials))
# 新建連接,這裏localhost可以更換爲服務器ip
channel = connection.channel()
# 創建頻道
channel.queue_declare(queue='q1')
# 聲明一個隊列,用於接收消息,隊列名字叫“q1”
channel.basic_publish(exchange='',
routing_key='q1',
body='q1數據')
# 注意在rabbitmq中,消息想要發送給隊列,必須經過交換(exchange),可以使用空字符串交換(exchange=''),它允許我們精確的指定發送給哪個隊列(routing_key=''),參數body值發送的數據
connection.close()
# 程序退出前,確保刷新網絡緩衝以及消息發送給rabbitmq,需要關閉本次連接
3.編寫消費者
import pika
credentials = pika.PlainCredentials("用戶名","密碼")
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',credentials=credentials))
channel = connection.channel()
channel.queue_declare(queue="q1")
# 建立與rabbitmq的連接
def callbak(ch,method,properties,body):
print("消費者取出了消息:%r"%body.decode("utf8"))
channel.basic_consume(callbak,queue="q1",no_ack=True)
# 有消息來臨,立即執行callbak,沒有消息則夯住,等待消息
# no_ack 無需確認
channel.start_consuming()
# 開始消費,接收消息
ack機制
ACK機制用於保證消費者如果拿了隊列的消息,客戶端處理時出錯了,那麼隊列中仍然還存在這個消息,提供下一位消費者繼續取。
在消費者中no_ack=True時,數據消費後如果出錯就會丟失
當no_ack=False時,數據消費如果出錯,數據也不會丟失
演示
編寫消費者
import pika
credentials = pika.PlainCredentials("用戶名","密碼")
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',credentials=credentials))
channel = connection.channel()
# 聲明一個隊列(創建一個隊列)
channel.queue_declare(queue='q1')
def callback(ch, method, properties, body):
print("消費者接受到了任務: %r" % body.decode("utf-8"))
#int('abc')
ch.basic_ack(delivery_tag=method.delivery_tag)
# 回覆服務端消息確認
channel.basic_consume(callback,queue='金品沒',no_ack=False) #no_ack=False 禁止不確認機制,代表需要給與服務端消息確認回覆
channel.start_consuming()
消息持久化
消息的可靠性是RabbitMQ的一大特色,那麼RabbitMQ是如何保證消息可靠性的呢——消息持久化。 爲了保證RabbitMQ在退出或者crash等異常情況下數據沒有丟失,需要將queue,exchange和Message都持久化。
編寫生產者:
import pika
credentials = pika.PlainCredentials("xiaohu","xiaohu666")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.85',credentials=credentials))
channel = connection.channel()
'''
實現rabbitmq持久化條件
delivery_mode=2
使用durable=True聲明queue是持久化
'''
channel.queue_declare(queue='q1',durable=True) #此步表示隊列是支持持久化的參數
channel.basic_publish(exchange='',
routing_key='q1',
body='q1數據',
# 支持數據持久化:
properties=pika.BasicProperties(
delivery_mode=2,
)
)
connection.close()
RPC之遠程過程調用
將一個函數運行在遠程計算機上並且等待獲取那裏的結果,這個稱作遠程過程調用(Remote Procedure Call)或者 RPC。RPC是一個計算機通信協議。它封裝了數據的序列化,反序列化,以及傳輸協議
python實現RPC
通過python的xmlrpc庫實現
def respon_string(str):
return "得到了字符串:%s"%str
if __name__ == '__main__':
server = SimpleXMLRPCServer(('localhost', 8888)) # 初始化
server.register_function(respon_string, "get_string") # 註冊函數
server.serve_forever() # 保持等待調用狀態
from xmlrpc.client import ServerProxy
if __name__ == '__main__':
server = ServerProxy("http://localhost:8888") # 初始化服務器
print (server.get_string("發送的數據1")) # 調用函數並傳參
saltstack
saltstack是由thomas Hatch於2011年創建的一個開源項目,設計初衷是爲了實現一個快速的遠程執行系統。
Salt是python編寫的,支持用戶通過python自定義功能模塊,也提供了大量的python API接口,用戶可以根據需要進行簡單快速的擴展。
salt部署基本架構
在安裝salt之前,先理解salt架構中各個角色,主要區分是salt-master和salt-minion,顧名思義master是中心控制系統,minion是被管理的客戶端。
使用saltstack
1.環境準備
服務器1:ip地址192.168.178.11,身份master
服務器2:ip地址192.168.178.12,身份slave
修改2臺機器的主機名,用於主機名通信,加速salt的命令執行
master :
hostnamectl set-hostname master
minion :
hostnamectl set-hostname minion
關閉2臺機器的iptables防火牆策略,防止端口拒絕
iptables -F #清空防火牆規則
systemctl stop firewalld #關閉防火強服務
systemctl disable firewalld #禁止防火牆開機自啓
2.安裝
master:
yum install salt-master -y
minion:
yum install salt-minion -y
3.配置/etc/hosts文件用於主機名通信
master:
192.168.178.12 master
minion:
192.168.178.11 minion
4.修改salt的master和minion的配置文件
修改master的/etc/salt/master文件如下
interface: 0.0.0.0
publish_port: 4505
user: root
worker_threads: 5
ret_port: 4506
修改minion的/etc/salt/master文件如下
master: master
master_port: 4506
user: root
id: minion1
5.分別啓動salt-master和salt-minion
master:
systemctl start salt-master
minion:
systemctl start salt-minion
6.查看密鑰是否被讀取到
master:
salt-key -L
7.檢查2臺機器的密鑰信息,是否一致
master:
salt-key -f minion1
minion:
salt-call --local key.finger
8.接收minion1的密鑰並準備接管
salt-key -a minion1
9.測試服務器是否存活
salt '*' test.ping
密鑰管理命令
只有Master接受了Minion Key後,才能進行管理。具體的認證命令爲salt-key常用的有如下命令。
salt-key 參數
-L #查看KEY狀態
Accepted Keys: #已經接受的key
Denied Keys: #拒絕的key
Unaccepted Keys:#未加入的key
Rejected Keys: #吊銷的key
-A #允許所有
-D #刪除所有
-a #認證指定的key
-d #刪除指定的key
-r #註銷掉指定key(該狀態爲未被認證)
salt命令接口
salt '*' cmd.run "touch /opt/new_file.txt"
# 指定所有接管機器
salt 'minion1 ' cmd.run "touch /opt/new_file.txt"
# 單獨指定某一臺機器
salt提供的軟件安裝模塊
#其實是在遠程調用yum命令
salt '*' pkg.install "nginx" # 安裝
salt '*' pkg.remove "nginx"、# 卸載
salt '*' pkg.version "nginx" # 查看版本信息
salt提供的服務信息模塊
# 其實鎖在遠程調用systemctl命令
salt '*' service.start "redis"
salt '*' service.status "redis"
採集服務器靜態信息-grains模塊
salt '*' grains.items
# 所有資源信息
salt '*' grains.item fqdn_ip4
# 指定資源信息
輸出格式
輸出json格式的數據
salt '*' service.status "redis" --out=json
輸出yaml格式的數據
salt '*' cmd.run_all 'hostname' --out=yaml
yaml語法
yaml容易被解析,應用於配置文件
語法規則
大小寫敏感
使用縮進表示層級關係
縮進時禁止tab鍵,只能空格
縮進的空格數不重要,相同層級的元素左側對其即可
# 表示註釋行
yaml支持的數據結構
對象: 鍵值對,也稱作映射 mapping 哈希hashes 字典 dict 冒號表示 key: value
數組: 一組按次序排列的值,又稱爲序列sequence 列表list 短橫線 - list1
純量: 單個不可再分的值
python語法對比yaml
python
{ v1:
{ v2:
[ 3, 4 ],
v3:
[ 'a', 'b' ]
}
}
yaml
v1:
v2:
- 3
- 4
v3:
- a
- b
python操作saltstack
import salt.client
local=salt.client.LocalClient()
local.cmd('minion1','cmd.run',['ifconfig'])