2019年5月29日 星期三

Zabbix



安裝流程

1 安裝server
2 安裝 mysql
3 建立 db
4 改設定

參考官方安裝文件
https://www.zabbix.com/download?zabbix=4.0&os_distribution=centos&os_version=7&db=mysql

https://www.zabbix.com/documentation/4.0/manual/installation/install_from_packages/rhel_centos

設定 zabbix mysql password

grant all privileges on zabbix.* to zabbix@localhost identified by 'password';
flush privileges;

設定 php time zone

vi /etc/httpd/conf.d/zabbix.conf,
php_value date.timezone Asia/Shanghai

2019年5月16日 星期四

MySQL InnoDB Lock

詳細說明
詳細說明

InnoDB在transaction中,會視語法不同,自動加鎖。
Transaction中的鎖,都是以Row為標的。

非transaction中,因為會自動COMMIT,所以使用加鎖的語法也沒用。

InnoDB三種加鎖類型

  • Record lock: This is a lock on an index record.
  • Gap lock: This is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.
  • Next-key lock: This is a combination of a record lock on the index record and a gap lock on the gap before the index record.
  • 官網說明:http://dev.mysql.com/doc/refman/5.7/en/innodb-record-level-locks.html
  • 重點1:Next-key locking combines index-row locking with gap locking.
  • InnoDB performs row-level locking in such a way that when it searches or scans a table index, it sets shared or exclusive locks on the index records it encounters (select 過程搜尋遇到的資料列都會被加鎖)

InnoDB鎖定模式

  • 共享鎖定 (shared lock) (S lock):permits the transaction that holds the lock to read a row.
  • 排他鎖定 (exclusive lock) (X lock):permits the transaction that holds the lock to update or delete a row.

不同語句的加鎖效果

  • SELECT ... FROM 基本不加鎖
    但在 SERIALIZABLE 隔離層級時,會自動在遇到的資料加鎖
  • SELECT ... FROM ... LOCK IN SHARE MODE (加共享鎖)
  • SELECT ... FROM ... FOR UPDATE (加排它鎖)
  • UPDATE ... WHERE ... (加排它鎖)
  • DELETE FROM ... WHERE ... (加排它鎖)
  • INSERT (加排它鎖)

MySQL AUTOCOMMIT命令

Autocommit 是設定MySQL是否自動提交變更

AUTOCOMMIT 的設定值,預設一般都是 1

查詢目前 AUTOCOMMIT 的設定值:SELECT @@AUTOCOMMIT

將 AUTOCOMMIT 改為 0 時 ( SET AUTOCOMMIT=0 ),就算沒使用transaction( START TRANSACTION 或 BEGIN ),整個連線執行的 SQL 指令,都會等到下達 COMMIT 提交後,才會真正儲存變更。

也就是當 AUTOCOMMIT=0 時,跟在交易模式下相同。

更改COMMIT狀態指令:
SET AUTOCOMMIT=0; // AUTOCOMMIT=1;

提交指令:
COMMIT;

2019年3月26日 星期二

Linux 常用指令

Process 管理

//列出系統上最耗費記憶體的程式
//-e 輸出所有行程的資訊
//-o 指定輸出欄位
//--sort 排序
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head

//取當前pid
echo $$

//process 資源限制
ls /proc/{pid}/fd
cat /proc/{pid}/limits

//開檔狀況
ls -l /proc/{pid}/fd | less

//總開檔數
ls -l /proc/{pid}/fd | wc -l

網路相關

//查看80是哪個procese監聽的
netstat -tlnp | grep :22

tcp    0  0 0.0.0.0:22  0.0.0.0:*  LISTEN   1444/sshd
tcp6   0  0 :::22       :::*       LISTEN   1444/sshd

User 管理

sudo -i 切換為root

ssh 管理

//scp
scp "fileName" ubuntu@xxx.xx.xx.xx:/home/ubuntu/
scp -i "keyfile" filename aa@xxx.xxx.xxx.xxx:/home/aa/
sshpass -p "pass" scp "fileName" ubuntu@xxx.xx.xx.xx:/home/ubuntu/

//指定port P大寫
scp -P port root@xxx.xxx.xxx:/root/abc.jpg abc.jpc 
scp -P port abc.jpg root@xxx.xxx.xxx:/root/abc.jpg

//指定key
ssh -i 'keyfile' aa@xxx.xxx.xxx.xxx

//設定ssh timeout 時間
vim /etc/ssh/sshd_config

//找到ClientAliveInterval 参数,如果没有就自己加一行。
//client alive 檢查,秒
ClientAliveInterval=600 

//client alive 檢查次數 
ClientAliveCountMax=12

//依據以上設定,就是600*12=7200秒都沒反應就斷線
//開啟root ssh login
sudo passwd root    //更改root密碼
sudo vi /etc/ssh/sshd_config
PermitRootLogin yes
PasswordAuthentication yes

//centos 
service sshd restart
systemctl restart sshd

//debain
service ssh restart
systemctl restart sshd

ssh agent

1. Start ssh-agent in the background.
 > Agent pid xxxxx
2. Add ssh key to agent
  $ ssh-add -K pathToPrivateKey
  (-K 只限mac 內建的ssh-add, 表示存 passphase in your keychain)

3. if you key with passphase, agent will ask you to input pass.

//看ssh-agent執行狀況
看變數,是否有輸出
echo $SSH_AUTH_SOCK
echo $SSH_AGENT_PID

//in shell script
//自動加入所有預設rsa的key
if [ -z "$SSH_AUTH_SOCK" ] ; then
  eval `ssh-agent -K`
  ssh-add
fi

//kill ssh-agent
ssh-agent -k

github 使用多個 ssh key 與帳號

Host   連線至遠端的別稱(可以隨便填)
HostName   遠端的Domain或IP
Port   遠端的SSH連接埠(為預設的話可以不填)
User   使用者名稱
PreferredAuthentications   偏好使用的驗證(這邊的值都為publickey)
IdentityFile   私鑰的位置(可為相對或絕對位置,但建議使用絕對位置)

//edit ~/.ssh/config

Host gh.aaa.my
 HostName github.com
 User Hi_AAA
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/id_rsa_aaa_github

Host gh.bbb.company
 HostName github.com
 User Hi_BBB
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/id_rsa_bbb_github

Host bb.aaa.my
 HostName bitbucket.org
 User Yo_AAA
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/id_rsa_aaa_bitbucket

原本 repo 位置會改變
原本 git@github.com:Hi_AAA/my_project.git  
新的 git@gh.aaa.my:Hi_AAA/my_project.git

Domain的部分可以使用設定檔的 Host 名稱取代

//key 加入 ssh-agent 管理
ssh-add 

apt


apt-cache policy mysql-server       列出mysql所有版本
apt-get install mysql-server=5.6.29 安裝mysql指定版本

2019年3月4日 星期一

網路 http

NotFalse 技術客詳細說明

HTTP

1.0 /1.1 /2.0

主要特色

簡單:request - response
不限傳輸資料內容(content-type定義)
無連接:一個request一個連接
無狀態

URI 與URL 參考

URI (Uniform Resource Identifier)統一資源識別符

web上的資源,例如檔案、圖片、程式,都是用URI定義的。
能定位到資源的就是URI,例如:
localhost:80/index.html
localhost:80/user/save

URL(Uniform Resource Location)統一資源定位符

URL是URI的子集。
URL是路徑,URI是實際資源。
URI:localhost:80/user/save
URL:localhost:80/user

Message

HTTP/1.1傳輸是以message為單位。
(HTTP/2是以message frame訊息框為單位)
Message稱為訊息、報文、消息。

Message格式

Start-line(起始行)
Headers(多個header-field+CRLF)
CRLF
Message-body(可選的)

Request Message範例

POST /?id=1 HTTP/1.1        (Start-line=>request line)
Host: echo.paw.cloud        (header-field)
Content-Type: application/json; charset=utf-8 (header-field)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0 (header-field)
Connection: close           (header-field)
Content-Length: 136         (header-field)
(CRLF)
(以下為message-body)
{
  "status": "ok",
  "extended": true,
  "results": [
    {"value": 0, "type": "int64"},
    {"value": 1.0e+3, "type": "decimal"}
  ]
}

Response Message範例

HTTP/1.1 200 OK                      (Start-line=>status line)
Content-Type: text/html; charset=utf-8    (header-field)
Date: Sat, 18 Feb 2017 00:01:57 GMT       (header-field)
Server: nginx/1.11.8                      (header-field) 
transfer-encoding: chunked                (header-field)
Connection: Close                         (header-field)
(CRLF)
(以下為message-body)
<html lang="en">
<head>
<title>echo<title>
</head>

Start-line 起始行

Request start line,依序是:
方法(method)、空白(space)、請求目標(request target)、空白(space)、HTTP版本(http version)、CRLF

Response start line,依序是:
HTTP版本(http version)、空白(space)、狀態碼(status code)、空白(space)、原因短語(reason phrase)、CRLF

Method

HTTP1.0 定義三種方法:post,get,head
HTTP1.1 定義的方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT

GET  请求指定的页面信息,并返回实体主体。
HEAD     类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST     向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT      从客户端向服务器传送的数据取代指定的文档的内容。
DELETE   请求服务器删除指定的页面。
CONNECT  HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS  允许客户端查看服务器的性能。
TRACE    回显服务器收到的请求,主要用于测试或诊断
  • POST 
  • 規定資料要放在body中
    四種常用的content-type:
    application/x-www-form-urlencoded
    multipart/form-data
    application/json
    text/xml

Status Code

1xx 請求接受,繼續處理。
2xx 請求成功。
3xx 重定向-要完成請求要進一步處理。
4xx 客戶端錯誤,例如請求語法錯誤。請求無法實現:403。
5xx 服務器端錯誤。

Content Type

NotFalse 技術客詳細說明
  • application/x-www-form-urlencoded
  • 常用於POST表單,是key-value形式

    POST http://www.example.com HTTP/1.1
    Content-Type: application/x-www-form-urlencoded;charset=utf-8
    .....省略
    title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
    

  • multipart/form-data
  • 使用表單上傳文件時,必須對form的enctype設定為multipart-/form-data

    POST http://www.example.com HTTP/1.1
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
    
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="text"
    
    title
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="file"; filename="chrome.png"
    Content-Type: image/png
    
    PNG ... content of chrome.png ...
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
    

  • application/json
  • POST http://www.example.com HTTP/1.1 
    Content-Type: application/json;charset=utf-8
    
    {"title":"test","sub":[1,2,3]}
    


  • text/xml
  • POST http://www.example.com HTTP/1.1 
    Content-Type: text/xml
    
    
    <methodcall>
        <methodname>examples.getStateName</methodname>
        <params>
            <param />
                <value><i4>41</i4></value>
            
        </params>
    </methodcall>

keep alive模式

參考
keep alive 需client-server兩邊配合

http 1.0中默認是關閉的,需要在http頭加入"Connection: Keep-Alive”,才能啓用Keep-Alive;

http 1.1中默認啓用Keep-Alive,如果加入"Connection: close “,才關閉。

目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的連接請求了

所以是否能完成一個完整的Keep- Alive連接就看服務器設置情況。

2019年2月15日 星期五

網路 Socket

Beejs guide to network programming詳細說明

Socket Types

  • Stream Socket
  • SOCK_STREAM 串流式
    基於TCP
    資料需要可靠的、需要順序的多半用stream socket
    例如:HTTP/TELNET

  • Datagram Socket
  • SOCK_DGRAM 訊息式
    基於UDP
    不可靠、不一定照順序、但是如果送達(封包重組完成,如果有分割的話),資料就是正確的。
    遊戲玩家位置、音樂、音效,等可容許小量丟失的。
    例如:TFT/DHCPD

  • Row Socket


  • Link Layer Socket

2019年2月13日 星期三

RabbitMQ

基本概念

官方網頁

RabbitMQ就像郵局,唯一不同的是它送數位資料,郵局送信。
Queue就是郵筒,存在郵局裡(RabbitMQ),只受限於ram跟disk。

message只存在queue裡。
多個producers可以送message給同一個queue。
多個consumer可以從同一個queue收message。
基本上每個message被收走就沒有了。
  • RabbitMQ=郵局
  • Queue=郵筒(存在於郵局RabbitMQ)
  • Message=信
  • Exchange=在producer這邊,他是收信的工具、在consumer這邊,他是送信的工具(存在於郵局RabbitMQ)
  • Producer=寄信者
  • Consumer=收信者

連線架構

TCP connection -> connection -> channel

Message 送出後,consumer會回傳ack(acknowledgement),
確認message正確收取,否則會re-queue此message。

訊息模型

Producer -> exchange -> Queue -> exchange -> Consumer
                        Queue -> exchange -> Consumer

以下為完成傳遞必要項目,缺一不可

  • 1 由Producer產生Message
  • 2 Message送到左邊的Exchange
  • 3 左邊的Exchange把Message送到綁定的Queue
  • 4 右邊的Exchange從Queue取出Message
  • 5 右邊的Exchange把Message送給Consumer
Producer及Consumer都可以宣告Exchange及Queue
若是沒宣告就是使用預設的,或是RabbitMQ會自行建立
宣告同名的Exchange或是Queue,就表示用現有的,RabbitMQ不會新建立一個
宣告同名的Exchange或是Queue,參數必須完全相同,否則報錯

基本模型(Producer/Consumer)
Producer -> Queue -> Consumer
Producer/Consumer是位於app,Queue是位於RabbitMQ
多個consumer模型(Worker Queues)
1 massage平均分配給多個consumer
2 等consumer回覆之後,才送新的message下去
Exchange模型(Publish/Subscribe)
所有要收的consumer,自行綁定上該exchange

一 Produce/Consumer(基本模型)

官方網頁

二 Work Queues(message acknowledgement、message durable)

官方網頁
  • Round-robin dispatching 輪詢式派送
    輪流派送給每個註冊的worker

  • Massage acknowledgement 訊息確認
    msgs, err := ch.Consume(
      q.Name, // queue
      "",     // consumer
      false,  // auto-ack
      false,  // exclusive
      false,  // no-local
      false,  // no-wait
      nil,    // args
    )
    
    //幾本上auto-ack都要設成true,不然就要自己送
    //否則rabbitmq 會保留此message,造成資源消耗
    
    go func() {
      for d := range msgs {
        log.Printf("Received a message: %s", d.Body)
        dot_count := bytes.Count(d.Body, []byte("."))
        t := time.Duration(dot_count)
        time.Sleep(t * time.Second)
        log.Printf("Done")
        d.Ack(false)
      }
    }()
    

  • Massage durability 訊息耐用(即便rabbitmq重開,未送出的message也不會消失)
    q, err := ch.QueueDeclare(
      "hello",      // name
      true,         // durable
      false,        // delete when unused
      false,        // exclusive
      false,        // no-wait
      nil,          // arguments
    )
    //producer、consumer宣告的queue durable要設成true
    //宣告同名的queue參數必須相同,否則錯誤
    
    err = ch.Publish(
      "",           // exchange
      q.Name,       // routing key
      false,        // mandatory
      false,
      amqp.Publishing {
        DeliveryMode: amqp.Persistent,
        ContentType:  "text/plain",
        Body:         []byte(body),
    })
    //publishing DeliveryMode 要設成 amqp.Persistent
    
    

  • 完成一個work才繼續派送(Fair dispatch 一節)
    基本上RabbitMQ的派送是平均派送,當他收到就派送,
    所以有可能派送給還沒完成工作的worker。
    可設定prefetch count=1
    這時rabbitMQ會收到前一個message的acknowledgement才會派送下一個。
    
    注意,此時queue有可能被填滿,你需要多設定幾個woker。
    
    err = ch.Qos(
      1,     // prefetch count
      0,     // prefetch size
      false, // global
    )
    

三 Publish/Subscribe(one message to multiple consumers)

官方網頁

Published message are going to be broadcast to all the receivers.
  • Exchanges
    4 types of exchange:direct,topic,headers,fanout
    
    err = ch.ExchangeDeclare(
      "logs",   // name
      "fanout", // type
      true,     // durable
      false,    // auto-deleted
      false,    // internal
      false,    // no-wait
      nil,      // arguments
    )
    
    //fanout:broadcast all messages to all the queues it knows
    
    

  • Bindings(Binding exchange and queue)
    err = ch.QueueBind(
      q.Name, // queue name
      "",     // routing key
      "logs", // exchange
      false,
      nil
    )
    

四 Routing(用路由方式傳送message給不同Queue)

官方網頁

Subscribe only to a subset of the messages.
  • 基本概念
    exchange publish時,可以加上路由(routing key)
    queue可以綁定exchange及routing key
    一個queue可以綁定一個exchange及多個routing key
    這樣就可以一個exchange 用多種routing發布,然後consumer利用不同routing接收
    

  • Bindings
    //Binding 是綁定exchange 及 queue
    //Binding時可以設定路由,用routing key parameter
    
    err = ch.QueueBind(
      q.Name,    // queue name
      "black",   // routing key
      "logs",    // exchange
      false,
      nil)
    
    //route to black
    
    

  • Direct exchange
    //用direct exchange才能使用binding的routing key
    //用fanout exchange會忽略routing key參數,合理,所以他才叫fanout
    
    err = ch.ExchangeDeclare(
                    "logs_direct", // name
                    "direct",      // type
                    true,          // durable
                    false,         // auto-deleted
                    false,         // internal
                    false,         // no-wait
                    nil,           // arguments
    )
    
     q, err := ch.QueueDeclare(
                    "",    // name
                    false, // durable
                    false, // delete when usused
                    true,  // exclusive
                    false, // no-wait
                    nil,   // arguments
     )
            
    err = ch.QueueBind(
      q.Name, // queue name
      "",     // routing key
      "logs", // exchange
      false,
      nil
    )
    

五 Publish/Subscribe(one message to multiple consumers)

官方網頁

Published message are going to be broadcast to all the receivers.
  • Exchanges
    4 types of exchange:direct,topic,headers,fanout
    
    err = ch.ExchangeDeclare(
      "logs",   // name
      "fanout", // type
      true,     // durable
      false,    // auto-deleted
      false,    // internal
      false,    // no-wait
      nil,      // arguments
    )
    
    //fanout:broadcast all messages to all the queues it knows
    
    

  • Bindings(Binding exchange and queue)
    err = ch.QueueBind(
      q.Name, // queue name
      "",     // routing key
      "logs", // exchange
      false,
      nil
    )
    
  • 
    

  • 
    

正式產品需要注意的主題

官方說明文件

  • Connection Management

  • Error Handling

  • Connection Recovery

  • Concurrency

  • Metric Collection

參考頁面
Publisher Confirms and Consumer Acknowledgements
Production Checklist
Mornitoring

linux安裝

主目錄 /opt/rabbitmq
看相關變數 printenv | grep rabbitmq
執行檔 /opt/rabbitmq/sbin
執行檔 /usr/local/bin

服務啟動
systemctl start rabbitmq-server


mac home brew 安裝

官網說明

相關的scripts及cli tools安裝在/usr/local/opt/rabbitmq/sbin,
需要自己加到path
export PATH=$PATH:/usr/local/opt/rabbitmq/sbin

服務啟動
brew services start rabbitmq
brew services stoprabbitmq
啟動在前景
/usr/local/Cellar/rabbitmq/3.7.11/sbin/rabbitmq-server

管理 rabbitmqctl

用這個程式管理rabbitmq大部分項目,像是增加使用者、列出使用者、重啟、列出參數等。

範例



增加使用者 add_user [userName][password]
rabbitmqctl add_user admin admin
更改使用者tag,改成管理者 set_user_tags [...]
rabbitmqctl set_user_tags admin administrator
更改使用者權限 set_permissions [name]
rabbitmqctl set_permissions -p / username ".*" ".*" ".*"
更改密碼 change_password [username] [password]
rabbitmqctl change_password admin admin
查詢未確認的message(unacknowledged) list_queues [queueName] messages_ready messages_unacknowledged
sudo rabbitmqctl list_queues queueName messages_ready messages_unacknowledged

監控

監控程式啟動在 http://localhost:15672 使用瀏覽器就可以開啟,要先建立一個user
rabbitmq-plugins enable rabbitmq-management

外掛管理

rabbitmq-plugins [-n [node]] [-t [timeout]] [-l] [-q] [command] [command options]

Eg.
rabbitmq-plugins [-n ] [-t ] [-l] [-q] is_enabled [plugin1] [plugin2] 

參數

-n node

-q quiet

-h  help

list 列出所有外掛

is_enabled [plugin1][,[plugin2]]   查看plugin是否啟用

enable [plugin]  啟用外掛

範例


啟用外掛
rabbitmq-plugins enable rabbitmq_management

管理工具

rabbitmqadmin