① 在linux下安裝rabbitmq失敗怎麼解決
RabbitMQ 是由 LShift 提供的一個 Advanced Message Queuing Protocol (AMQP) 的開源實現,由以高性能、健壯以及可伸縮性出名的 Erlang 寫成,因此也是繼承了這些優點。
AMQP 里主要要說兩個組件:Exchange 和 Queue (在 AMQP 1.0 里還會有變動),如下圖所示,綠色的 X 就是 Exchange ,紅色的是 Queue ,這兩者都在 Server 端,又稱作 Broker ,這部分是 RabbitMQ 實現的,而藍色的則是客戶端,通常有 Procer 和 Consumer 兩種類型:
1:mq的安裝需要Erlang,所以首先下載Erlang,下載地址:http://www.erlang.org/download.html直接下載源碼,編譯安裝即可。
將下載好的tar包解壓編譯安裝,如下命令:
tar -zxvf otp_src_R16B03-1.tar.gz
cd otp_src_R16B03-1
./configure && make install
安裝過程中可能出現如下錯誤:
configure:error:
No curses library functions found
configure: error:/bin/sh'/home/niewf/software/erlang_R13B01/erts/configure'
failed for erts
解決方法:
yum list|grep ncurses
yum -y install ncurses-devel
yum install ncurses-devel
或者直接下載ncurses包編譯安裝。
下載地址:http://download.chinaunix.net/download/0008000/7242.shtml
tar zxvf ncurses.tar.gz #解壓縮並且釋放 文件包
cd ncurses #進入解壓縮的目錄(注意版本)
./configure #按照你的系統環境製作安裝配置文件
make #編譯源代碼並且編譯NCURSES庫
su root #切換到root用戶環境
make install #安裝編譯好的NCURSES庫
完成後繼續返回上一步操作。
2:安裝python,如果系統中python版本低於2.5的話需要升級python到2.6以上,具體可參考:http://gavinshaw.blog.51cto.com/385947/610585
3:安裝simplejson,直接下載simplejson源碼包編譯安裝即可,下載地址:https://pypi.python.org/pypi/simplejson/。
下載simplejson源碼包後,運行python setup.py install即可完成安裝。
4:安裝rabbit mq,下載地址:https://www.rabbitmq.com/install-generic-unix.html
下載後放入相應目錄解壓,進入%RABBITMQ_HOME%/sbin目錄下運行:./rabbitmq-server start即可啟動mq。
如果遇到如下錯誤,則參考http://leeon.me/a/rabbitmq-start-fail-note解決方案
ERROR: epmd error for host "xxx": address (cannot connect to host/port)
到此mq已經安裝完成。
在%RABBITMQ_HOME%/sbin目錄運行./rabbitmqctl status可查看當前mq狀態。
同時mq也提供了界面查看當前mq狀態,但是需要啟用該插件功能,運行如下命令:
rabbitmq-plugins enable rabbitmq_management,然後在瀏覽器中輸入:http://host-name:15672/#/即可訪問,頁面結果如下:
② 程序員應知應會之自動化運維那些事兒
對於一個開發人員來講,可能運維並不是自己的職責所在。但是作為一名開發人員,卻不能不了解自動化運維的整個流程。因為對於一個信息系統而言,開發和運維本質是一體的,尤其對於一些小公司來講,可能運維人員本身就是開發人員抽空兼任的。
而自動化運維,本質上是介於開發和運維之間的,是運維和開發的交集,甚至很多時候都要寫不少代碼。因此,任何一個開發人員,都需要有自動化運維的相關知識。
一個了解好的開發人員,即使自己不做運維相關的工作,也能夠知道自己在將項目交付給運維人員的時候,哪些東西是重要的,那些是必須配置的等等。然而在實際工作中,往往開發人員會給運維人員留下一些坑,一些只有他自己知道,而運維人員不知道的東西。導致運維人員自己試了很多次發現不行的時候,找到開發人員,開發人員研究了一下才會告訴他,在某某環境中必須用哪個埠之類的。這樣不僅白白浪費了運維人員的時間,也增加了很多溝通的工作量。
反過來也是如此,一些現場的問題如果運維人員不能現場給出問題的定位。對於開發人員來講是非常難以復現的。比如之前有某家企業,運維人員在客戶現場發現問題。費了很大力氣從客氣的內網裡面把日誌導出來,發給開發人員,結果開發人員仔細研究了日誌之後,發現是網不通的問題。開發人員顯然是不可能知道為啥網不通的,搞不好是壓根沒連網線。
所以今天我們來聊一聊,對於一個程序員來講,需要了解的自動化運維的那些事。
一、自動化運維的概念
隨著信息時代的持續發展,初期的幾台伺服器已經發展成為了龐大的數據中心,單靠人工已經無法滿足在技術、業務、管理等方面的要求。一個運維人員手工配置幾台伺服器還可能。配置幾百上千台伺服器那就累死了,還容易出錯。那麼就需要對運維工作進行標准化、自動化、架構優化、過程優化等。從面降低運維服務成本。其中,自動化最開始作為代替人工操作為出發點的訴求被廣泛研究和應用。
所謂自 動化運維,即在最少的人工干預下,結合運用腳本與第三方工具,保證業務系統7*24小時高效穩定運行 。這是所有業務系統運維的終極目標。
按照運維的發展成熟度來看, 運維大致可分為三個階段 :
(1)依靠純手工,重復地進行軟體的部署與運維;
(2)通過編寫腳本,方便地進行軟體的部署與運維;
(3)藉助第三方工具,高效地進行軟體的部署與運維;
二、自動化運維需要解決的問題
自動化運維通常來講,需要解決以下幾個問題: 自動部署配置、風險事前預警、故障事中解決、和故障事後管理 。
三、自動化運維的常用工具
自動化運維常用的工具包括以下幾種:
1、Ansible
ansible是基於Python開發的自動化運維工具,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。
ansible具有如下一些特性:
(1)模塊化:調用特定的模塊,完成特殊的任務。
(2)Paramiko(python對ssh的實現),PyYaml,jinja2(模塊語言)三個關鍵模塊。
(3)支持自定義模塊,可使用任何編程語言寫模塊。
(4)基於python語言實現。
(5)部署簡單,基於python和SSH(默認已安裝),agentless,無需代理不依賴KPI(無需SSL)。
(6)安全,基於OpenSSH
(7)冪等性:一個任務執行一次和執行n遍效果一樣,不因重復執行帶來意外情況。
(8)支持playbook編排任務,YAML格式,編排任務,支持豐富的數據結構。
(9)較強大的多層解決方案role。
2、Chef
Chef是一個功能強大的自動化工具,可以部署,修復和更新以及管理伺服器和應用程序到任何環境。
Chef 主要分為三個部分 Chef Server、Workstation 以及 Chef Client。用戶在 Workstation 上編寫 Cookbook。然後,通過 knife 命令上傳到 Chef Server。最後,在 Chef Client 上面實施安裝和部署工作。所以,對於 Cookbook 地編寫在整個自動化部署中起到了重要的作用。
Chef Server 包含所有配置數據,並存儲描述Chef-Client中每個Nodes的Recipe,Cookbook和元數據。配置詳細信息通過Chef-Client提供給Nodes。所做的任何更改都必須通過Chef Server進行部署。在推送更改之前,它通過使用授權密鑰來驗證Nodes和Workstations是否與伺服器配對,然後允許Workstations和Nodes之間進行通信。
Workstations 用於與Chef-server進行交互,還用於與Chef-nodes進行交互。它還用於創建Cookbook。Workstations是所有交互發生的地方,在這里創建,測試和部署Cookbook,並在Workstations中測試代碼。
Chef命令行工具 是創建,測試和部署Cookbook的地方,並通過此策略將其上載到Chef Server。
Knife 用於與ChefNodes進行交互。
Test Kitchen 用於驗證Chef代碼
Chef-Repo 是一個通過Chef命令行工具在其中創建,測試和維護Cookbook的存儲庫。
Nodes 由Chef管理,每個Nodes通過在其上安裝Chef-Client進行配置。 ChefNodes 是一台機器,例如物理雲,雲主機等。
Chef-Client 負責注冊和認證Nodes,構建Nodes對象以及配置Nodes。Chef-Client在每個Nodes上本地運行以配置該Nodes。
Cookbook 是Chef 框架的重要基礎功能之一。在 Chef Server 對目標機器做安裝部署的時候,是通過 Runlist。而 Runlist 裡面又包含了一個一個具體的 Cookbook,所以,最終對一個目標機器的部署任務就落到了 Cookbook 上。而對於 Cookbook 來說,其中包含了多個組件,我們可以將 Cookbook 簡單地理解成一個容器或者可以理解為一個包,裡麵包含了 recipes、files、templates、libraries、metadata 等信息。這些信息用於配置我們的目標機器。
3、Puppet
puppet是一種Linux、Unix平台的集中配置管理系統,所謂配置管理系統,就是管理其裡面諸如文件、用戶、進程、軟體包等資源。它可以運行在一台伺服器端,每個客戶端通過SSL證書連接到服務端,得到本機器的配置列表,然後根據列表來完成配置工作,所以如果硬體性能比較高,維護管理上千上萬台機器是非常輕松的,前提是客戶端的配置、伺服器路徑、軟體需要保持一致。
客戶端Puppet會調用本地facter,facter探測出該主機的常用變數,例如主機名、內存大小、IP地址等。然後Puppetd把這些信息發送到Puppet服務端;
Puppet服務端檢測到客戶端的主機名,然後會檢測manifest中對應的node配置,並對這段內容進行解析,facter發送過來的信息可以作為變數進行處理;
Puppet伺服器匹配Puppet客戶端相關聯的代碼才能進行解析,其他的代碼不解析,解析分為幾個過程,首先是語法檢查,然後會生成一個中間的偽代碼,之後再把偽代碼發給Puppet客戶端;
Puppet客戶端接收到偽代碼之後就會執行,執行完後會將執行的結果發送給Puppet伺服器;
Puppet服務端再把客戶端的執行結果寫入日誌。
4、Saltstack
SaltStack是基於python開發的一套C/S自動化運維工具。部署輕松,擴展性好,很容易管理上萬台伺服器,速度夠快。與伺服器之間的交流,以毫秒為單位。SaltStack提供了一個動態基礎設施通信匯流排用於編排,遠程執行、配置管理等等。它的底層使用ZeroMQ消息隊列pub/sub方式通信,使用SSL證書簽發的方式進行認證管理,傳輸採用AES加密。
在saltstack架構中伺服器端叫Master,客戶端叫Minion。
在Master和Minion端都是以守護進程的模式運行,一直監聽配置文件裡面定義的ret_port(接受minion請求)和publish_port(發布消息)的埠。當Minion運行時會自動連接到配置文件裡面定義的Master地址ret_port埠進行連接認證。
saltstack除了傳統的C/S架構外,其實還有一種叫做masterless的架構,其不需要單獨安裝一台 master 伺服器,只需要在每台機器上安裝 Minion端,然後採用本機只負責對本機的配置管理機制服務的模式。
saltstack提供如下一些功能:
(1)遠程執行:(批量執行命令)在master上執行命令時,會在所有的minion上執行。
(2)配置管理/狀態管理 :(描述想到達到的狀態,saltstack就會去執行)
(3)雲管理(cloud):用於管理雲主機
(4)事件驅動:被動執行,當達到某個值會自動觸發
這四種自動化運維工具的比較如下,現在主流的基本上ansible和saltstack用的多一些:
③ 如何把程序從windows平台移植到linux平台
需要用到的技術舉廳有:
1. 抽取其中用到的 Win32API, 分為通信類, 多線程類,時間字元串等函數類, 逐一封裝成 Linux 的函數;
2. 調試移植後的整個代碼庫, 並作必要的調整和修正;
3. 需要 C++11/14 的辯蘆經驗;
4. 需要 Windows 和 Linux 高性能多線程 C++伺服器程序開發和調試的正灶隱經驗,
5. 需要 boost 及 zeromq, 以及非同步通信庫, 非同步日誌庫等方面的經驗;
④ 為啥linux使用zeromq出現未定義zmq
Windows下VS2008使用ZeroMQ說明一、下載ZeroMQ
二、編譯ZeroMQ庫文件
解壓zeromq-4.0.3.zip文件,進入builds\msvc目錄,用VS打開*.sln工程文件,編譯生成解決方案。編譯完成後,會在lib目錄下生成dll和lib文件
三、編寫簡單的測試工程
用VS新建2個項目,一個是server端,一個是client端
將ZeroMQ源碼項目的include目錄下的兩個文件「zmq.h」,「zmq_utils.h」拷貝至自己新建的工程
將ZeroMQ源碼項目的lib目錄下的兩個文件「libzmq.dll」,「libzmq.lib」拷貝至自己新建的工程
將文件「zmq.h」,「zmq_utils.h」和「libzmq.lib」添加進自己新建的項目。
client端代碼:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include "zeroMQ/zmq.h"
#include "zeroMQ/zmq_utils.h"
int main(int argc,char** argv)
⑤ Linux下各種鎖的理解和使用及總結解決epoll驚群問題(面試常考)-
鎖出現的原因
臨界資源是什麼: 多線程執行流所共享的資源
鎖的作用是什麼, 可以做原子操作, 在多線程中針對臨界資源的互斥訪問... 保證一個時刻只有一個線程可以持有鎖對於臨界資源做修改操作...
任何一個線程如果需要修改,向臨界資源做寫入操作都必須持有鎖,沒有持有鎖就不能對於臨界資源做寫入操作.
鎖 : 保證同一時刻只能有一個線程對於臨界資源做寫入操作 (鎖地功能)
再一個直觀地代碼引出問題,再從指令集的角度去看問題
上述一個及其奇怪的結果,這個結果每一次運行都可能是不一樣的,Why ? 按照我們本來的想法是每一個線程 + 20000000 結果肯定應該是60000000呀,可以就是達不到這個值
為何? (深入匯編指令來看) 一定將過程放置到匯編指令上去看就可以理解這個過程了.
a++; 或者 a += 1; 這些操作的匯編操作是幾個步驟?
其實是三個步驟:
正常情況下,數據少,操作的線程少,問題倒是不大,想一想要是這樣的情況下,操作次數大,對齊操作的線程多,有些線程從中間切入進來了,在運算之後還沒寫回內存就另外一個線程切入進來同時對於之前的數據進行++ 再寫回內存, 啥效果,多次++ 操作之後結果確實一次加加操作後的結果。 這樣的操作 (術語叫做函數的重入) 我覺得其實就是重入到了匯編指令中間了,還沒將上一次運算的結果寫回內存就重新對這個內存讀取再運算寫入,結果肯定和正常的邏輯後的結果不一樣呀
來一幅圖片解釋一下
咋辦? 其實問題很清楚,我們只需要處理的是多條匯編指令不能讓它中間被插入其他的線程運算. (要想自己在執行匯編指令的時候別人不插入進來) 將多條匯編指令綁定成為一條指令不就OK了嘛。
也就是原子操作!!!
不會原子操作?操作系統給咱提供了線程的 綁定方式工具呀:mutex 互斥鎖(互斥量), 自旋鎖(spinlock), 讀寫鎖(readers-writer lock) 他們也稱作悲觀鎖. 作用都是一個樣,將多個匯編指令鎖成為一條原子操作 (此處的匯編指令也相當於如下的臨界資源)
悲觀鎖:鎖如其名,每次都悲觀地認為其他線程也會來修改數據,進行寫入操作,所以會在取數據前先加鎖保護,當其他線程想要訪問數據時,被阻塞掛起
樂觀鎖:每次取數據的時候,總是樂觀地認為數據不會被其他線程修改,因此不上鎖。但是在更新數據前, 會判斷其他數據在更新前有沒有對數據進行修改。
互斥鎖
最為常見使用地鎖就是互斥鎖, 也稱互斥量. mutex
特徵,當其他線程持有互斥鎖對臨界資源做寫入操作地時候,當前線程只能掛起等待,讓出CPU,存在線程間切換工作
解釋一下存在線程間切換工作 : 當線程試圖去獲取鎖對臨界資源做寫入操作時候,如果鎖被別的線程正在持有,該線程會保存上下文直接掛起,讓出CPU,等到鎖被釋放出來再進行線程間切換,從新持有CPU執行寫入操作
互斥鎖需要進行線程間切換,相比自旋鎖而言性能會差上許多,因為自旋鎖不會讓出CPU, 也就不需要進行線程間切換的步驟,具體原理下一點詳述
加互斥量(互斥鎖)確實可以達到要求,但是會發現運行時間非常的長,因為線程間不斷地切換也需要時間, 線程間切換的代價比較大.
相關視頻推薦
你繞不開的組件—鎖,4個方面手撕鎖的多種實現
「驚群」原理、鎖的設計方案及繞不開的「死鎖」問題
學習地址:C/C++Linux伺服器開發/後台架構師【零聲教育】-學習視頻教程-騰訊課堂
需要C/C++ Linux伺服器架構師學習資料加qun812855908獲取(資料包括 C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg 等),免費分享
自旋鎖
spinlock.自旋鎖.
對比互斥量(互斥鎖)而言,獲取自旋鎖不需要進行線程間切換,如果自旋鎖正在被別的線程佔用,該線程也不會放棄CPU進行掛起休眠,而是恰如其名的在哪裡不斷地循環地查看自旋鎖保持者(持有者)是否將自旋鎖資源釋放出來... (自旋地原來就是如此)
口語解釋自旋:持有自旋鎖的線程不釋放自旋鎖,那也沒有關系呀,我就在這里不斷地一遍又一遍地查詢自旋鎖是否釋放出來,一旦釋放出來我立馬就可以直接使用 (因為我並沒有掛起等待,不需要像互斥鎖還需要進行線程間切換,重新獲取CPU,保存恢復上下文等等操作)
哪正是因為上述這些特點,線程嘗試獲取自旋鎖,獲取不到不會採取休眠掛起地方式,而是原地自旋(一遍又一遍查詢自旋鎖是否可以獲取)效率是遠高於互斥鎖了. 那我們是不是所有情況都使用自旋鎖就行了呢,互斥鎖就可以放棄使用了嗎????
解釋自旋鎖地弊端:如果每一個線程都僅僅只是需要短時間獲取這個鎖,那我自旋占據CPU等待是沒啥問題地。要是線程需要長時間地使用占據(鎖)。。。 會造成過多地無端占據CPU資源,俗稱站著茅坑不拉屎... 但是要是僅僅是短時間地自旋,平衡CPU利用率 + 程序運行效率 (自旋鎖確實是在有些時候更加合適)
自旋鎖需要場景:內核可搶占或者SMP(多處理器)情況下才真正需求 (避免死鎖陷入死循環,瘋狂地自旋,比如遞歸獲取自旋鎖. 你獲取了還要獲取,但是又沒法釋放)
自旋鎖的使用函數其實和互斥鎖幾乎是一摸一樣地,僅僅只是需要將所有的mutex換成spin即可
僅僅只是在init存在些許不同
何為驚群,池塘一堆, 我瞄準一條插過去,但是好似所有的都像是覺著自己正在被插一樣的四處逃竄。 這個就是驚群的生活一點的理解
驚群現象其實一點也不少,比如說 accept pthread_cond_broadcast 還有多個線程共享epoll監視一個listenfd 然後此刻 listenfd 說來 SYN了,放在了SYN隊列中,然後完成了三次握手放在了 accept隊列中了, 現在問題是這個connect我應該交付給哪一個線程處理呢.
多個epoll監視准備工作的線程 就是這群 (),然後connet就是魚叉,這一叉下去肯定是所有的 epoll線程都會被驚醒 (多線程共享listenfd引發的epoll驚群)
同樣如果將上述的多個線程換成多個進程共享監視 同一個 listenfd 就是(多進程的epoll驚群現象)
咱再畫一個草圖再來理解一下這個驚群:
如果是多進程道理是一樣滴,僅僅只是將所有的線程換成進程就OK了
終是來到了今天的正題了: epoll驚群問題地解決上面了...
首先 先說說accept的驚群問題,沒想到吧accept 平時大家寫它的多線程地時候,多個線程同時accept同一個listensock地時候也是會存在驚群問題地,但是accept地驚群問題已經被Linux內核處理了: 當有新的連接進入到accept隊列的時候,內核喚醒且僅喚醒一個進程來處理
但是對於epoll的驚群問題,內核卻沒有直接進行處理。哪既然內核沒有直接幫我們處理,我們應該如何針對這種現象做出一定的措施呢?
驚群效應帶來的弊端: 驚群現象會造成epoll的偽喚醒,本來epoll是阻塞掛起等待著地,這個時候因為掛起等待是不會佔用CPU地。。。 但是一旦喚醒就會佔用CPU去處理發生地IO事件, 但是其實是一個偽喚醒,這個就是對於線程或者進程的無效調度。然而進程或者線程地調取是需要花費代價地,需要上下文切換。需要進行進程(線程)間的不斷切換... 本來多核CPU是用來支持高並發地,但是現在卻被用來無效地喚醒,對於多核CPU簡直就是一種浪費 (浪費系統資源) 還會影響系統的性能.
解決方式(一般是兩種)
Nginx的解決方式:
加鎖:驚群問題發生的前提是多個進程(線程)監聽同一個套接字(listensock)上的事件,所以我們只讓一個進程(線程)去處理監聽套接字就可以了。
畫兩張圖來理解一下:
上述還沒有進行一個每一個進程都對應一個listensock 而是多線程共享一個listensock 運行結果如下
所有的線程同時被喚醒了,但是實際上會處理連接的僅僅只是一個線程,
咱僅僅只是將主線程做如上這樣一個簡單的修改,每一個線程對應一個listensock;每一個線程一個獨有的監視窗口,將問題拋給內核去處理,讓內核去負載均衡 : 結果如下
僅僅喚醒一個線程來進行處理連接,解決了驚群問題
本文通過介紹兩種鎖入手,以及為什麼需要鎖,鎖本質就是為了保護,持有鎖你就有權力有能力操作寫入一定的臨界保護資源,沒有鎖你就不行需要等待,本質其實是將多條匯編指令綁定成原子操作
然後介紹了驚群現象,通過一個巧妙地例子,扔一顆石子,只是瞄準一條魚扔過去了,但是整池魚都被驚醒了,
對應我們地實際問題就是, 多個線程或者進程共同監視同一個listensock。。。。然後IO連接事件到來地時候本來僅僅只是需要一個線程醒過來處理即可,但是卻會使得所有地線程(進程)全部醒過來,造成不必要地進程線程間切換,多核CPU被浪費喔,系統資源被浪費
處理方式 一。 Nginx 源碼加互斥鎖處理。。 二。設置SO_REUSEPORT, 使得多個進程線程可以同時連接同一個port , 為每一個進程線程搞一個listensock... 將問題拋給內核去處理,讓他去負載均衡地僅僅將IO連接事件分配給一個進程或線程