2019年10月23日 星期三

go modules


用途

可以在$GOPHTH外開專案
怕依賴package不見,可以保留依賴檔案(用vendor功能)
同一依賴package,可已有多版本共存在依賴目錄
可以用Goproxy解決有些地方無法使用o get的問題

說明

環境變數要打開 GO111MODULE=on
專案目錄要設定成使用 module : go mod init
專案的外部 package 還是放在$GOPATH/pkg/mod 下
可以保留目前用的外部 package 到 vendor目錄
可選擇使用 vendor 目錄的 package 或用 go mod 抓

流程

  1. 環境變數設置 GO111MODULE=on(使用 go module 模式)
  2. 專案設定使用 module 。 專案目錄下 go mod init。產生 go.mod 檔案。
  3. 安裝外部 package 方法1:go get -u github.com/xxxx/xxx。會更新 go.mod。
    如果 package 沒有在 go.mod 中指定版本,會抓最新的 tag。沒有 tag 會抓最新 commit。
  4. 安裝外部 package 方法2:go mod downloac。下載全部依賴到 $GOPATH/pkg/mod 。
  5. 然後 go 就會到 $GOPATH/pkg/mod 去找需要的外部 package。

原則

  • go get 如果 package 沒有在 go.mod 中指定版本,會抓最新的 tag。沒有 tag 會抓最新 commit。
  • go get 可抓指定的 tag 或 指定的 commit hash。
  • 要更改專案使用的 package 版本,可以直接改 go.mod,然後重新 go get .....
  • 要使用 vendor 目錄的 package: go build, go install, go test 都加上 -mod=vendor 參數。

go111MODULE 設定

  • 只要有設定GO111MODULE=on,就是使用module。
  • 1.13起,專案在 GOPATH 外,且有 go.mod 文件。無論有無設定都等同于 GO111MODULE=on。
  • 專案在 GOPATH 内,且没有 go.mod 文件時,等同於 GO111MODULE=off

go.mod 設定

  • module 定義模組位置
  • require 指定外部 package 及其版本
  • exclude 排除指定的 package
  • replace 只用不同的 package 取代原本的某個 package
module modtest
go 1.12
require (

 github.com/mattn/go-isatty v0.0.8 // indirect
 github.com/sirupsen/logrus v1.4.2
 github.com/ugorji/go v1.1.7 // indirect
 gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
 gopkg.in/yaml.v2 v2.2.2 // indirect
)
exclude github.com/gin-gonic/gin v1.4.0
replace github.com/tedmax100/modtest => ../gomodtest  //用本地目錄或遠端 repo 取代 modtest

go mod 命令

  • go mod init [project dir / or this dir]
  • go mod download
  • go mod tidy
  • go mod vendor
  • go mod edit
  • go mod why

goland IDE

A module 專案時,IDE的 build/test working dir 要在 module 目錄

B module 專案時,IDE的 build/test output dir 不需要在 module 目錄

C Preference/Go/Go Modules(vgo) => Enable



1 Init project to create go.mod

in goland IDE terminal
>go mod init
will create go.mod

2 Create go.sum

in goland IDE terminal
>go test / go build
will create go.mod

or go mod tidy
will create go.mod and add / remove dependencies

go.mod 裡面會紀錄這個project用到的dependencies及版本。
因為是紀錄版本,所以如果作者commit卻沒有tag 版本,那就會對應錯。

3 Dependency 的版本不一定對,要自己確認。

因為dependency 是從某個公開的repository 抓的(多半是github),
他抓的原則是:
a 如果有指定版本,就抓指定版本。
b 抓有tag release版的最新版。

問題

有可能作者commit很多版,但是都沒更新 release tag,這樣就抓不到你要的版本。

方法:

in project direcroty
go get -u github.com/satori/go.uuid@b2ce2384e17bbe0c6d34077efa39dbab3e09123b

這樣會抓回指定commit的版本
go.mod / go.sum裡面,這個 package的版號,會跟著改。

如果是自己寫的package


go.mod檔案的 module 設定要正確,go get 是用這個判斷 module path,
因為 go mod 要從 git server repo 抓 package,
他不會從 local 電腦 的 $GOPATH 抓 package,
所以要把自己寫的 package 也加入 go mod,
要把這個 package 放到 github。
或放到某個自設的 git server 的 repo。

否則使用go mod 會出現  cannot find module providing package  ...... error

go get 抓 github private repository

get get 只使用https
可能需要社 GOPRIVATE 變數
go env -w GOPRIVATE=github.com/abcd

//設定 global config
//好像一定要設成 global, 設local沒用
git config --global url."https://$USERNAME:$ACCESS_TOKEN@github.com".insteadOf "https://github.com"
$USERNAME 就是github username
$ACCESS_TOKEN 就是 user access token, 在 setting => Developer settings => Personal access tokens


2019年8月23日 星期五

Git

Git global setup

git config --global user.name "cruise"
git config --global user.email "cruisecg.cg@gmail.com"

Create a new repository

git clone https://gitlab.3ag.xyz/backend/service.git
cd service
touch README.md
git add README.md
git commit -m "add README"
git push -u origin master

Push an existing folder

cd existing_folder
git init
git remote add origin https://gitlab.3ag.xyz/backend/service.git
git add .
git commit -m "Initial commit"
git push -u origin master

Push an existing Git repository

cd existing_repo
git remote rename origin old-origin
git remote add origin https://gitlab.3ag.xyz/backend/service.git
git push -u origin --all
git push -u origin --tags

用ssh 取代 https

教學
//可以每次手打
git remote set-url origin git@gitlab.com/...

//globally config (~/.gitconfig) or per-repo (.git/config)
git config url.ssh://git@github.com/.insteadOf https://github.com/
git config url.ssh://git@gitlab.com/.insteadOf https://gitlab.com/

or
git config --global url.ssh://git@github.com/.insteadOf https://github.com/
git config --global url.ssh://git@gitlab.com/.insteadOf https://gitlab.com/

//這幾種格式都試一下
git config url.git@github.com/.insteadOf https://github.com/
git config url.git@github.com:.insteadOf https://github.com/
git config url.ssh://git@github.com:.insteadOf https://github.com/

檔案

檔案狀態
1 untracked  commit過後加入的檔案,預設沒有 track
2 tracked    有 track 的檔案,有任何變更,會追蹤
3 unstaged   有追蹤,但是沒有加入預備區(預備提交)
4 staged     有加入預備區
5 uncommitted  在預備區,尚未提交
6 committed    已經提交(push 就會上到 remote repos)

變更檔案狀態
改變檔案狀態,都是使用 add 命令。無論是要 track , stage 檔案,都是 add 。
add 之後,檔案會變成 uncommitted 狀態。

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連接就看服務器設置情況。