用于数据分析

A simple embedded language for running inline SQL in Python programs.

基于 duckdb ,可以方便的与 pandas 结合,可以方便的将 csv 导入,并用 sql 进行分析。

一个内网穿透工具

A modern, simple TCP tunnel in Rust that exposes local ports to a remote server, bypassing standard NAT connection firewalls.

类似花生壳,可以给内网做 dns 解析,便于做一些测试。

mkcert

用于生成 local 地址的 https 证书

关于站点地图的指南,可以参考: https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap

在这篇文档中,我觉得以下五个方面值得关注

一、lastmod 字段

文档中,我比较关注的内容是 lastmod。以前使用程序生成 sitemap 时,lastmod 的取值是站点地图的生成日期,仔细琢磨一下总觉得哪里有问题。对于搜索引擎来说,它最想了解的是该页面是否有更新,所以这个指的准确含义是该网页的 实质上 的最后更新时间。

sitemap.org 这样说,“对于许多动态 URL,您可以根据基础数据的更改时间或使用基于定期更新(如果适用)的一些近似值轻松计算 lastmod 日期。甚至使用近似日期或时间戳也可以帮助爬虫避免爬取未更改的 URL,这将降低 Web 服务器的带宽和 CPU 要求。“

总而言之,如果网页发生了实质内容的变更,希望搜索引擎进行更新,那么就可以更新这个时间戳,否则没有必要浪费爬虫的资源,以及服务器的带宽资源。

二、prioritychangefreq 字段

文档中提到,google 的爬虫将忽略这两个字段。

简单的想一下就可以理解,一方面这两个值生产方(站长)很难评估,另一方面,消费方(爬虫)很难按照这两个值执行。

所以,结论是,在 sitemap 中去掉这两个没用的值。

三、Url 的规范

  1. 使用一致且完全限定的网址,主要指的是比如 www 和非 www 的问题。
  2. 必须对站点地图文件进行 UTF-8 编码。
  3. 在站点地图中仅列出规范网址
  4. 非字母数字字符和非拉丁字符需要转义。
  5. 站点地图用于向 Google 建议您认为重要的网页,google 并不会保证爬取所有的页面。

四、通知 google 爬取

当站点的内容发生变更,站点地图进行了更新的时候,你可以主动的通知 google 来爬取。对于一个经常在更新的网站来说,google 会频繁的来爬取内容,但是如果一个网站的访问量较小,而且也没有太多的内容更新,google 就不会主动的来爬取,此时,通知 google 爬取算是一个可行的办法。

五、多语言

如果要做多语言站点,那么从 SEO 的角度也需要做一些考量。

  1. 如果您针对不同语言或区域提供了其他版本的网页,可以在站点地图或 HTML 标记中使用 hreflang 指明其他版本的网址。
  2. 关于这些变体的网页,需要做内容的翻译才行,具体的要求见:https://developers.google.com/search/docs/specialty/international/localized-versions

日志用途

Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。

Systemd 的日志文件是二进制格式的,必须使用 Journald 提供的 journalctl 来查看,默认不带任何参数时会输出系统和所有后台进程的混合日志。

默认日志最大限制为所在文件系统容量的 10%,可以修改 /etc/systemd/journald.conf 中的 SystemMaxUse 来指定该最大限制。

常用命令

# 查看所有日志(默认情况下 ,只保存本次启动的日志)
$ sudo journalctl

# 显示尾部的最新10行日志
$ sudo journalctl -n

# 显示尾部指定行数的日志
$ sudo journalctl -n 20

# 实时滚动显示最新日志
$ sudo journalctl -f

# 查看指定时间的日志
$ sudo journalctl --since="2012-10-30 18:17:16"
$ sudo journalctl --since "20 min ago"
$ sudo journalctl --since yesterday
$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"
$ sudo journalctl --since 09:00 --until "1 hour ago"


# 查看内核日志(不显示应用日志)
$ sudo journalctl -k

# 查看系统本次启动的日志
$ sudo journalctl -b
$ sudo journalctl -b -0

# 查看上一次启动的日志(需更改设置)
$ sudo journalctl -b -1


# 查看指定优先级(及其以上级别)的日志,共有8级 0: emerg 1: alert 2: crit 3: err 4: warning 5: notice 6: info 7: debug
$ sudo journalctl -p err -b

查看指定服务的日志


$ sudo journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
$ sudo journalctl _PID=1

# 查看某个路径的脚本的日志
$ sudo journalctl /usr/bin/bash

# 查看指定用户的日志
$ sudo journalctl _UID=33 --since today

# 查看某个 Unit 的日志
$ sudo journalctl -u nginx.service
$ sudo journalctl -u nginx.service --since today

# 实时滚动显示某个 Unit 的最新日志
$ sudo journalctl -u nginx.service -f

# 合并显示多个 Unit 的日志
$ journalctl -u nginx.service -u php-fpm.service --since today

查看格式

# 日志默认分页输出,--no-pager 改为正常的标准输出
$ sudo journalctl --no-pager

# 以 JSON 格式(单行)输出
$ sudo journalctl -b -u nginx.service -o json

# 以 JSON 格式(多行)输出,可读性更好
$ sudo journalctl -b -u nginx.serviceqq
 -o json-pretty

查看格式

# 显示日志占据的硬盘空间
$ sudo journalctl --disk-usage

# 仅保留500MB大小的日志文
$ sudo journalctl --vacuum-size=500M

# 指定日志文件保存多久
$ sudo journalctl --vacuum-time=1years

# 仅保留最近一个月的日志文件
$ sudo journalctl --vacuum-time=1m

# 仅保留最近2天的日志文件
$ sudo journalctl --vacuum-time=2d

如何清理

你可以通过以下命令减小日志的大小

sudo journalctl --vacuum-size=100M

这将保留最新的 100M 数据。

sudo journalctl --vacuum-time=10d

将删除除过去 10 天之外的所有内容。

如果您是一个github的使用者,那么你一定会接触到deploy key。github 使用 deploy key 来进行权限认证,被授予的机器才能有读或读写的能力。

如果你的server上只部署一个app的话,那用起来就很简单:

  1. 通过 ssh-keygen 命令生成rsa凭证到 .ssh/ 文件夹下
  2. 拷贝对应的公钥文件内容
  3. 进入 github 项目 Settings 中,选择左边栏 Deploy keys
  4. 点击 Add deploy keys,复制进去即可。

但是问题来了,如果你有多个项目部署在一个 server 上,如果使用同一个 ssh key,github 就会阻止,无法允许同样的 key 用于不同的项目,github 中一个 key 只能用来部署一个项目,这应该是出于安全的考虑。

那么,一个服务器上大多数情况下不可能只部署一个项目,遇到这种需求,要怎么做呢?

解决方案

官方也是给了解决方案的:

大致的方案是为每个存储库生成一个专用密钥对,在服务器的 SSH 配置文件(通常是~/.ssh/config)中,为每个存储库添加一个别名条目。

操作流程

1.选择一个目录,用于 git 项目 key 存储,比如 /home/user/.ssh/deploy/

2.为每个项目单独生成密钥,如下:

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/deploy/id_rsa_projecta
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/deploy/id_rsa_projecta
Your public key has been saved in /root/.ssh/deploy/id_rsa_projecta.pub
The key fingerprint is:
SHA256:TBeANn8XdDr/P7AljDf7hHvntleZTMlfJItEGZUkDCM [email protected]
The key's randomart image is:
+---[RSA 3072]----+
|       .E.+===+. |
|      +  . o=+o .|
|     . o. ..oo.+.|
|       o... oo.+.|
|        S. .o + =|
|           . *.*o|
|            ..B.o|
|             ooo=|
|             .o=B|
+----[SHA256]-----+

这样你就有了为项目单独生成的秘钥。

3.将生成的公钥添加到 github 项目的 deploy keys 中。

4.在 .ssh/ 文件夹下创建 config 文件,加入如下配置:

Host projecta
HostName github.com
User git
IdentityFile /home/.ssh/deploy/id_rsa_projecta

Host projecta 存储库的别名。
Hostname github.com 配置与别名一起使用的主机名。
IdentityFile=/home/user/.ssh/id_rsa_projecta 为别名分配私钥。

5.测试

ssh -vT projecta

在我们的电商站点的 google 分析中, 存在大量的 direct 流量, 这部分流量按照 google 给出的解释是用户直接输入网址进入网站或者没有正确获取到 referrer 请求头信息从而记录的.

为了能够准确的了解用户在从外站跳转到我站点时所发生的跳转过程, 分析 referrer 信息丢失的原因, 从而看是否能通过技术的手段调整这部分数据, 特别的进行一些测试.

1.在 shell 中使用 curl 模拟手机 user agent 请求 pc 端 http 链接, 使用 L 参数跟踪跳转, 跳转之后, referrer 保留.

curl -I http://www.dressafford.com/cheap-wedding-dresses.html --referrer http://www.guohuawei.com --user-agent "ipad" -L

84.17.41.94, 64.252.70.208 - - [12/Sep/2022:10:39:21 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 200 251938 "http://www.guohuawei.com" "ipad"

通过测试用例 1 , 我们可以发现, 默认情况下服务器端在跳转时, referrer 信息会携带.

2.在第三方网站页面中插入 pc 端 https 链接, 使用手机浏览器点击网页中的链接, 跳转之后, referrer 保留.

36.106.254.39, 64.252.111.201 - - [12/Sep/2022:10:54:42 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 200 24258 "https://www.guohuawei.com/" "Mozilla/5.0 (Linux; Android 10; GM1910) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36"

通过测试用例 2, 我们可以发现, 从 https 的 pc 跳转到 https 的 mobile 网站, referrer 信息不会丢失.

3.在第三方网站页面中插入 pc 端 http 链接, 使用手机浏览器(打开的时候强制是 https 站点)点击网页中的链接, 跳转之后, referrer 丢失.

36.106.254.39, 64.252.112.164 - - [12/Sep/2022:10:53:45 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 200 24258 "-" "Mozilla/5.0 (Linux; Android 10; GM1910) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36

4.在第三方网站页面中插入移动端 http 链接, 使用手机浏览器(打开的时候强制是 https 站点)点击网页中的链接, 跳转之后, referrer 丢失.

36.106.254.39, 64.252.111.212 - - [12/Sep/2022:10:55:47 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 200 24267 "-" "Mozilla/5.0 (Linux; Android 10; GM1910) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36"

5.在第三方网站页面中插入移动端 http 链接, 使用电脑访问第三方网站页面的 https 地址,点击链接, 跳转之后, referrer 没有传递, 下面记录的是 pc 端的请求日志, 日志里面已经没有了 referrer 信息, 也就是说在 https 页面中如果存在 http 链接, 点击跳转时, 属于降级, 浏览器不会将 referrer 信息携带到目标站点中, 这主要是处于安全性的考虑.

84.17.41.94, 64.252.72.154 - - [12/Sep/2022:11:52:06 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 302 142 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"

通过测试用例 3,4,5 我们可以发现, 如果 https 页面跳转到 http 页面, 会导致 referrer 信息丢失, 由于这次跳转是从外站到我站, 这个跳转是否允许 referrer 保留下来, 不能由我方决定.

6.在第三方网站页面中插入移动端 http 链接, 使用电脑访问第三方网站页面的 http 地址,点击链接, 跳转之后, referrer 保留了下来.

84.17.41.94, 64.252.121.127 - - [12/Sep/2022:13:58:12 +0000] "GET /cheap-wedding-dresses.html HTTP/1.1" 200 24258 "http://www.guohuawei.com/" "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"

通过测试用例 6 我们可以发现, 如果是从 http 跳转到 http 网站, 然后再次在同域名下 从 http 跳转到 https 下, referrer 信息得到了传递和保留.