Skip to main content

· 12 min read
w0x7ce

df

df命令可以获取硬盘被占用了多少空间,目前还剩下多少空间等信息,它也可以显示所有文件系统对i节点和磁盘块的使用情况。

df命令各个选项的含义如下:
  -a:显示所有文件系统的磁盘使用情况,包括0块(block)的文件系统,如/proc文件系统。
  -k:以k字节为单位显示。
  -i:显示i节点信息,而不是磁盘块。
  -t:显示各指定类型的文件系统的磁盘空间使用情况。
  -x:列出不是某一指定类型文件系统的磁盘空间使用情况(与t选项相反)。
  -T:显示文件系统类型。
ubuntu@VM-HK-w0x7ce:~$ df
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 202488 968 201520 1% /run
/dev/vda2 51538380 6022796 45499200 12% /
tmpfs 1012440 24 1012416 1% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 202488 4 202484 1% /run/user/1000

第1列是代表文件系统对应的设备文件的路径名(一般是硬盘上的分区);第2列给出分区包含的数据块(1024字节)的数目;第3,4列分别表示已用的和可用的数据块数目。

第3,4列块数之和不一定等于第2列中的块数。这是因为默认的每个分区都留了少量空间供系统管理员使用的缘故。即使遇到普通用户 空间已满的情况,管理员仍能登录和留有解决问题所需的工作空间。清单中Use%列表示普通用户空间使用的百分比,若这一数字达到100%,分区仍然留有系 统管理员使用的空间。

最后,Mounted on列表示文件系统的安装点。

du (disk usage)

disk usage 含义为显示磁盘空间的使用情况,统计目录(或文件)所占磁盘空间的大小。该命令的功能是逐级进入指定目录的每一个子目录并显示该目录占用文件系统数据块(1024字节)的情况。若没有给出指定目录,则对当前目录进行统计。

du命令各个选项的含义如下:  
-s:对每个Names参数只给出占用的数据块总数。
-a:递归地显示指定目录中各文件及子目录中各文件占用的数据块数。若既不指定-s,也不指定-a,则只显示Names中的每一个目录及其中的各子目录所占的磁盘块数。
-b:以字节为单位列出磁盘空间使用情况(系统默认以k字节为单位)。
-k:以1024字节为单位列出磁盘空间使用情况。
-c:最后再加上一个总计(系统默认设置)。
-l:计算所有的文件大小,对硬链接文件,则计算多次。
-x:跳过在不同文件系统上的目录不予统计。
ubuntu@VM-HK-w0x7ce:/etc$ du -h ./apt
12K ./apt/trusted.gpg.d
4.0K ./apt/keyrings
64K ./apt/apt.conf.d
4.0K ./apt/auth.conf.d
4.0K ./apt/preferences.d
4.0K ./apt/sources
4.0K ./apt/sources.list.d
104K ./apt

tune2fs

tune2fs 命令用于调整文件系统的参数,是 ext2 及 ext3 文件系统常用的调整工具。

df命令各个选项的含义如下:
-c 次数 #挂载多少次后运行硬盘检查命令
-e 行为 #发现错误时的行为,包括continue(继续)、remount-on(挂载成只读)、panic(导致内核不稳定)
-f #及时发现错误,仍强制执行
-i 时间 #检查的时间间隔, d 为天数, m 为月数, w 为周数
-j #新建 ext3 日志式的文件系统
-l #显示文件系统的相关信息
-L 标签 #指定文件系统的标签名称
-m 保留比例 #指定对硬盘的保留比例,默认为 5%

查看文件系统信息

root@VM-HK-w0x7ce:/home/ubuntu# tune2fs -l /dev/vda2
tune2fs 1.46.5 (30-Dec-2021)
Filesystem volume name: Disk_One
Last mounted on: /
Filesystem UUID: 7bccaefa-b039-4ff6-bd32-22dde0066c0b
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 3276800
Block count: 13106683
Reserved block count: 0
Overhead clusters: 66747
Free blocks: 12042633
Free inodes: 3179795
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Reserved GDT blocks: 1019
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
Flex block group size: 16
Filesystem created: Sun Apr 24 20:03:06 2022
Last mount time: Thu Jul 28 09:59:27 2022
Last write time: Fri Aug 12 12:45:27 2022
Mount count: 11
Maximum mount count: -1
Last checked: Sun Apr 24 20:03:06 2022
Check interval: 0 (<none>)
Lifetime writes: 13 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
First orphan inode: 15612
Default directory hash: half_md4
Directory Hash Seed: 06aeded3-785f-4aaa-8100-d3e54f41d421
Journal backup: inode blocks
Checksum type: crc32c
Checksum: 0xf004571c

显示卷 & 更改卷名字

root@VM-HK-w0x7ce:/home/ubuntu# tune2fs -l /dev/vda2 | grep volume
Filesystem volume name: <none>
root@VM-HK-w0x7ce:/home/ubuntu# tune2fs -L w0x7ce_disk_01 /dev/vda2
tune2fs 1.46.5 (30-Dec-2021)
root@VM-HK-w0x7ce:/home/ubuntu# tune2fs -l /dev/vda2 | grep volume
Filesystem volume name: w0x7ce_disk_01

改变预留空间比例

root@VM-HK-w0x7ce:/home/ubuntu# tune2fs -m 1 /dev/vda2
tune2fs 1.46.5 (30-Dec-2021)
Setting reserved blocks percentage to 1% (131066 blocks)

案例分析

root@slave01:~# df -h
Filesystem Size Used Avail Use% Mounted on
udev 63G 0 63G 0% /dev
tmpfs 13G 2.8M 13G 1% /run
/dev/sda4 221G 217G 4.8G 100% /
tmpfs 63G 0 63G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 63G 0 63G 0% /sys/fs/cgroup
/dev/loop1 1.9M 1.9M 0 100% /snap/shadowsocks-libev/508
/dev/loop5 56M 56M 0 100% /snap/core18/2538
/dev/loop4 114M 114M 0 100% /snap/core/13425
/dev/sda2 1.9G 100M 1.6G 6% /boot
/dev/sda1 952M 4.4M 947M 1% /boot/efi
/dev/sda3 215G 185G 20G 91% /home
/dev/sdb 3.6T 2.8T 668G 81% /storage
/dev/loop2 560M 560M 0 100% /snap/pycharm-community/293
tmpfs 13G 0 13G 0% /run/user/1000
/dev/loop3 224M 224M 0 100% /snap/code/104
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf/merged
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797/merged
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/2e5c611e27c16368f4383de5c8ac6ae560f34d64160f08eb9a9e1e433daa6ac4/merged
tmpfs 13G 0 13G 0% /run/user/1008
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/84b5916793a1773e5835462fdd0467acb3576e94743cdc79c9e08504ac52ca31/merged
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/5a7005e5cefa0a120fccb4855eab9bff258c6a950166faac2fd22c8cf2979484/merged
overlay 221G 214G 4.8G 98% /var/lib/docker/overlay2/3ab0a88edd37a7e5df24d68b4e5f59f0aee2f01419b9a6f82b982e3f7e89ef79/merged
tmpfs 13G 0 13G 0% /run/user/1011
tmpfs 13G 0 13G 0% /run/user/0

Step 1 在根目录下寻找 大于 500M 的文件

find . -size +500M -print0 | xargs -0 du -h > /root/AA.log
vim /root/AA.log

#type
:g/{STRING}/d
#global 文字 delete 删除 /storage /xxx 不相关行

然后 删除对应无用文件

Step 2 根据 Filesystem 查看可疑文件系统

overlay

首先 利用mount 查看 overlay 对应的路径

root@slave01:/var/lib/docker/overlay2# mount -t  overlay
overlay on /var/lib/docker/overlay2/38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/VPU3WEBK7ZSS4CAIEG2WSIDEWG:/var/lib/docker/overlay2/l/HJSGHVFPEIXPODVB2G6SGCVUKX:/var/lib/docker/overlay2/l/LQIBNX7UBIZU2AKHNK2G6V2KLV:/var/lib/docker/overlay2/l/KGEOYKQ734GFQEKUWZCSE6KFSL,upperdir=/var/lib/docker/overlay2/38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf/diff,workdir=/var/lib/docker/overlay2/38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf/work)
overlay on /var/lib/docker/overlay2/28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/DHEKFL6D46UEDBR5PHWHN6UEHH:/var/lib/docker/overlay2/l/SNN7A2T7ZBXYKW2SXBQKSIX67C:/var/lib/docker/overlay2/l/FYK374GFEJZGCQQW2ALAIRHVSO:/var/lib/docker/overlay2/l/7HACMERHIGQR7JZQQGJNCKNUS7:/var/lib/docker/overlay2/l/QS6R2DYIBTBQRHOVGB4VHAWPV6:/var/lib/docker/overlay2/l/FKTA7IQF4JNBOFNRG353Q4T22C:/var/lib/docker/overlay2/l/IAWRXYRJ4V67KBVYV2TI5M7M4M:/var/lib/docker/overlay2/l/Y4G4HGVVSYPCSPGILFDLB5ITYI:/var/lib/docker/overlay2/l/STDB5J7V3YO3XUK5XNT7D6FEOG:/var/lib/docker/overlay2/l/YPRRYJ5PGWZ6BQ5NSLMEBYPB4I:/var/lib/docker/overlay2/l/RCUOIVTEDAON5N3DP3BVUQVXBH:/var/lib/docker/overlay2/l/U2F73KIPTHDRJA7NZVNJT4KHLI,upperdir=/var/lib/docker/overlay2/28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797/diff,workdir=/var/lib/docker/overlay2/28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797/work)

留意到

/var/lib/docker/overlay2

pushd 进相关目录

du -h --max-depth=1

如下输出

root@slave01:/var/lib/docker/overlay2# du -h --max-depth=1
1.7G ./7129b703bd58ba9d0217e3770050b5bfba57cfef6548eda21f1dd3b9a3c572bf
40K ./28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797-init
24K ./86e5ce373c451d537975223605338f787a218d361a7292ea93e1ab667e28e644
3.8G ./4718a3ed58149a869dea349ae80c487584a8ab3dd16a5d9f385eaf15bdb18a3a
241M ./38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf
40K ./f39b75e04364d91c1ac074e3b797a670b9f8d419e693890b66967438fc7427e1-init
78M ./5cf6779b3682b5f40be1100134d3d6d6d763f1cc96193ad87b20ec20bbab301f
292K ./0df64755c145230dfad62016a000dc0d16302c868bf36e1c45af249af28eeaaa
18G ./f187076c8cc73e4212e7b59944af7665800961898f345c54d7210adddacdc0fe
18M ./bfd5b5212714fa1ea875934e2fcdadc77d295fc614ead0f5eb69b2bc58440a79
14G ./84b5916793a1773e5835462fdd0467acb3576e94743cdc79c9e08504ac52ca31
749M ./b23680886239a3b89d53948e1311bffa1c0e0dbaa0649f9dfc6df62b75c5c67d
32K ./48477f6ae9617edff67f43e59c9b546bb1a228fa0212231ac662b1a0f2cfe1d5
32K ./16ce11a5b972bba2b98cacd5609674e944e82770a79808040a297b70f951d238
116M ./1b207660bbd786106a86ad125b12fc0525ec51d602a6cfef8e3ff5f6567f7cd3
36K ./34253942384fd03637adbd7b959fab29e8e60c421f071e2a14f72452db97f1eb
18M ./94d362e3e7a1e6efee5d373008a19e9e3cc4578541cbb140a13eabba3ff66a96
70G ./28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797
40K ./36affaa6f22adb0d45e6b8f5c3ad9c92fbf50f0c53fc6518465c86a52429990f-init
29M ./80c6d1117ca7c8b64095c1e1f18bd7df9d916347031b6bd403521103443b7505
33M ./8dd21e66d906381cbb62062e2aac36e863ad1e373c39facd9f3764a9144c09c4
11G ./3ab0a88edd37a7e5df24d68b4e5f59f0aee2f01419b9a6f82b982e3f7e89ef79
244G .

这时 我们可以利用grep 来检索对应的docker

docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep "x"

如id含3的容器

root@slave01:/var/lib/docker/overlay2# docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep "3"
4637, /wanta7780, /var/lib/docker/overlay2/2e5c611e27c16368f4383de5c8ac6ae560f34d64160f08eb9a9e1e433daa6ac4/work
17106, /nn2, /var/lib/docker/overlay2/3ab0a88edd37a7e5df24d68b4e5f59f0aee2f01419b9a6f82b982e3f7e89ef79/work
15986, /chz, /var/lib/docker/overlay2/84b5916793a1773e5835462fdd0467acb3576e94743cdc79c9e08504ac52ca31/work
4384, /xpq, /var/lib/docker/overlay2/28bbbb41fef8d50f3ecf916b6134e3ba7e7348120fa78314df5ffdbe1dc7d797/work
38783, /portainer, /var/lib/docker/overlay2/38ce2a2c8fadbb345c6c88e4023e2553a15580cef2852c121098679f6c4c2abf/work

如果找不到相关的容器,可能这就是之前的残留文件,直接 删除删除即可。

通过 df -h 我们可以看到 Used 下降了很多

root@slave01:/var/lib/docker/overlay2# df -h
Filesystem Size Used Avail Use% Mounted on
udev 63G 0 63G 0% /dev
tmpfs 13G 2.9M 13G 1% /run
/dev/sda4 221G 214G 4.8G 100% /

最后修改预留空间为 1%

tune2fs -m 1 /dev/sda4
df -h

##可以看到
/dev/sda4 221G 214G 4.8G 98% /
root@slave01:/var/lib/docker/overlay2# sudo tune2fs -l /dev/sda4 | grep -i 'block count'
Block count: 59107328
Reserved block count: 591073

可以看出可用空间变多,完成空间释放

Tips

xargs (eXtended ARGuments)

  1. xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。

  2. xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。

  3. xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

  4. xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。

  5. xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。

xargs 一般是和管道一起使用。

命令格式:
somecommand |xargs -item command
参数:

-a file 从文件中读入作为 stdin

-e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。

-p 当每次执行一个argument的时候询问一次用户。

-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。

-t 表示先打印命令,然后再执行。

-i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。

-r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。

-s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。

-L num 从标准输入一次读取 num 行送给 command 命令。

-l 同 -L。

-d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。

-x exit的意思,主要是配合-s使用

example

find ./ -name "systemd*" | xargs -i cp -r {} {}.bak #寻找 systemd开头文件并备份

· 4 min read
w0x7ce

Colly & coinmarket

Colly 是什么,什么要用它,怎样利用它进行量化相关的应用

colly 是用Go 语言编写的功能强大的爬虫框架。 它提供简洁的API,拥有强劲的性能,可以自动处理cookie&session,还有提供灵活的扩展机制

Colly 本身不能做量化 但是 Colly可以更高效的帮助我们采集数据,为我们提供量化的弹药

Colly的使用

Colly的执行顺序

colly函式作用順序(Call order of callbacks)

  1. OnRequest 在发起请求前 可以进行Header相关的设定
  2. OnError 如果请求时候出现错误 在这里捕获它
  3. OnResponseHeaders 收到响应标头时候 我们需要做的东西写在这里
  4. OnResponse 收到响应回复的时候 我们要做的事情 写在这里
  5. OnHTML 收到相应为HTML格式时候(晚于OnResponse),进行goquerySelector篩選
  6. OnXML 收到相应为XML格式时候(晚于OnHTML),进行xpathQuery筛选
  7. OnScraped 抓取网页(类似于OnResponse),但在最后才进行调用

Colly 的安装

``bash     # 安装Golang     wget "https://go.dev/dl/go1.18.linux-amd64.tar.gz"     rm -rf /usr/local/go && tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz     export PATH=$PATH:/usr/local/go/bin     go version     ``

``bash # 启用 Go Modules 功能 go env -w GO111MODULE=on # 1. 七牛 CDN go env -w GOPROXY=https://goproxy.cn,direct # 2. 阿里云 go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct # 3. 官方 go env -w GOPROXY=https://goproxy.io,direct ``

``bash mkdir Crawl && pushd Crawl go mod init go get -u github.com/gocolly/colly/v2 go mod tidy ``

网络环境的配置

因为在国内 无法直接连接上数字货币的网站 所以 我们需要配置代理, 我们的本地代理为 socks5:/127.0.0.1:12999

如果没有搭建 可以 尝试在服务器上用snap 安装 shadowsocks

``bash sudo apt-get update && sudo apt-get upgrade -y sudo apt install snapd sudo snap install shadowsocks-libev sudo snap run shadowsocks-libev.ss-local -s server_ip -p server_port -l local_port -b 0.0.0.0 -k passwd -m method ``

完整代码

```golang
package main

import (
"fmt"
"log"
"strconv"

colly "github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/proxy"
excelize "github.com/xuri/excelize/v2"
)

type GG struct {
_url string
_name string
_now_price string
}

func main() {

num := 0
f := excelize.NewFile()

// Instantiate default collector
c := colly.NewCollector()
// Rotate two socks5 proxies
rp, err := proxy.RoundRobinProxySwitcher("socks5://127.0.0.1:12999", "socks5://127.0.0.1:12999")
if err != nil {
log.Fatal(err)
}
// 【设置代理IP】 ,这里使用的是轮询ip方式
c.SetProxyFunc(rp)

c.OnRequest(func(r *colly.Request) {
r.Headers.Set("Authority", "coinmarketcap.com")
r.Headers.Set("Cache-Control", "max-age=0")
r.Headers.Set("Sec-Ch-Ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"99\", \"Microsoft Edge\";v=\"99\"")
r.Headers.Set("Sec-Ch-Ua-Mobile", "?0")
r.Headers.Set("Sec-Ch-Ua-Platform", "\"Windows\"")
r.Headers.Set("Upgrade-Insecure-Requests", "1")
r.Headers.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39")
r.Headers.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
r.Headers.Set("Sec-Fetch-Site", "same-origin")
r.Headers.Set("Sec-Fetch-Mode", "navigate")
r.Headers.Set("Sec-Fetch-User", "?2")
r.Headers.Set("Sec-Fetch-Dest", "document")
r.Headers.Set("Referer", "https://coinmarketcap.com/all/views/all/")
r.Headers.Set("Accept-Language", "zh-TW,zh-HK;q=0.9,zh;q=0.8,en;q=0.7,zh-CN;q=0.6,en-GB;q=0.5,en-US;q=0.4")

})

c.OnResponse(func(r *colly.Response) {

})

c.OnHTML(".cmc-table__table-wrapper-outer tbody tr", func(e *colly.HTMLElement) {

DOGE := GG{}
if len(e.ChildText("td[class='name-cell']")) == 0 {
DOGE._url = "https://coinmarketcap.com" + e.ChildAttr("a[class='cmc-link']", "href")
DOGE._name = e.ChildText("a[class='cmc-table__column-name--name cmc-link']")
} else {
DOGE._url = "https://coinmarketcap.com" + e.ChildAttr("a[class='cmc-link']", "href")
DOGE._name = e.ChildText("td[class='name-cell']")
}

c_coin := colly.NewCollector()
c_coin.SetProxyFunc(rp)
c_coin.OnRequest(func(r *colly.Request) {
r.Headers.Set("Authority", "coinmarketcap.com")
r.Headers.Set("Cache-Control", "max-age=0")
r.Headers.Set("Sec-Ch-Ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"99\", \"Microsoft Edge\";v=\"99\"")
r.Headers.Set("Sec-Ch-Ua-Mobile", "?0")
r.Headers.Set("Sec-Ch-Ua-Platform", "\"Windows\"")
r.Headers.Set("Upgrade-Insecure-Requests", "1")
r.Headers.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39")
r.Headers.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
r.Headers.Set("Sec-Fetch-Site", "same-origin")
r.Headers.Set("Sec-Fetch-Mode", "navigate")
r.Headers.Set("Sec-Fetch-User", "?2")
r.Headers.Set("Sec-Fetch-Dest", "document")
r.Headers.Set("Referer", "https://coinmarketcap.com/all/views/all/")
r.Headers.Set("Accept-Language", "zh-TW,zh-HK;q=0.9,zh;q=0.8,en;q=0.7,zh-CN;q=0.6,en-GB;q=0.5,en-US;q=0.4")
})
c_coin.OnResponse(func(r *colly.Response) {
})
c_coin.OnHTML("div[class='priceValue ']", func(r *colly.HTMLElement) {
DOGE._now_price = string(r.Text)
})
c_coin.Visit(DOGE._url)

fmt.Print(DOGE._name, " ")
fmt.Print(DOGE._now_price, " ")
fmt.Println(DOGE._url)

var A_num string = "A" + strconv.Itoa(num)
B_price := "B" + strconv.Itoa(num)
C_url := "C" + strconv.Itoa(num)

f.SetCellValue("Sheet1", A_num, DOGE._name)
f.SetCellValue("Sheet1", B_price, DOGE._now_price)
f.SetCellValue("Sheet1", C_url, DOGE._url)

if err := f.SaveAs("Coin_price.xlsx"); err != nil {
fmt.Println(err)
}
num += 1

})

c.Visit("https://coinmarketcap.com/all/views/all/")

}
```

· 7 min read
w0x7ce

ab install

sudo apt-get install apache2-utils

ab 参数

-A auth-username:password
为服务器提供BASIC身份验证凭据。用户名和密码由一个单独分隔,:并通过wire base64编码发送。无论服务器是否需要它,都会发送该字符串(即,已发送401认证)。
-b windowsize
TCP发送/接收缓冲区的大小,以字节为单位。
-B local-address
在进行传出连接时绑定的地址。
-c concurrency
一次执行多个请求的数量。默认值是一次一个请求。
-C cookie-name=value
Cookie:在请求中添加一行。论证通常是一 对的形式。该字段是可重复的。name=value
-d
不显示“XX [ms]表中提供的百分比”。(遗产支持)。
-e csv-file
写一个逗号分隔值(CSV)文件,其中包含为每个百分比(从1%到100%)提供服务该百分比请求所用的时间(以毫秒为单位)。这通常比'gnuplot'文件更有用; 因为结果已经“装箱”了。
-f protocol
指定SSL / TLS协议(SSL2,SSL3,TLS1,TLS1.1,TLS1.2或ALL)。2.4.4及更高版本中提供了TLS1.1和TLS1.2支持。
-g gnuplot-file
将所有测量值写为'gnuplot'或TSV(Tab单独值)文件。这个文件可以很容易地导入到Gnuplot,IDL,Mathematica,Igor甚至Excel等软件包中。标签位于文件的第一行。
-h
显示使用信息。
-H custom-header
在请求中附加额外的标头。该参数是典型地在一个有效报头线的形式,含有一个冒号分隔的字段值对(即,"Accept-Encoding: zip/zop;8bit")。
-i
做HEAD请求而不是GET。
-k
启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。默认值是没有KeepAlive。
-l
如果响应的长度不恒定,请不要报告错误。这对动态页面很有用。适用于2.4.7及更高版本。
-m HTTP-method
请求的自定义HTTP方法。适用于2.4.10及更高版本。
-n requests
为基准测试会话执行的请求数。默认情况下只执行单个请求,这通常会导致非代表性的基准测试结果。
-p POST-file
包含POST数据的文件。记得还要设置-T。
-P proxy-auth-username:password
将BASIC身份验证凭据提供给代理路由。用户名和密码由一个单独分隔,:并通过wire base64编码发送。无论代理是否需要它,都会发送该字符串(即,已发送407代理身份验证)。
-q
处理超过150个请求时,每10%或100个请求左右ab输出进度计数stderr。该 -q标志将禁止这些消息。
-r
不要退出套接字接收错误。
-s timeout
套接字超时前等待的最大秒数。默认值为30秒。适用于2.4.4及更高版本。
-S
当平均值和中位数分别超过标准差的一倍或两倍时,不显示中值和标准差值,也不显示警告/错误消息。默认为min / avg / max值。(遗产支持)。
-t timelimit
用于基准测试的最大秒数。这意味着 -n 50000内部。使用此选项可在固定的总时间内对服务器进行基准测试。默认情况下没有时间限制。
-T content-type
用于POST / PUT数据的内容类型标头,例如。 application/x-www-form-urlencoded。默认是text/plain。
-u PUT-file
包含数据到PUT的文件。记得还要设置-T。
-v verbosity
设置详细级别 - 4以及上面打印标题信息,3上面打印响应代码(404,200等), 2以及上面打印警告和信息。
-V
显示版本号并退出。
-w
在HTML表格中打印结果。默认表格为两列宽,背景为白色。
-x <table>-attributes
用作...的属性的字符串<table>。插入属性。<table here >
-X proxy[:port]
使用代理服务器来处理请求。
-y <tr>-attributes
用作...的属性的字符串<tr>
-z <td>-attributes
用作...的属性的字符串<td>
-Z ciphersuite
指定SSL / TLS密码套件(请参阅openssl密码)

常用参数

-t timelimit  测试时间限制,单位秒
-s timeout 每个请求时间限制,单位秒
-v verbosity 日志输出级别,可以选择1, 2等,调试使用
-T content-type POST/PUT接口的content-type
-p postfile POST请求发送的数据文件

ab demo

ab -c 10 -n 100 -r -s 200 http://127.0.0.1:1080/

测试POST请求

  1. 以x-www-form-urlencoded形式发送

    ab -n 1000 -c 100 -p post.txt -T 'application/x-www-form-urlencoded' http://www.test.com/test/api

    假定需要发送的json数据为 {name : “hello,world”}。 post.txt文件内容:

    name=hello,world
  2. 以multipart/form-data形式发送

    ab -n 1000 -c 100 -p post.txt -T 'multipart/form-data; boundary=--WebKitFormBoundaryE19zNvXGzXaLvS5C' http://www.test.com/test/api

    post.txt文件内容如下:

    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
    Content-Disposition: form-data; name="name"

    hello,world
    ----WebKitFormBoundaryE19zNvXGzXaLvS5C
  • POST的文件内容可以通过postman测试接口来查看。
  • 性能测试得到的最重要的指标就是QPS(Requests per second),反映了接口的并发承受能力,也就是系统的峰值性能。如果对接口的调用超过了这一限制,就要考虑提升硬件或者做一些优化了。

参考文档:

  1. ab参数介绍:http://httpd.apache.org/docs/2.4/programs/ab.html
  2. 使用ab命令发送一个post请求:http://stackoverflow.com/questions/29731023/make-a-post-request-using-ab-apache-benchmarking-on-a-django-server
  3. 同上:http://stackoverflow.com/questions/20220270/posting-multipart-form-data-with-apache-bench-ab

· 3 min read
w0x7ce

安裝 colly

# 启用 Go Modules 功能
go env -w GO111MODULE=on
# 1. 七牛 CDN
go env -w GOPROXY=https://goproxy.cn,direct
# 2. 阿里云
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
# 3. 官方
go env -w GOPROXY=https://goproxy.io,direct
go get -u github.com/gocolly/colly/v2

Colly OnResponse


package main

import (
"fmt"
"strings"
"github.com/gocolly/colly"
)

var count int = 0

func main() {
c := colly.NewCollector() // 在colly中使用 Collector 這類物件 來做事情

c.OnResponse(func(r *colly.Response) { // 當Visit訪問網頁後,網頁響應(Response)時候執行的事情
// fmt.Println(string(r.Body)) // 返回的Response物件r.Body 是[]Byte格式,要再轉成字串
})

c.OnRequest(func(r *colly.Request) { // 需要寫這一段 User-Agent 降低被ban 可能性
r.Headers.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36")
})

// 當Visit訪問網頁後,在網頁響應(Response)之後、發現這是HTML格式 執行的事情
// F12 OnHTML 支持 class
c.OnHTML(".qa-list__title-link", func(e *colly.HTMLElement) { // 每找到一個符合 goquerySelector字樣的結果,便會進這個OnHTML一次
e.Text = strings.TrimSpace(e.Text)
fmt.Println(e.Text)
count++
})

c.Visit("https://ithelp.ithome.com.tw/users/20125192/ironman/3155") // Visit 要放最後
}

c.OnHTML

<title>...</title>
<meta name="..." content="...">
<h3 class="qa-list__title qa-list__title--ironman">Go繁不及備載<span> 系列</span></h3>
<a href="/users/20125192" id="account" data-account="gjlmotea">我的主頁</a>
  1. Tag 標籤

    c.OnHTML("title", func(e *colly.HTMLElement) {
    fmt.Println(e.Text)
    })
  2. Attr 屬性

    c.OnHTML("meta[name]", func(e *colly.HTMLElement) {
    fmt.Println(e)
    })
  3. AttrVal 屬性值

    name="description"這串屬性的content

    c.OnHTML("meta[name='description']", func(e *colly.HTMLElement) {
    fmt.Println(e.Attr("content")) // 抓此Tag中的name屬性 來找出此Tag,再印此Tag中的content屬性
    })
  4. CSS Class 名稱

    c.OnHTML(".qa-list__title-link", func(e *colly.HTMLElement) { // 每找到一個符合 goquerySelector字樣的結果,便會進這個OnHTML一次
    fmt.Println(e.Text)
    })

  5. CSS ID 唯一識別

    以 CSS來抓該 id底下的字

    c.OnHTML("#read_more", func(e *colly.HTMLElement) {
    fmt.Println(e.Text)
    })

執行順序

colly函式作用順序(Call order of callbacks)

  1. OnRequest 在發起請求之前,可以預先對Header的參數進行設定
  2. OnError 如果在請求的時候發生錯誤
  3. OnResponseHeaders 收到響應的標頭時
  4. OnResponse 收到響應回復的時候
  5. OnHTML 收到的響應是HTML格式時(時間點比 OnResponse還晚),進行goquerySelector篩選
  6. OnXML 收到的響應是XML格式時(時間點比 OnHTML還晚),進行xpathQuery篩選
  7. OnScraped 抓取網頁(與OnResponse相仿),但在最後才進行調用

· 2 min read
w0x7ce

Way 1 simple use ufoym/deepo

https://github.com/ufoym/deepo https://hub.docker.com/r/ufoym/deepo

Configure Docker

Step 1 Uninstall old version

 sudo apt-get remove docker docker-engine docker.io containerd runc

Step 2 Install latest docker

 sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
 sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Step 3 Install nvidia-docker

  1. Setting up NVIDIA Container Toolkit

    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
    && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
    && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
  2. To get access to experimental features such as CUDA on WSL or the new MIG capability on A100

    curl -s -L https://nvidia.github.io/nvidia-container-runtime/experimental/$distribution/nvidia-container-runtime.list | sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
  3. Install the nvidia-docker2

    sudo apt update
    sudo apt-get install -y nvidia-docker2
  4. Final restart

    sudo systemctl restart docker

Step 4 Select the verion depends on ur ENV

    nvidia-smi #view the cuda version if it's cuda10.2
docker pull ufoym/deepo:pytorch-cu102
nvidia-docker run --name w0x7ce -p 7789:22 -p 7791:7790 -it -v /storage:/data ufoym/deepo:pytorch-cu102

NOW it will work well !

USE note

docker start [tag]
docker attach [tag]
ctrl +p + q ## exit without stop the container
docker ps -a

Misc

中国内地使用可以配置镜像,以便加速下载

  • 请首先查看是否在 docker.service 文件中配置过镜像地址。

    $ systemctl cat docker | grep '\-\-registry\-mirror'
  • 如果该命令有输出,那么请执行 $ systemctl cat docker 查看 ExecStart= 出现的位置,修改对应的文件内容去掉 --registry-mirror 参数及其值,并按接下来的步骤进行配置。

  • 如果以上命令没有任何输出,那么就可以在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}

ci可用测试

· One min read
w0x7ce
https://www.anaconda.com/products/individual-d
bash Anaconda*sh
source <path to conda>/bin/activate and then run conda init

Use

conda create -n name python=3.7 -y
conda activate name

· One min read
w0x7ce

· 8 min read
w0x7ce
  • Web 應用的自動化打包和發布。
  • 自動化測試和持續集成、發布。
  • 在服務型環境中部署和調整數據庫或其他的後台應用。
  • 從頭編譯或者擴展現有的 OpenShift 或 Cloud Foundry 平台來搭建自己的 PaaS 環境。

Docker 的優點

Docker 是一個用於開發,交付和運行應用程序的開放平台。 Docker 使您能夠將應用程序與基礎架構分開,從而可以快速交付軟件。借助 Docker,您可以與管理應用程序相同的方式來管理基礎架構。通過利用 Docker 的方法來快速交付,測試和部署代碼,您可以大大減少編寫代碼和在生產環境中運行代碼之間的延遲。

  1. 快速,一致地交付您的應用程序 Docker 允許開發人員使用您提供的應用程序或服務的本地容器在標準化環境中工作,從而簡化了開發的生命週期。

容器非常適合持續集成和持續交付(CI / CD)工作流程,請考慮以下示例方案:

您的開發人員在本地編寫代碼,並使用 Docker 容器與同事共享他們的工作。

他們使用 Docker 將其應用程序推送到測試環境中,並執行自動或手動測試。

當開發人員發現錯誤時,他們可以在開發環境中對其進行修復,然後將其重新部署到測試環境中,以進行測試和驗證。

測試完成後,將修補程序推送給生產環境,就像將更新的鏡像推送到生產環境一樣簡單。

  1. 響應式部署和擴展 Docker 是基於容器的平台,允許高度可移植的工作負載。 Docker 容器可以在開發人員的本機上,數據中心的物理或虛擬機上,雲服務上或混合環境中運行。

Docker 的可移植性和輕量級的特性,還可以使您輕鬆地完成動態管理的工作負擔,並根據業務需求指示,實時擴展或拆除應用程序和服務。

  1. 在同一硬件上運行更多工作負載 Docker 輕巧快速。它為基於虛擬機管理程序的虛擬機提供了可行、經濟、高效的替代方案,因此您可以利用更多的計算能力來實現業務目標。 Docker 非常適合於高密度環境以及中小型部署,而您可以用更少的資源做更多的事情

Docker安裝

curl -sSL https://get.daocloud.io/docker | sh

Docker卸載

 sudo apt-get remove docker docker-engine docker.io containerd runc

Docker使用基礎

Docker Hello World

Docker 允許你在容器內運行應用程序, 使用 docker run 命令來在容器內運行一個應用程序。

輸出Hello world

w0x7ce@w0x7ce:~$ docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world

各個參數解析:

docker: Docker 的二進制執行文件。

run: 與前面的 docker 組合來運行一個容器。

ubuntu:15.10 指定要運行的鏡像,Docker 首先從本地主機上查找鏡像是否存在,如果不存在,Docker 就會從鏡像倉庫 Docker Hub 下載公共鏡像。

/bin/echo "Hello world": 在啟動的容器裡執行的命令

以上命令完整的意思可以解釋為:Docker 以 ubuntu15.10 鏡像創建一個新容器,然後在容器裡執行 bin/echo "Hello world",然後輸出結果。

運行交互式的容器

我們通過 docker 的兩個參數 -i -t,讓 docker 運行的容器實現"對話"的能力:

w0x7ce@w0x7ce:~$ docker run -i -t ubuntu:15.10 /bin/bash
root@0123ce188bd8:/#

各個參數解析:

-t: 在新容器內指定一個偽終端或終端。

-i: 允許你對容器內的標準輸入 (STDIN) 進行交互。

注意第二行 root@0123ce188bd8:/#,此時我們已進入一個 ubuntu15.10 系統的容器

我們嘗試在容器中運行命令 cat /proc/version和ls分別查看當前系統的版本信息和當前目錄下的文件列表

root@0123ce188bd8:/#  cat /proc/version
Linux version 4.4.0-151-generic (buildd@lgw01-amd64-043) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #178-Ubuntu SMP Tue Jun 11 08:30:22 UTC 2019
root@0123ce188bd8:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@0123ce188bd8:/#

我們可以通過運行 exit 命令或者使用 CTRL+D 來退出容器。

root@0123ce188bd8:/#  exit
exit
root@w0x7ce:~#

注意第三行中 root@w0x7ce:~# 表明我們已經退出了當前的容器,返回到當前的主機中。

啟動容器(後台模式)

使用以下命令創建一個以進程方式運行的容器

w0x7ce@w0x7ce:~$ docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63

在輸出中,我們沒有看到期望的 "hello world",而是一串長字符

2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63

這個長字符串叫做容器 ID,對每個容器來說都是唯一的,我們可以通過容器 ID 來查看對應的容器發生了什麼。

首先,我們需要確認容器有在運行,可以通過 docker ps 來查看:

w0x7ce@w0x7ce:~$ docker ps
CONTAINER ID IMAGE COMMAND ...
5917eac21c36 ubuntu:15.10 "/bin/sh -c 'while t…" ...

輸出詳情介紹:

CONTAINER ID: 容器 ID。

IMAGE: 使用的鏡像。

COMMAND: 啟動容器時運行的命令。

CREATED: 容器的創建時間。

STATUS: 容器狀態。

狀態有7種:

created(已創建)
restarting(重啟中)
running 或 Up(運行中)
removing(遷移中)
paused(暫停)
exited(停止)
dead(死亡)
PORTS: 容器的端口信息和使用的連接類型(tcp\udp)。

NAMES: 自動分配的容器名稱。

在宿主主機內使用 docker logs 命令,查看容器內的標準輸出:

w0x7ce@w0x7ce:~$ docker logs 2b1b7a428627
w0x7ce@w0x7ce:~$ docker logs amazing_cori

停止容器

我們使用 docker stop 命令來停止容器:

通過 docker ps 查看,容器已經停止工作:

w0x7ce@w0x7ce:~$ docker ps

可以看到容器已經不在了。

也可以用下面的命令來停止:

w0x7ce@w0x7ce:~$ docker stop amazing_cori

· One min read
w0x7ce

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
w0x7ce

這一些 傳頌着經典的歌

藏着了 太多太多寄望

在這刻 迷途在遠方他鄉

感謝你 歌聲裏伴我跨過