十一月札記

認識獲取(瞭解概念) -> 知識學習(建立模型) -> 技能訓練(實踐)

git 常用命令

git tag -a v1.3.1 -m "version v1.3.1 2019-6-20 ok"      #創建了本地一個版本 V20180817 ,並且添加了附註信息 version 20180817 但是目前這個標籤僅僅是提交到了本地git倉庫.
git push origin --tags  # 同步到遠程代碼庫,tag 遠程推送
git show v20180107      #查看對應的版本號
git reset --hard XXXXXXXX   # 回到當時版本
git tag -a v1.3.2 -m "version v1.3.2 2019-7-12 ok"
git pull origin master 如果是多人開發的話 需要把遠程master上的代碼pull下來
把dev分支的代碼合併到master上
git merge dev
然後查看狀態
git status
上面的意思就是你有12個commit,需要push到遠程master上 
執行下面命令即可
git push origin master

git強制覆蓋:
git fetch --all
git reset --hard origin/master
git pull
    
git push origin --delete dev # 刪除遠程dev分支
git branch -d dev # 刪除本地分支dev

apt-get 常用命令

apt-cache search XXXXX :查詢包
apt-get update:更新安裝列表
apt-get upgrade:升級軟件
apt-get install software_name :安裝軟件
apt-get --purge remove  software_name :卸載軟件及其配置
apt-get autoremove software_name:卸載軟件及其依賴的安裝包
dpkg --list:羅列已安裝軟件

安裝python3.7

wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
xz -d Python-3.7.0.tar.xz
tar -xvf Python-3.7.0.tar
cd Python-3.7.0
./configure
make
sudo make install

curl

## 需要注意的是在window中單引號要改成雙引號,json格式數據中雙引號要加\轉義
curl -v -X POST "127.0.0.1:3000/v1/image" -d "{\"group_id\":1,\"name\":\"aaa\",\"url\":\"bbb\",\"status\":1}" -H "Content-Type: application/json"

mysql

# 以管理員身份運行,在命令行輸入cd+mySQL的bin目錄的安裝路徑
C:\Windows\system32>cd C:\Program Files\MySQL\MySQL Server5.6\bin
C:\Program Files\MySQL\MySQL Server5.6\bin>mysqld --remove
Service successfully removed.
C:\Program Files\MySQL\MySQL Server5.6\bin>mysqld --install
Service successfully installed.
C:\Program Files\MySQL\MySQL Server5.6\bin>net start mysql

grant replication slave on *.* to 'toto1'@'%' identified by 'toto123';
GRANT ALL PRIVILEGES ON `camel_test`.* TO 'toto'@'%' WITH GRANT OPTION;

GRANT REPLICATION SLAVE ON *.* TO 'toto1'@'%' IDENTIFIED BY 'toto123';
GRANT REPLICATION  SUPER ON `camel_test`.* TO 'toto1'@'%';

grant replication slave, reload, super on *.* to 'toto1'@'%' identified by 'toto123';
flush privileges;
show variables like '%binlog_format%';  # 查看bin-log模式:statment(SBR)格式. Row(RBR)格式. MIXED(MBR)綜合格式。
show status like 'table_locks_%';# 數據庫鎖統計
show variables like '%expire_logs_days%'; # 查看默認的日誌保存天數
show variables like '%log_error%'; #查看錯誤日誌路徑:
show variables like '%slow_query_log%'; # MySQL慢查詢日誌
SHOW BINARY LOGS;   # 獲取當前二進制日誌列表 

MySQL徹底清除slave信息

在我們的MySQL,Master和Slave進行主從切換的時候,Slave成功升級爲主庫,那麼這個時候就需要徹底清理從庫的信息,不然監控系統會認爲這臺服務器是Slave,而且會報主從同步失敗。
其實非常的簡單,只需要以下兩步:

mysql> stop slave;
mysql> reset slave all;

reset slave all;是清除從庫的同步複製信息. 包括連接信息和二進制文件名. 位置。
從庫上執行這個命令後,使用show slave status將不會有輸出。

select id from user where id in (select user_id from shippers inner join commits on shippers.id=commits.shipper_id where commits.type=4);

update truck tk,
(select t.fk_truck_plate,t.fk_carrier_id,t.shipper_name,s.com_no,c.type from carrier_truck_commit t inner join commits c on t.id=c.shipper_id inner join shippers s on s.id=t.fk_carrier_id) obj
 set tk.fk_carrier_id=obj.fk_carrier_id, tk.carrier_name=obj.shipper_name,tk.carrier_code=obj.com_no,tk.carrier_type=obj.type,tk.team_carrier_id=obj.fk_carrier_id, tk.team_carrier_name=obj.shipper_name,tk.team_carrier_code=obj.com_no,tk.own_carrier_id=obj.fk_carrier_id, tk.own_carrier_name=obj.shipper_name,tk.own_carrier_code=obj.com_no 
 where tk.plate=obj.fk_truck_plate;
 
SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
      [PARTITION partition_list]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]


# 不同版本默認的SQL_MODE
MySQL 5.5:空
MySQL 5.6:NO_ENGINE_SUBSTITUTION
MySQL 5.7:ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER,  NO_ENGINE_SUBSTITUTION
MySQL 8.0:ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE,  NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION
# 如何修改SQL_MODE
SQL_MODE既可在全局級別修改,又可在會話級別修改。可指定多個MODE,MODE之間用逗號隔開。
# 全局級別
set global sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES';
# 會話級別
set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES';
# 總結
1. SQL_MODE在非嚴格模式下,會出現很多意料不到的結果。建議線上開啓嚴格模式。但對於線上老的環境,如果一開始就運行在非嚴格模式下,切忌直接調整,畢竟兩者的差異性還是相當巨大。
2. 官方默認的SQL_MODE一直在發生變化,MySQL 5.5, 5.6, 5.7就不盡相同,但總體是趨嚴的,在對數據庫進行升級時,其必須考慮默認的SQL_MODE是否需要調整。
3. 在進行數據庫遷移時,可通過調整SQL_MODE來兼容其它數據庫的語法。

go雜記

#可被尋址
值的修改從表面意義上叫可尋址,換一種說法就是值必須“可被設置”。那麼,想修改變量值,一般的步驟是:
取這個變量的地址或者這個變量所在的結構體已經是指針類型。
使用 reflect.ValueOf 進行值包裝。
通過 Value.Elem() 獲得指針值指向的元素值對象(Value),因爲值對象(Value)內部對象爲指針時,使用 set 設置時會報出宕機錯誤。
使用 Value.Set 設置值。


# GO111MODULE
set GO111MODULE=off
set GOPROXY=https://goproxy.io
set GO111MODULE=auto # 在gopath中就默認on,其他地方默認off

# go get 參數
-u  用於下載指定的路徑包及其依賴包,默認情況下,不會下載本地已經存在的,只會下載本地不存在的代碼包。就是口中常說的跟新包 比如:go get -u github.com/jinzhu/gorm。會把最新的 gorm 包下載到你本地
-d  此命令僅僅是下載路徑包,而不會進行安裝。即不會執行 go install 命令
-t  讓命令程序同時下載並安裝指定的代碼包中的測試源碼文件中依賴的代碼包。
-fix    讓命令程序在下載代碼包後先執行修正動作,而後再進行編譯和安裝。。
-insecure   允許命令程序使用非安全的scheme(如HTTP)去下載指定的代碼包。如果你用的代碼倉庫(如公司內部的Gitlab)沒有HTTPS支持,可以添加此標記。請在確定安全的情況下使用它。(記得 使用工具 git 時,有個版本就是 http 升級爲了https)
-v  打印出那些下載的代碼包的名字。
-f  僅在使用-u標記時纔有效。該標記會讓命令程序忽略掉對已下載代碼包的導入路徑的檢查。如果下載並安裝的代碼包所屬的項目是你從別人那裏Fork過來的,那麼這樣做就尤爲重要了 。
-x  打印出整個過程使用了哪些命令。

# GO111MODULE=auto(auto是指如果在gopath下不啓用mod)
go mod init XXX //創建了一個名字爲XXX的新模塊,自動分析項目裏的依賴關係同步到go.mod文件中,同時創建go.sum文件(XXX必須和模塊名一致)
go build, go test //和其它構建代碼包的命令,會在需要的時候在 go.mod 文件中添加新的依賴項
go list -m all //列出了當前模塊所有的依賴項
go get //修改指定依賴項的版本(或者添加一個新的依賴項)
go mod tidy -v //移除模塊中沒有用到的依賴項,並打印詳情
go mod vendor -v //生成vendor文件夾,該文件夾下將會放置你go.mod文件描述的依賴包
go mod help查看幫助
go mod init<項目模塊名稱>初始化模塊,會在項目根目錄下生成 go.mod文件。

go mod tidy 根據go.mod文件來處理依賴關係。
go mod vendor將依賴包複製到項目下的 vendor目錄。建議一些使用了被牆包的話可以這麼處理,方便用戶快速使用命令go build -mod=vendor編譯
go list -m all顯示依賴關係。go list -m -json all顯示詳細依賴關係。
go mod download <path@version>下載依賴。參數<path@version>是非必寫的,path是包的路徑,version是包的版本。
# 如果你使用的 Go 版本>=1.13, 你可以通過設置 GOPRIVATE 環境變量來控制哪些私有倉庫和依賴(公司內部倉庫)不通過 proxy 來拉取,直接走本地,設置如下:
set GOPROXY=https://proxy.golang.org
set GOPROXY=https://goproxy.io
Go version >= 1.13
go env -w GOPROXY=https://goproxy.io
go env -w GOPRIVATE=*.corp.example.com //設置不走 proxy 的私有倉庫,多個用逗號相隔
引入本地包的方法(在go.mod中)
require (
    test v0.0.0
)

replace (
 test => ../test
)

注意:
1.引入的包必須也是gomod的(有.mod文件)
2.replace時必須使用相對路徑比如../ ./
3.require 的包後必須帶版本號,replace中可帶可不帶

require go-crud/conf v0.0.0
replace go-crud/conf => ./conf


# Golang 解決 golang.org/x/ 下包下載不下來的問題

由於衆所周知的原因,golang在下載golang.org的包時會出現訪問不了的情況。尤其是x包,很多庫都依賴於它。由於x包在github上都有鏡像,我們可以使用從github.com上先clone下來,再做軟鏈接的方式曲線救國。
mkdir -p $GOPATH/src/github.com/golang/
git clone https://github.com/golang/sys.git $GOPATH/src/github.com/golang/sys
git clone https://github.com/golang/net.git $GOPATH/src/github.com/golang/net
git clone https://github.com/golang/text.git $GOPATH/src/github.com/golang/text
git clone https://github.com/golang/lint.git $GOPATH/src/github.com/golang/lint
git clone https://github.com/golang/tools.git $GOPATH/src/github.com/golang/tools
git clone https://github.com/golang/crypto.git $GOPATH/src/github.com/golang/crypto

ln -s $GOPATH/src/github.com/golang/ $GOPATH/src/golang.org/x

git clone https://github.com/golang/context.git $GOPATH/src/github.com/golang/context
ln -s /usr/bin/go $GOPATH/src/golang.org/x
ln -s /usr/bin/go /usr/local/go/bin/go
ln -s /usr/bin/X11/go /usr/local/go/bin/go

supervisorctl 後臺任務進程管理

supervisor能把一個普通進程變爲後臺daemon進程,並監控進程狀態,在進程異常退出時能夠自動重啓(或者告警),同時還提供一些相關的管理功能
1.查詢所有進程狀態:
supervisorctl status
2.啓. 停. 重啓業務進程,tomcat爲進程名,即[program:tomcat]裏配置的值:
supervisorctl start tomcat
supervisorctl stop tomcat
supervisorctl restart tomcat
3.管理全部進程:
supervisorctl start all
supervisorctl stop all
supervisorctl restart all
4.重新加載配置文件,停止原有進程並按新的配置啓動所有進程(注意:所有進程會停止並重啓,線上操作慎重)
supervisorctl reload
5.根據最新的配置文件,啓動新配置或有改動的進程,配置沒有改動的進程不會受影響而被重啓(注意:這纔是線上可以操作的命令,不會重啓原有進程)
supervisorctl update

#把stderr重定向到stdout,默認false;
stdout_logfile=/data/log/tomcat/out-memcache.log
#標準日誌輸出;
stderr_logfile=/data/log/tomcat/err-memcache.log

systemctl 服務管理

systemctl enable servicename    開機啓動服務
systemctl disable servicename    停止開機啓動服務
systemctl start/stop/restart servicename    啓動/停止/重啓服務
systemctl reload servicename    重新加載配置文件
systemctl status servicename    查看服務狀態
systemctl -a    列出所有服務的狀態
systemctl list-units    列出當前系統服務狀態
systemctl list-unit-files    列出服務的狀態
systemctl list-dependencies servicename    列出服務的依賴關係
systemctl list-sockets    顯示套接字文件
systemctl list-timers    列出定時器
systemctl cat servicename    查看服務的配置文件
systemctl show-environment    查看環境變量
systemd-analyze blame    顯示每個進程消耗時間
systemd-analyze plot    生成網頁

架構

好的架構不是設計出來的,而是進化而來的:
(1)流量小的時候,我們要提高開發效率,可以在早期要引入ORM,DAO;
(2)流量變大,可以使用動靜分離. 讀寫分離. 主從同步. 垂直拆分. CDN. MVC等方式不斷提升網站的性能和研發效率;
(3)面對更大的流量時,通過垂直拆分. 服務化. 反向代理. 開發框架(站點/服務)等等手段,可以不斷提升高可用(研發效率);
(4)在面對上億級的流量時,通過配置中心. 柔性服務. 消息總線. 自動化(迴歸,測試,運維,監控)來迎接新的挑戰;

1.所有的網絡調用沒有拋出最原始error信息。(經過加工之後的日誌會嚴重誤導人。)
2.超時時間的設置未能起到作用,未經過完整的壓測和故障演練,所以超時時間很容易無效。
3.內外網域名沒有隔離,需要區分內外網調用,做好環境隔離。
4.http服務器本身的超時沒有設置,如果程序內部出現問題導致處理超時,併發會把服務器拖垮。
5.系統一旦上雲之後整個網絡架構變得複雜,干擾因素太多,排查也會面臨比較大的依賴,對雲上的調用鏈路和網絡架構需要非常熟悉,這樣才能快速定位問題。

系統架構的目標是解決利益相關者的關注點


架構是這樣定義的:
1.每個系統都有一個架構
2.架構由架構元素以及相互之間的關係構成
3.系統是爲了滿足利益相關者(stakeholder)的需求而構建的
4.利益相關者都有自己的關注點(concerns)
5.架構由架構文檔描述
6.架構文檔描述了一系列的架構視角
7.每個視角都解決並且對應到利益相關者的關注點。


1.soft skills are always hard than hard skills,軟技能比硬技能難
2.choosing relationship over correctness ,注重關係重於誰對誰錯
3.架構的政治性,在中大型公司裏工作的架構師尤其要學習

政治指的是和他人協作將事情搞定的藝術,架構是一種社交活動,在技術的世界裏,個人主義很容易被打敗,即使你的目的是好的技術是最優的,技術決策是政治決策(technical decisions are political decisions),一個技術產品,一波人可以做,另一波人也可以做,到底誰做的好,真不好說,不管誰做,都給業務套上了一副手銬。

架構系統前,架構師的首要任務是盡最大可能找出所有利益相關者,業務方,產品經理,客戶 / 用戶,開發經理,工程師,項目經理,測試人員,運維人員,產品運營人員等等都有可能是利益相關者,架構師要充分和利益相關者溝通,深入理解他們的關注點和痛點,並出架構解決這些關注點。
最小可用產品(Minimum Viable Product, MVP)理念
收集 -> 測量 -> 調整 -> 閉環重複,在有測量數據和反饋的基礎上,系統. 應用. 流程和客戶體驗纔有可能獲得持續的提升和改善,否則沒有數據的所謂改進只能靠拍腦袋或者說猜測。
微服務更多是關於組織和團隊,而不是技術

反向面試

#職責
On-call (電話值班)的計劃或者規定是什麼?值班或者遇到問題加班時候有加班費嗎?
我的日常工作是什麼?
團隊裏面初級和高級工程師的比例是多少?(有計劃改變嗎)
入職培訓會是什麼樣的?
自己單獨的開發活動和按部就班工作的比例大概是怎樣的?
每天預期/核心工作時間是多少小時?
在你看來,這個工作做到什麼程度算成功?
我入職的崗位是新增還是接替之前離職的同事?(是否有技術債需要還)?(zh)
入職之後在哪個項目組,項目是新成立還是已有的?(zh)
#技術
公司常用的技術棧是什麼?
你們怎麼使用源碼控制系統?
你們怎麼測試代碼?
你們怎麼追蹤 bug?
你們怎麼集成和部署代碼改動?是使用持續集成和持續部署嗎?
你們的基礎設施搭建方法在版本管理系統裏嗎?或者是代碼化的嗎?
從計劃到完成一項任務的工作流是什麼樣的?
你們如何準備故障恢復?
有標準的開發環境嗎?是強制的嗎?
你們需要花費多長時間來給產品搭建一個本地測試環境?(分鐘/小時/天)
你們需要花費多長時間來響應代碼或者依賴中的安全問題?
所有的開發者都可以使用他們電腦的本地管理員權限嗎?
公司是否有技術分享交流活動?有的話,多久一次呢?(zh)
#團隊
工作是怎麼組織的?
團隊內/團隊間的交流通常是怎樣的?
如果遇到不同的意見怎樣處理?
誰來設定優先級 / 計劃?
如果被退回了會怎樣?(“這個在預計的時間內做不完”)
每週都會開什麼類型的會議?
產品/服務的規劃是什麼樣的?(n週一發佈 / 持續部署 / 多個發佈流 / ...)
生產環境發生事故了怎麼辦?是否有不批評人而分析問題的文化?
有沒有一些團隊正在經歷還尚待解決的挑戰?
公司技術團隊的架構和人員組成?(zh)
#公司
有沒有會議/旅行預算?使用的規定是什麼?
晉升流程是怎樣的?要求/預期是怎樣溝通的?
技術和管理兩條職業路徑是分開的嗎?
對於多元化招聘的現狀或者觀點是什麼?
有公司級別的學習資源嗎?比如電子書訂閱或者在線課程?
有獲取證書的預算嗎?
公司的成熟度如何?(早期尋找方向 / 有內容的工作 / 維護中 / ...)
我可以爲開源項目做貢獻嗎?是否需要審批?
有競業限制或者保密協議需要籤嗎?
你們認爲公司文化中的空白是什麼?
能夠跟我說一公司處於不良情況,以及如何處理的故事嗎?
#商業
你們現在盈利嗎?
如果沒有的話,還需要多久?
公司的資金來源是什麼?誰影響或者指定高層計劃或方向?
你們如何掙錢?
什麼阻止了你們掙更多的錢?
你們認爲什麼是你們的競爭優勢?
#遠程工作
遠程工作和辦公室工作的比例是多少?
公司提供硬件嗎?更新計劃如何?
額外的附件和家居可以通過公司購買嗎?這方面是否有預算?
有共享辦公或者上網的預算嗎?
多久需要去一次辦公室?
公司的會議室是否一直爲視頻會議準備着?
辦公室工作
辦公室的佈局如何?(開放的 / 小隔間 / 獨立辦公室)
有沒有支持/市場/或者其他需要大量打電話的團隊在我的團隊旁邊辦公?
#待遇
如果有獎金計劃的話,獎金如何分配?
如果有獎金計劃的話,過去的幾年裏通常會發百分之多少的獎金?
有五險一金或者其他退休養老金等福利嗎?如果有的話,公司有配套的商業保險嗎?
帶薪休假
帶薪休假時間有多久?
病假和事假是分開的還是一起算?
我可以提前使用假期時間嗎?也就是說應休假期是負的?
假期的更新策略是什麼樣的?也就是說未休的假期能否滾入下一週期
照顧小孩的政策如何?
無薪休假政策是什麼樣的?

shell的藝術

https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh.md

在 Bash 中,可以通過按 Tab 鍵實現自動補全參數,使用 ctrl-r 搜索命令行歷史記錄(按下按鍵之後,輸入關鍵字便可以搜索,重複按下 ctrl-r 會向後查找匹配項,按下 Enter 鍵會執行當前匹配的命令,而按下右方向鍵會將匹配項放入當前行中,不會直接執行,以便做出修改)。

在 Bash 中,可以按下 ctrl-w 刪除你鍵入的最後一個單詞,ctrl-u 可以刪除行內光標所在位置之前的內容,alt-b 和 alt-f 可以以單詞爲單位移動光標,ctrl-a 可以將光標移至行首,ctrl-e 可以將光標移至行尾,ctrl-k 可以刪除光標至行尾的所有內容,ctrl-l 可以清屏。鍵入 man readline 可以查看 Bash 中的默認快捷鍵。內容有很多,例如 alt-. 循環地移向前一個參數,而 alt-* 可以展開通配符。

pstree -p 以一種優雅的方式展示進程樹

使用 netstat -lntp 或 ss -plat 檢查哪些進程在監聽端口(默認是檢查 TCP 端口; 添加參數 -u 則檢查 UDP 端口)或者 lsof -iTCP -sTCP:LISTEN -P -n (這也可以在 OS X 上運行)。

lsof 來查看開啓的套接字和文件。
strace  跟蹤一個進程的系統調用或信號產生的情況
ltrace  跟蹤進程調用庫函數的情況
lsblk 列出塊設備信息:以樹形展示你的磁盤以及磁盤分區信息
lshw,lscpu,lspci,lsusb 和 dmidecode:查看硬件信息,包括 CPU. BIOS. RAID. 顯卡. USB設備等
lsmod 和 modinfo 列出內核模塊,並顯示其細節
pmap -d $pid
ps aux|grep $pid
top -p $pid
cat /proc/$pid/status 
ps aux | sort -k4nr | head -n 10 
htop -p $pid    # top 的加強版

# 查看CPU信息(型號)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
# 查看物理CPU個數
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每個物理CPU中core的個數(即核數)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看邏輯CPU的個數
cat /proc/cpuinfo| grep "processor"| wc -l
expr:計算表達式或正則匹配
m4:簡單的宏處理器
yes:多次打印字符串
cal:漂亮的日曆
env:執行一個命令(腳本文件中很有用)
printenv:打印環境變量(調試時或在寫腳本文件時很有用)
look:查找以特定字符串開頭的單詞或行
cut,paste 和 join:數據修改
fmt:格式化文本段落
pr:將文本格式化成頁/列形式
fold:包裹文本中的幾行
column:將文本格式化成多個對齊. 定寬的列或表格
expand 和 unexpand:製表符與空格之間轉換
nl:添加行號
seq:打印數字
bc:計算器
factor:分解因數
gpg:加密並簽名文件
toe:terminfo 入口列表
nc:網絡調試及數據傳輸
socat:套接字代理,與 netcat 類似
slurm:網絡流量可視化
dd:文件或設備間傳輸數據
file:確定文件類型
tree:以樹的形式顯示路徑和文件,類似於遞歸的 ls
stat:文件信息
time:執行命令,並計算執行時間
timeout:在指定時長範圍內執行命令,並在規定時間結束後停止進程
lockfile:使文件只能通過 rm -f 移除
logrotate: 切換. 壓縮以及發送日誌文件
watch:重複運行同一個命令,展示結果並/或高亮有更改的部分
when-changed:當檢測到文件更改時執行指定命令。參閱 inotifywait 和 entr。
tac:反向輸出文件
shuf:文件中隨機選取幾行
comm:一行一行的比較排序過的文件
strings:從二進制文件中抽取文本
tr:轉換字母
iconv 或 uconv:文本編碼轉換
split 和 csplit:分割文件
sponge:在寫入前讀取所有輸入,在讀取文件後再向同一文件寫入時比較有用,例如 grep -v something some-file | sponge some-file
units:將一種計量單位轉換爲另一種等效的計量單位(參閱 /usr/share/units/definitions.units)
apg:隨機生成密碼
xz:高比例的文件壓縮
ldd:動態庫信息
nm:提取 obj 文件中的符號
ab 或 wrk:web 服務器性能分析
strace:調試系統調用
mtr:更好的網絡調試跟蹤工具
cssh:可視化的併發 shell
rsync:通過 ssh 或本地文件系統同步文件和文件夾
wireshark 和 tshark:抓包和網絡調試工具
ngrep:網絡層的 grep
host 和 dig:DNS 查找
lsof:列出當前系統打開文件的工具以及查看端口信息
dstat:系統狀態查看
glances:高層次的多子系統總覽
iostat:硬盤使用狀態
mpstat: CPU 使用狀態
vmstat: 內存使用狀態
htop:top 的加強版
last:登入記錄
w:查看處於登錄狀態的用戶
id:用戶/組 ID 信息
sar:系統歷史數據
iftop 或 nethogs:套接字及進程的網絡利用情況
ss:套接字數據
dmesg:引導及系統錯誤信息
sysctl: 在內核運行時動態地查看和修改內核的運行參數
hdparm:SATA/ATA 磁盤更改及性能分析
lsblk:列出塊設備信息:以樹形展示你的磁盤以及磁盤分區信息
lshw,lscpu,lspci,lsusb 和 dmidecode:查看硬件信息,包括 CPU. BIOS. RAID. 顯卡. USB設備等
lsmod 和 modinfo:列出內核模塊,並顯示其細節
fortune,ddate 和 sl:額,這主要取決於你是否認爲蒸汽火車和莫名其妙的名人名言是否“有用”

網絡調試

# tracepath 122.235.81.5
 1?: [LOCALHOST]                                         pmtu 1500
 1:  no reply
 2:  no reply
 3:  11.208.177.13                                        11.165ms asymm  1
 4:  11.208.176.178                                       30.852ms asymm  2
 5:  116.251.117.174                                       0.690ms asymm  3
 6:  116.251.113.33                                        1.123ms asymm  4
 7:  150.138.130.117                                       0.978ms asymm  5
 8:  150.138.128.185                                       6.510ms asymm  6
 9:  202.97.13.49                                         17.593ms asymm  7
10:  61.164.23.254                                        19.454ms asymm  9
11:  61.164.4.103                                         32.944ms asymm 10
12:  122.235.81.5                                         23.153ms reached

# mtr 122.235.81.5
 Host                                                                                                         Loss%   Snt   Last   Avg  Best  Wrst StDev
 1. ???
 2. ???
 3. 11.208.176.157                                                                                             0.0%    12    0.8   1.9   0.7  13.3   3.5
 4. 11.208.177.254                                                                                             0.0%    12   58.5  37.4   0.9  75.4  33.0
 5. 116.251.117.170                                                                                            0.0%    12    1.2   2.0   1.1   6.7   1.4
 6. 103.41.143.114                                                                                             0.0%    12    2.5   1.4   1.2   2.5   0.3
 7. 150.138.130.113                                                                                            0.0%    12    0.9   1.0   0.9   1.3   0.0
 8. 150.138.128.113                                                                                            0.0%    12   11.1  11.2   9.0  21.3   3.5
 9. 202.97.39.25                                                                                              16.7%    12   24.7  25.7  24.7  32.3   2.2
10. 220.191.143.177                                                                                           54.5%    12   22.3  22.3  22.2  22.5   0.0
11. 61.164.4.101                                                                                               0.0%    12   27.5  51.7  27.4 245.8  64.3
12. 122.235.81.5                                                                                               0.0%    11   22.4  22.7  22.3  24.4   0.4

神器 strace

strace能做什麼:

它可以基於特定的系統調用或系統調用組進行過濾
它可以通過統計特定系統調用的使用次數,所花費的時間,以及成功和錯誤的數量來分析系統調用的使用。
它跟蹤發送到進程的信號。
可以通過pid附加到任何正在運行的進程。
調試性能問題,查看系統調用的頻率,找出耗時的程序段
查看程序讀取的是哪些文件從而定位比如配置文件加載錯誤問題
查看某個php腳本長時間運行“假死”情況
當程序出現“Out of memory”時被系統發出的SIGKILL信息所kill
另外因爲strace拿到的是系統調用相關信息,一般也即是IO操作信息,這個對於排查比如cpu佔用100%問題是無能爲力的。這個時候就可以使用GDB工具了。

strace參數:

-c 統計每一系統調用的所執行的時間,次數和出錯的次數等. 
-d 輸出strace關於標準錯誤的調試信息. 
-f 跟蹤由fork調用所產生的子進程. 
-ff 如果提供-o filename,則所有進程的跟蹤結果輸出到相應的filename.pid中,pid是各進程的進程號. 
-F 嘗試跟蹤vfork調用.在-f時,vfork不被跟蹤. 
-h 輸出簡要的幫助信息. 
-i 輸出系統調用的入口指針. 
-q 禁止輸出關於脫離的消息. 
-r 打印出相對時間關於,,每一個系統調用. 
-t 在輸出中的每一行前加上時間信息. 
-tt 在輸出中的每一行前加上時間信息,微秒級. 
-ttt 微秒級輸出,以秒了表示時間. 
-T 顯示每一調用所耗的時間. 
-v 輸出所有的系統調用.一些調用關於環境變量,狀態,輸入輸出等調用由於使用頻繁,默認不輸出. 
-V 輸出strace的版本信息. 
-x 以十六進制形式輸出非標準字符串 
-xx 所有字符串以十六進制形式輸出. 
-a column 
設置返回值的輸出位置.默認 爲40. 
-e expr 
指定一個表達式,用來控制如何跟蹤.格式如下: 
[qualifier=][!]value1[,value2]... 
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用來限定的符號或數字.默認的 qualifier是 trace.感嘆號是否定符號.例如: 
-eopen等價於 -e trace=open,表示只跟蹤open調用.而-etrace!=open表示跟蹤除了open以外的其他調用.有兩個特殊的符號 all 和 none. 
注意有些shell使用!來執行歷史記錄裏的命令,所以要使用\\. 
-e trace= 
只跟蹤指定的系統 調用.例如:-e trace=open,close,rean,write表示只跟蹤這四個系統調用.默認的爲set=all. 
-e trace=file 
只跟蹤有關文件操作的系統調用. 
-e trace=process 
只跟蹤有關進程控制的系統調用. 
-e trace=network 
跟蹤與網絡有關的所有系統調用. 
-e strace=signal 
跟蹤所有與系統信號有關的 系統調用 
-e trace=ipc 
跟蹤所有與進程通訊有關的系統調用 
-e abbrev= 
設定 strace輸出的系統調用的結果集.-v 等與 abbrev=none.默認爲abbrev=all. 
-e raw= 
將指 定的系統調用的參數以十六進制顯示. 
-e signal= 
指定跟蹤的系統信號.默認爲all.如 signal=!SIGIO(或者signal=!io),表示不跟蹤SIGIO信號. 
-e read= 
輸出從指定文件中讀出 的數據.例如: 
-e read=, 
-e write= 
輸出寫入到指定文件中的數據. 
-o filename 
將strace的輸出寫入文件filename 
-p pid 
跟蹤指定的進程pid. 
-s strsize 
指定輸出的字符串的最大長度.默認爲32.文件名一直全部輸出. 
-u username 
以username 的UID和GID執行被跟蹤的命令

window shell

netstat -ano    查看所有的端口占用
netstat -ano|findstr "3306" 
tasklist|findstr "pid" 找到進程名稱,
taskkill /f /t /im 進程名稱  結束進程
strace -p 也可以再window上用
wmic 神器....

hdparm:SATA/ATA 磁盤更改及性能分析,

hdparm -t /dev/sda  測試硬盤的讀取速度
hdparm -T /dev/xvda 測試硬盤緩存的讀取速度
{
hdparm [-CfghiIqtTvyYZ][-a <快取分區>][-A <0或1>][-c <I/O模式>][-d <0或1>][-k <0或1>][-K <0或1>][-m <分區數>][-n <0或1>][-p <PIO模式>][-P <分區數>][-r <0或1>][-S <時間>][-u <0或1>][-W <0或1>][-X <傳輸模式>][設備]

-a<快取分區> 設定讀取文件時,預先存入塊區的分區數,若不加上<快取分區>選項,則顯示目前的設定。
-A<0或1> 啓動或關閉讀取文件時的快取功能。
-c<I/O模式> 設定IDE32位I/O模式。
-C 檢測IDE硬盤的電源管理模式。
-d<0或1> 設定磁盤的DMA模式。
-f 將內存緩衝區的數據寫入硬盤,並清楚緩衝區。
-g 顯示硬盤的磁軌,磁頭,磁區等參數。
-h 顯示幫助。
-i 顯示硬盤的硬件規格信息,這些信息是在開機時由硬盤本身所提供。
-I 直接讀取硬盤所提供的硬件規格信息。
-k<0或1> 重設硬盤時,保留-dmu參數的設定。
-K<0或1> 重設硬盤時,保留-APSWXZ參數的設定。
-m<磁區數> 設定硬盤多重分區存取的分區數。
-n<0或1> 忽略硬盤寫入時所發生的錯誤。
-p<PIO模式> 設定硬盤的PIO模式。
-P<磁區數> 設定硬盤內部快取的分區數。
-q 在執行後續的參數時,不在屏幕上顯示任何信息。
-r<0或1> 設定硬盤的讀寫模式。
-S<時間> 設定硬盤進入省電模式前的等待時間。
-t 評估硬盤的讀取效率。
-T 評估硬盤快取的讀取效率。
-u<0或1> 在硬盤存取時,允許其他中斷要求同時執行。
-v 顯示硬盤的相關設定。
-W<0或1> 設定硬盤的寫入快取。
-X<傳輸模式> 設定硬盤的傳輸模式。
-y 使IDE硬盤進入省電模式。
-Y 使IDE硬盤進入睡眠模式。
-Z 關閉某些Seagate硬盤的自動省電功能。

查看CPU信息

# 總核數 = 物理CPU個數 X 每顆物理CPU的核數 
# 總邏輯CPU數 = 物理CPU個數 X 每顆物理CPU的核數 X 超線程數
# 查看物理CPU個數
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每個物理CPU中core的個數(即核數)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看邏輯CPU的個數
cat /proc/cpuinfo| grep "processor"| wc -l
# 查看CPU信息(型號)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c

}

python雜記

# pycharm sphinx-quickstart 生成API文檔
https://www.cnblogs.com/combfish/p/10297987.html

pip install line_profiler
安裝之後kernprof.py會加到環境變量中。
line_profiler可以統計每行代碼的執行次數和執行時間等,時間單位爲微妙。
1.在需要測試的函數加上@profile裝飾,這裏我們把測試代碼寫在C:\Python34\test.py文件上.
2.運行命令行:kernprof -l -v C:\Python34\test.py

pip install psutil # 需要先安裝 psutil 模塊
pip install memory_profiler
memory_profiler 模塊能夠逐行測量內存的佔用情況
python -m memory_profiler cp02/demo01.py

# 這些路徑都是錯誤的,會被應用logger的文件影響
log_path = os.path.realpath(os.getcwd()) + '/logs/'
print "log_path:", log_path
log_path = os.path.abspath(os.getcwd()) + '/logs/'
print "log_path:", log_path
log_path = '../logs/'
print "log_path:", log_path
# 以下爲正確的
log_path = os.path.split(os.path.realpath(__file__))[0] + '/../logs/'  # 固定文件路徑
print "log_path:", log_path
log_path = os.path.dirname(os.path.realpath(__file__)) + '/../logs/'  # 固定文件路徑
print "log_path:", log_path

pip show sphinx # 查看包信息


# 動態導入庫
mp = sys.modules.get('multiprocessing')
if mp is not None:
    # Errors may occur if multiprocessing has not finished loading
    # yet - e.g. if a custom import hook causes third-party code
    # to run when multiprocessing calls import. See issue 8200
    # for an example
    try:
        self.processName = mp.current_process().name
    except StandardError:
        pass
fi

# Python 中如何實現自動導入缺失的庫
https://my.oschina.net/u/4051725/blog/3123190 

# python logging日誌模塊以及多進程日誌 的幾種處理方式
https://blog.csdn.net/ll641058431/article/details/86446366

# uwsgi日誌按天切割
https://www.jianshu.com/p/6609fc915139

# 監聽事件
import time
from sqlalchemy import event
from sqlalchemy.engine import Engine


@event.listens_for(Engine, "before_cursor_execute")
def before_cursor_execute(conn, cursor, statement,
                          parameters, context, executemany):
    conn.info.setdefault('query_start_time', []).append(time.time())
    statement = "/*node1*/ " + statement
    print("Start Query: ", statement)


@event.listens_for(Engine, "after_cursor_execute")
def after_cursor_execute(conn, cursor, statement,
                         parameters, context, executemany):
    total = time.time() - conn.info['query_start_time'].pop(-1)
    print("Query Complete!")
    print("Total Time:", total)

# 優化器提示,使用 Select.prefix_with() 和 Query.prefix_with() ::
select(...).prefix_with("/*+ NO_RANGE_OPTIMIZATION(t4 PRIMARY) */")


用flask時遇到了返回字符串支持中文顯示的問題,在web端顯示的是utf-8的編碼,而不是中文
雖然不影響接口的讀取,但是可讀性太差,於是研究了一下怎麼直接顯示成中文。最後找到了解決方案如下,
在配置中加入下面一行代碼就OK了。
app.config['JSON_AS_ASCII'] = False
json.dumps()解決同樣的問題可以加入ensure_ascii=False

查詢服務鏈接狀態

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

CLOSED:無連接是活動的或正在進行  
LISTEN:服務器在等待進入呼叫  
SYN_RECV:一個連接請求已經到達,等待確認  
SYN_SENT:應用已經開始,打開一個連接  
ESTABLISHED:正常數據傳輸狀態  
FIN_WAIT1:應用說它已經完成  
FIN_WAIT2:另一邊已同意釋放  
ITMED_WAIT:等待所有分組死掉  
CLOSING:兩邊同時嘗試關閉  
TIME_WAIT:另一邊已初始化一個釋放  
LAST_ACK:等待所有分組死掉

通過修改內核參數使服務端的連接儘快釋放

vi /etc/sysctl.conf  
net.ipv4.tcp_syncookies = 1  # 表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN攻擊,默認爲0,表示關閉
net.ipv4.tcp_tw_reuse=1 #讓TIME_WAIT狀態可以重用,這樣即使TIME_WAIT佔滿了所有端口,也不會拒絕新的請求造成障礙 默認是0  
net.ipv4.tcp_tw_recycle=1 #表示開啓TCP連接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉。  
net.ipv4.tcp_fin_timeout=30  
/sbin/sysctl -p 讓修改生效  

別名IP

ifconfig eth0:1 192.168.209.22 broadcast 192.168.209.255 netmask 255.255.255.0 up
route add -host 192.168.209.22 dev eth0:1
ifconfig eth0:1 down


# 輔助IP
ip addr add 192.168.40.20/24 dev eth0
ip addr del 192.168.40.20/24 dev eth0


ifconfig eth1:0 115.28.27.232 netmask 255.255.252.0 up
route add -host 115.28.27.232 dev eth1:0

ip addr show
ip addr

## 遠程轉發,本地代理10.30.108.193:6379,通過118.190.87.8轉發
ssh -L 6379:10.30.108.193:6379 [email protected] -p 8100

ssh -L <local port>:<remote host>:<remote port> <SSH server host>   # 本地轉發
ssh -R <local port>:<remote host>:<remote port> <SSH server host>   # 遠程轉發

先把數據結構搞清楚,程序的其餘部分自現。—— David Jones

sar 診斷系統瓶頸

sar(System Activity Reporter系統活動情況報告)是目前 Linux 上最爲全面的系統性能分析工具之一,可以從多方面對系統的活動進行報告,包括:文件的讀寫情況、 系統調用的使用情況、磁盤I/O、CPU效率、內存使用狀況、進程活動及IPC有關的活動等
# sar命令常用格式
sar [options] [-A] [-o file] t [n]
其中:
t爲採樣間隔,n爲採樣次數,默認值是1;
-o file表示將命令結果以二進制格式存放在文件中,file 是文件名。

options 爲命令行選項,sar命令常用選項如下:
-A:所有報告的總和
-u:輸出CPU使用情況的統計信息
-v:輸出inode、文件和其他內核表的統計信息
-d:輸出每一個塊設備的活動信息
-r:輸出內存和交換空間的統計信息
-b:顯示I/O和傳送速率的統計信息
-a:文件讀寫情況
-c:輸出進程統計信息,每秒創建的進程數
-R:輸出內存頁面的統計信息
-y:終端設備活動情況
-w:輸出系統交換活動信息

要判斷系統瓶頸問題,有時需幾個 sar 命令選項結合起來
懷疑CPU存在瓶頸,可用 sar -u 和 sar -q 等來查看
懷疑內存存在瓶頸,可用 sar -B、sar -r 和 sar -W 等來查看
懷疑I/O存在瓶頸,可用 sar -b、sar -u 和 sar -d 等來查看

#常用命令彙總,因版本和平臺不同,有部分命令可能沒有或顯示結果不一致:

默認監控: sar 5 5     #  CPU和IOWAIT統計狀態 
sar -b 5 5        # IO傳送速率
sar -B 5 5        # 頁交換速率
sar -c 5 5        # 進程創建的速率
sar -d 5 5        # 塊設備的活躍信息
sar -n DEV 5 5    # 網路設備的狀態信息
sar -n SOCK 5 5   # SOCK的使用情況
sar -n ALL 5 5    # 所有的網絡狀態信息
sar -P ALL 5 5    # 每顆CPU的使用狀態信息和IOWAIT統計狀態 
sar -q 5 5        # 隊列的長度(等待運行的進程數)和負載的狀態
sar -r 5 5       # 內存和swap空間使用情況
sar -R 5 5       # 內存的統計信息(內存頁的分配和釋放、系統每秒作爲BUFFER使用內存頁、每秒被cache到的內存頁)
sar -u 5 5       # CPU的使用情況和IOWAIT信息(同默認監控)
sar -v 5 5       # inode, file and other kernel tablesd的狀態信息
sar -w 5 5       # 每秒上下文交換的數目
sar -W 5 5       # SWAP交換的統計信息(監控狀態同iostat 的si so)
sar -x 2906 5 5  # 顯示指定進程(2906)的統計信息,信息包括:進程造成的錯誤、用戶級和系統級用戶CPU的佔用情況、運行在哪顆CPU上
sar -y 5 5       # TTY設備的活動狀態
將輸出到文件(-o)和讀取記錄信息(-f)


sar也可以監控非實時數據,通過cron週期的運行到指定目錄下
例如:我們想查看本月27日,從0點到23點的內存資源.
sa27就是本月27日,指定具體的時間可以通過-s(start)和-e(end)來指定.
sar -f /var/log/sa/sa27 -s 00:00:00 -e 23:00:00 -r

go 編譯

# go help build
講到go build編譯,不能不提跨平臺編譯,Go提供了編譯鏈工具,可以讓我們在任何一個開發平臺上,編譯出其他平臺的可執行文件。
默認情況下,都是根據我們當前的機器生成的可執行文件,比如你的是Linux 64位,就會生成Linux 64位下的可執行文件,比如我的Mac;可以使用go env查看編譯環境
# go env
GOARCH="amd64"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"

GOOS=linux GOARCH=386 go tool compile -S main.go >> main.S 就可以獲取了main.go的彙編版本。

注意裏面兩個重要的環境變量GOOS和GOARCH,其中GOOS指的是目標操作系統,它的可用值爲:
darwin
freebsd
linux
windows
android
dragonfly
netbsd
openbsd
plan9
solaris
一共支持10種操作系統。GOARCH指的是目標處理器的架構,目前支持的有:
arm
arm64
386
amd64
ppc64
ppc64le
mips64
mips64le
s390x
# 具體組合參考:
https://golang.org/doc/install/source#environment
# 如果我們要生成不同平臺架構的可執行程序,只要改變這兩個環境變量就可以了,比如要生成Linux 64位的程序,命令如下:
GOOS=linux GOARCH=amd64 go build flysnow.org/hello
前面兩個賦值,是更改環境變量,這樣的好處是隻針對本次運行有效,不會更改我們默認的配置。
更多關於go build的用戶可以通過以下命令查看:go help build


nil 是go語言中預先定義的標識符, 沒有默認類型,但它有許多可能的類型,對於編譯器來說,必須從上下文中獲取充足的信息才能推斷出nil的類型。
nil可以代表很多類型的零值,在go語言中,nil可以代表下面這些類型的零值:
    指針類型(包括unsafe中的)
    map類型
    slice類型
    function類型
    channel類型
    interface類型

true和false的默認類型是bool
iota的預先定義類型是int
不同類型的nil值佔用的內存大小可能是不一樣的
兩個不同類型的nil值可能無法進行比較
在go語言中map,slice和function不能比較。比較兩個無法比較類型的值(包含nil)是非法的。
對nil channel,map,slice和array 指針進行range操作也是合法的。
nil只能賦值給指針、channel、func、interface、map或slice類型的變量 (非基礎類型) 否則會引發 panic


# 鏈接:https://www.jianshu.com/p/174aa63b2cc5  Go語言中的Nil

碎碎念

先把數據結構搞清楚,程序的其餘部分自現。—— David Jones

清晰的數據結構,清晰的概念

學習的過程是:例子(問題+答案)-> 知識 –> 新問題檢驗 –> 反饋

模擬情景
心理表徵
模型類比
刻意練習
小幅迭代
對比反饋

<軟技能-代碼之外的生存指南>
1)瞭解全局
2)確定範圍
3)定義目標
4)尋找資源
5)創建學習計劃
6)篩選資源
7)開始學習,淺嘗輒止
8)動手操作,邊學邊玩
9)全面掌握,學以致用
10)樂爲人師,融會貫通

在鬥爭中,有這麼四個原則是我要向大家推薦的:
第一原則,絕對不要隨意擴大斗爭對象,鬥爭對象要儘可能指向單個人或少部分人。這是一條基本原則,一定要注意
第二原則,鬥爭訴求一定要非常明確。訴求點要有先後順序,抓緊把優先級高的訴求先實現了,不能實現的可以往後放。解決問題是個時間過程而不是一個時間點
第三原則,鬥爭的奧義是不要試圖去說服或者壓服你的鬥爭對象,他不可能被你說服。你鬥爭過程中的全部表演都是爲了爭取第三方和旁觀者
第四原則,不要輕易威脅你的鬥爭對象,但是隻要威脅了就一定要保證自己有能力做到

自帶的redis性能測試工具

redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

goland 遠程調試

# window上的goland參考此處配置
https://www.520mwx.com/view/53702
本地進入IDE,在要調試的地方打上斷點,然後run--debug--eidit configurations-->添加remote主機信息和調試用的端口8200。
# 將代碼sync到服務器的對應目錄下
export GOPROXY=https://goproxy.io
# 構建主程序可執行文件
go build -o demo.exe
# 構建dlv工具
git clone https://github.com/go-delve/delve.git
go build -o dlv
# 開啓遠程調試程序
dlv --listen=:8200 --headless=true --api-version=2 --accept-multiclient exec ./demo

# ps
go build -gcflags=all="-N -l"  ## 必須這樣編譯,才能用dlv打印出變量,第二個是小寫的L,不是大寫的i
阿里雲機器上的github比較快,可以代理下使用

docker常用知識

# 常用命令
docker ps         # 查看正在運行的容器
docker ps -a      # 查看所有容器
docker ps -l      # 查看最近一次運行的容器

docker search busybox   # 搜索Busybox鏡像(集成了100多個最常用Linux命令的軟件工具箱,精簡的UNIX工具集)
docker pull busybox     # 下載Busybox鏡像
docker images      # 查看鏡像
docker rmi 鏡像名  # 刪除鏡像
docker build -t 鏡像名:鏡像版本 -f Dockerfile .   # 依據Dockerfile構建鏡像
docker create 容器名或者容器ID    # 創建容器
docker start [-i] 容器名        # 啓動容器
docker run 容器名或者容器ID       # 運行容器,相當於docker create + docker start
    docker run -it -v /var/data:/abc myos   # 主機卷的映射--docker容器不保持任何數據,重要數據請使用外部卷存儲(數據持久化)容器可以掛載真實機目錄或共享存儲爲卷.
    docker run -it -v /mnt/nfs/:/zhuhaiyan 192.168.6.153:5000/myos  # 使用共享存儲的映射
    docker run -idt --name busybox1 busybox cal # 運行busybox容器,並運行 cal 命令
    docker run -p 8300:8300 -itd -v /home/lgj/gopath/gf-demos:/* webserver2 # 冒號":"前面的目錄是宿主機目錄,後面的目錄是容器內目錄。端口映射
    docker run -d --name nginx1.1 -p 8080:80 hub.c.163.com/library/nginx  # 主機的8080端口映射到容器中的80端口
    docker run -a stdin -a stdout -i -t ubuntu /bin/bash
    docker run -t -i 鏡像名:v2 /bin/bash
    
docker attach 容器名或者容器ID bash     # 進入容器的命令行(退出容器後容器會停止)
docker exec -it 容器名或者容器ID bash   # 進入容器的命令行
docker stop 容器名                    # 停止容器
docker rm 容器名                      # 刪除容器

docker top 容器名                    # 查看WEB應用程序容器的進程
docker inspect 容器名                # 查看Docker的底層信息
docker logs -tf 容器名    #查看容器應用的實時日誌
docker logs --tail="10" 容器名 # 打印容器mytest應用後10行的內容

# dockerfile1
```
FROM scratch
ADD rootfs.tar.xz /
COPY main main
EXPOSE 8080
CMD ["./main"]
```
# dockerfile2
```
FROM docker.io/alpine

RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.6/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.6/community/" >> /etc/apk/repositories
RUN apk update
RUN apk add bash vim
```

# 參考
https://my.oschina.net/zhizhisoft/blog/2966531  # 重點來了! CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . 必須通過此命令構建的二進制文件才能不依賴bash.sh等等啥啊執行.
https://www.cnblogs.com/sap-jerry/p/10029824.html
https://www.runoob.com/docker/docker-image-usage.html
https://segmentfault.com/a/1190000021051021#articleHeader16
https://www.runoob.com/docker/docker-run-command.html   # docker命令大全

docker 打包go程序步驟

1. 創件dockerfile文件命名爲Dockerfile.scratch
```
# 使用scratch開啓
FROM scratch
# 將內部程序輸出映射到外界
RUN ln -sf /dev/stdout /xx/xx.log \ # info
    && ln -sf /dev/stderr /xx/xx.log # error
# 拷貝編譯程序
COPY main main
# 拷貝依賴的配置文件
ADD config/config.toml config.toml
# 打開8080端口
EXPOSE 8080
# 運行!
CMD ["./main"]
```

2. 使用go程序編寫一個web服務
```
package main

import (
"fmt"
"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "hello world!")
}

func main() {
        http.HandleFunc("/", handler)
        fmt.Println("服務端口: 8080")
        http.ListenAndServe(":8080", nil)
}
```
3. 編譯程序. 創建鏡像. 運行服務

$ go build main.go
$ sudo docker build -t webserver -f Dockerfile.scratch .
$ sudo docker run webserver
standard_init_linux.go:190: exec user process caused "no such file or directory"
運行程序會報以上錯誤,原因是cgo需要libc庫,使用以下命令重新編譯運行:

$ CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
$ sudo docker build -t webserver -f Dockerfile.scratch .
$ sudo docker run -p 8080:8080 webserver
服務端口: 8080
成功開啓docker容器的 go web服務

4. 因爲使用了最簡單的鏡像,沒安裝各種依賴,就是把go程序當做一個可執行文件直接執行的,
所以要是go程序中有依賴其他什麼東西如路徑,配置,文件,系統命令啥的都可能報錯.

docker 容器裏的進程爲什麼要前臺運行?

《第一本Docker書》講到Docker容器啓動web服務時,都指定了前臺運行的參數,例如apache:
ENTRYPOINT [ "/usr/sbin/apache2" ]
CMD ["-D", "FOREGROUND"]
又例如nginx:
ENTRYPOINT [ "/usr/sbin/nginx", "-g", "daemon off;" ]
爲什麼要這麼做呢?因爲Docker容器僅在它的1號進程(PID爲1)運行時,會保持運行。如果1號進程退出了,Docker容器也就退出了。
(1)容器中運行多個守護進程時,前面的進程要用後臺方式運行(或添加 &),否則後面的服務無法啓動
(2)容器中最後一個守護進程一定要用前臺方式運行,否則start.sh退出,容器退出,所有的服務就白啓動了

大多數情況下,我們啓動一個Docker容器,只讓它運行一個前臺程序,並且保證它不會退出,當容器檢查到內部沒有運行的前臺進程之後,自己就會自動退出。
docker run .... --restart=always

在Linux系統啓動之後,第一個啓動的用戶態進程是/sbin/init ,它的PID是1,其餘用戶態的進程都是init進程的子進程。Supervisor在Docker容器裏面充當的就類似init進程的角色,其它的應用進程都是Supervisor進程的子進程。通過這種方法就可以實現在一個容器中啓動運行多個應用。

https://blog.csdn.net/u010039418/article/details/83749762

秒殺系統基本架構

# 層級    產品  解決方案
應用層 瀏覽器、APP 瀏覽器緩存、本地緩存(sqllite,localstorage)、按鈕控制(過濾垃圾流量)、圖形驗證碼(防止接口刷)
網絡層 網絡路由    CDN (超大併發秒殺很有必要、靜態資源,節省服務器帶寬)
負載層 Nginx   負載均衡、動靜分離、反向代理緩存、限流
服務層 java應用  動態頁面靜態化(讓瀏覽器可以緩存)、應用緩存、分佈式緩存、異步、隊列、限流、分佈式鎖
數據庫 oracle、mysql    原子操作保障(樂觀鎖、悲觀鎖)

# 限流算法
1. 令牌桶:(處理突發流量)
以一定速率填充令牌(填滿了則丟棄),另外一邊去拿令牌,拿到令牌的可以進行下一步操作,沒拿到令牌的直接拒絕

2. 漏桶:(處理速率恆定)
流入水滴的速率任意,桶底按常量速率流出水滴如果流入速率過快、超過了桶的容量、則直接丟棄水滴

# 方案
1. 客戶端過濾垃圾流量
2. nginx 動靜分離(反向代理圖片)、負載均衡、限流
    {
    https://blog.csdn.net/hellow__world/article/details/78658041
    https://blog.csdn.net/dongl890426/article/details/83863763
    # 樣例
    imit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        location  /search/ {
            limit_req zone=one burst=5 nodelay;
       }
    }
    
    $binary_remote_addr :表示通過remote_addr這個標識來做限制,“binary_”的目的是縮寫內存佔用量,是限制同一客戶端ip地址
    zone=one:10m:表示生成一個大小爲10M,名字爲one的內存區域,用來存儲訪問的頻次信息
    rate=1r/s:表示允許相同標識的客戶端的訪問頻次,這裏限制的是每秒1次,即每秒只處理一個請求,還可以有比如30r/m的,即限制每2秒訪問一次,即每2秒才處理一個請求。
    zone=one :設置使用哪個配置區域來做限制,與上面limit_req_zone 裏的name對應
    burst=5:重點說明一下這個配置,burst爆發的意思,這個配置的意思是設置一個大小爲5的緩衝區當有大量請求(爆發)過來時,超過了訪問頻次限制的請求可以先放到這個緩衝區內等待,但是這個等待區裏的位置只有5個,超過的請求會直接報503的錯誤然後返回。
    nodelay:
    如果設置,會在瞬時提供處理(burst + rate)個請求的能力,請求超過(burst + rate)的時候就會直接返回503,永遠不存在請求需要等待的情況。(這裏的rate的單位是:r/s)
    如果沒有設置,則所有請求會依次等待排隊

    limit_req zone=req_zone;
    嚴格依照在limti_req_zone中配置的rate來處理請求
    超過rate處理能力範圍的,直接drop
    表現爲對收到的請求無延時

    limit_req zone=req_zone burst=5;
    依照在limti_req_zone中配置的rate來處理請求
    同時設置了一個大小爲5的緩衝隊列,在緩衝隊列中的請求會等待慢慢處理
    超過了burst緩衝隊列長度和rate處理能力的請求被直接丟棄
    表現爲對收到的請求有延時

    limit_req zone=req_zone burst=5 nodelay;
    依照在limti_req_zone中配置的rate來處理請求
    同時設置了一個大小爲5的緩衝隊列,當請求到來時,會爆發出一個峯值處理能力,對於峯值處理數量之外的請求,直接丟棄
    在完成峯值請求之後,緩衝隊列不能再放入請求。如果rate=10r/m,且這段時間內沒有請求再到來,則每6 s 緩衝隊列就能回覆一個緩衝請求的能力,直到回覆到能緩衝5個請求位置。
    }

3. 分佈式限流(redis + lua , nginx + lua)
4. 服務層再次限流
5. 原子減庫存
6. 隊列、異步
7. 數據庫鎖 (select version from table from table where id = 1,update table set count = count -1 ,version = version + 1 where id = 1 and version = version)帶重試樂觀鎖、不帶重試的樂觀鎖(併發情況下成功率太低)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章