之前的文章里面也总结过一些 fail2ban 的简单使用,这里就扩展开来,把一些常见的使用方式记录一下,以便后面回顾。
今天想起这件事情主要是看到日志发现新建的服务(非标准端口)也有人不断的扫描,尝试登录,虽然已经设置过 SSH,nginx 端口的 fail2ban,但是没有考虑到所有的服务端口。
sudo apt install fail2ban
fail2ban 的主要配置都集中在 /etc/fail2ban/
目录下
fail2ban 的功能可以分散在不同的文件中进行管理,配置优先顺序是:
jail.conf
jail.d/*.conf
jail.local
jail.d/*.local
在 jail.local
中配置
[ssh]
enabled = true
port = ssh, 10022
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
修改配置后可以使用如下方法来重新加载配置:
fail2ban-client reload
用上面的方法配置 ssh 后查看 Nginx access 日志还依然有非常多的 IP 再不停的扫描,所以想办法如果能把 fail2ban 的日志过滤出来然后再给 fail2ban 就可以把 fail2ban 中发现的 IP 再 block 掉。
参考该链接 中内容新增 filter,然后配置:
[fail2ban]
enabled = true
filter = fail2ban
action = iptables-allports[name=fail2ban]
logpath = /var/log/fail2ban.log
# findtime: 1 day
findtime = 86400
# bantime: 1 year
bantime = 31536000
解决方法来自 stackoverflow
查看状态:
fail2ban-client status
测试筛选规则设否匹配当前的日志格式 auth.log
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
用 iptables 来查看:
sudo iptables -L -v -n
[mysqld]
port = 3306
logpath = /var/log/mysql/error.log
log_warnings = 2
maxretry = 5
使用 Maven 来管理项目的依赖,带来便捷性的同时也引入了一些问题。对于一个大型项目来说,引用数十个依赖是经常遇到的。Maven 在管理这些依赖的时候,遵循一些基本原则,这就是这篇文章主要要定义的问题。另外如果项目中出现了依赖冲突,也是这篇文章的重点。
dependencyManagement 主要有两个作用
使用 dependencyManagement 声明依赖,实际项目并不会引入,因此子项目需要显示声明需要用的依赖
dependencies
即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项。父工程使用 dependencyManagement 假引用,目的是管理版本号。dependencies 用于实际上需要引入的工程,这些工程如果继承于父工程会找到对应的版本号。
maven 中的仓库分为两种,snapshot 快照仓库和 release 发布仓库。snapshot 快照仓库用于保存开发过程中的不稳定版本,release 正式仓库则是用来保存稳定的发行版本。定义一个组件或者模块为快照版本,只需要在 pom 文件中在该模块的版本号后加上 -SNAPSHOT
即可(注意这里必须是大写)。
在 distributionManagement 段中配置的是 snapshot 快照库和 release 发布库的地址
<distributionManagement>
<repository>
<id>central</id>
<name>artifactory-releases</name>
<url>releases-url</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>artifactory-snapshots</name>
<url>snapshots-releases</url>
</snapshotRepository>
</distributionManagement>
maven 区别对待 release 版本构件和 snapshot 版本,snapshot 为开发过程中版本,实时但不稳定。
一般来说发布到远程仓库还需要认证,没有任何配置信息,可能会得到 401 错误。所以还需要在 maven 的 settings.xml 文件中做如下配置:
<server>
<id>central</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
需要注意的是,settings.xml 中 server 元素下 id 的值必须与 POM 中 repository 或 snapshotRepository 下 id 的值完全一致。将认证信息放到 settings 下而非 POM 中,是因为 POM 往往是它人可见的,而 settings.xml 是本地的。配置完成后就可以通过 mvn deploy
进行发布了。
在之前的 Maven 介绍中也有提及,这边展开。
在之前的 maven 介绍 中指出来 Maven 的传递性依赖两个原则,第一就近原则,第二依赖路径距离一样则优先定义的依赖。
而当项目比较复杂之后,避免不了可能会出现打包时依赖的 jar 出现冲突。当引入新的依赖,发现项目中突然出现很多 method not found,或者 class not found 问题,基本上可以确定是因为依赖产生了冲突。
举一个比较直观的例子
加入我们的项目 A ,依赖 B, C 两个包,而 B ,C 各自依赖了 G1.0 和 G2.0 两个版本的包,那么 Maven 怎么选择?
Maven 的依赖传递会自动寻找到 B,C 两个依赖,并且发现依赖的 C,并自动引入,那么 G 会引入 1.0 还是 2.0 呢?这里就要引入 Maven 的第一个原则,最短路径优先
,这条原则是 A - B - C - D1.0 另外 A - E - D2.0 显然 Maven 会选择 D2.0,而显然在这个例子中是不行的;那么就要提到第二条原则,谁先定义则使用谁,所以在路径一致前提下,如果先定义了 A - B - G1.0,会选择 G1.0,而这个时候可能就会产生问题,命名我需要使用 G2.0 中新的方法和类,但是 G1.0 中并没有就会出现错误。
这个时候就需要通过下面的步骤来排查错误。
在项目启动时把所有的加载的 jar 包都打印出来,添加 VM 参数 -verbose:class
。通过打印的信息确认是否正确的 jar 包被依赖。
通过 maven 自带的工具来查看依赖树
mvn dependency:tree -Dverbose
通过查看其中可能导致冲突的 jar 包,然后使用 exclusions 来排除掉。
<dependency>
<groupId>info.einverne.chat</groupId>
<artifactId>common-biz</artifactId>
<version>1.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
上面提到的例子是一个很简单的演示,实际情况要比这个复杂许多,有的时候仅仅通过 mvn dependency:tree
可能无法快速的发现冲突,这个时候就可以尝试使用 Enforcer 插件,这个插件也可以自定义许多规则,我们可以使用 dependencyConvergence – ensures all dependencies converge to the same version.
来保证所有的依赖都使用相同的版本。
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<rules><dependencyConvergence/></rules>
</configuration>
</plugin>
</plugins>
在定义了插件之后就可以使用 mvn 的 goal —- mvn enforcer:enforce
来分析项目,会给出可能的冲突结果
Dependency convergence error for log4j:log4j:1.2.17 paths to dependency are:
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
+-org.slf4j:slf4j-log4j12:1.7.6
+-log4j:log4j:1.2.17
and
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
+-log4j:log4j:1.2.16
对于这个插件更多的介绍,可以查看另一篇插件的文章
可能是之前测试短域名生成服务的时候,添加了 http://localhost:8080
的跳转,导致了此后所有对该地址的访问都被重定向到了另一个网址,即使我在 8080 端口的服务已经停止,并且已经更换了其他测试的服务,Chrome 依然缓存了 301 重定向。
而由因为跳转的时间非常快,所以我无法使用以前经常使用的 Ctrl+Shift+R 来强行刷新页面清除缓存。所以只能求助 Google,幸而操作并不复杂,不过让我学到了一些 Chrome 的小 tips,因此记录下来。
之前提到的 Ctrl + Shift + R 就能够强制刷新,但其实还有一种UI上面的操作,如果打开 DevTools 的情况下,点击刷新按钮,并长按,会弹出如下的菜单,选择 Empty Cache and Hard Reload
即可。
针对我的情况,直接打开 http://localhost
然后强行刷新即可。
开启 Developer Tools,一般的快捷键是 Ctrl + Shift + I ,如果从菜单上开启是Chrome的点点点 -> 工具 -> 开发者工具;或者任意的页面点击 Inspect 审查当前页面,就能打开。
然后再打开的开发者调试工具集中,打开 Settings,快捷键 F1,在工具集的右上角,点点点-> Settings。
在 Perferences -> Network 标签下 有一个 Disable Cache(while Devtools is open)
,选中即可。
当然最暴力的就是清除数据了,不建议这么做。
UFW,全称 Uncomplicated Firewall,是通过 iptables 实现的防火墙工具。ufw 是对 iptables 的封装,iptables 的规则太过于复杂,不适合新手。这篇文章也是如何增强VPS安全性的扩展篇,在修改了SSH端口,登录用户之后,最好清楚自己开放了VPS的哪些端口访问,把他们用 ufw 管理起来,防止被滥用。
Ubuntu 默认已经安装如果没有安装,使用一行命令即可:
sudo apt update && sudo apt install ufw
默认情况下,ufw 的配置文件在 /etc/default/ufw
,然后用户定义的防火墙规则文件会存在 /etc/ufw/*.rules
和 /lib/ufw/*.rules
。
UFW 默认允许所哟出站连接,拒绝所有入站连接
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo vim /etc/defaulf/ufw
然后修改
IPV6=yes
sudo ufw allow ssh
# 等价于
sudo ufw allow 22
如果修改了SSH连接端口,记住相应的允许端口连接。
sudo ufw allow http
# 等价于
sudo ufw allow 80
sudo ufw allow https
sudo ufw allow 443
默认情况下 ufw allow 不加 in
是指允许入站连接,如果要允许出站,加上 out
sudo ufw allow in port
sudo ufw allow out port
sudo ufw allow ftp
# 等价于
sudo ufw allow 21/tcp
sudo ufw allow 6000:6005/tcp
sudo ufw allow 7000:7005/udp
默认情况下相应的端口允许所有IP连接,通过from指定允许某IP的连接
sudo ufw allow from 123.45.67.89
sudo ufw allow from 123.45.67.89 to any port 22
如果要允许子网的连接
sudo ufw allow from 15.15.15.0/24
sudo ufw allow from 15.15.15.0/24 to any port 22
和允许连接一样,只要将相应的allow换成 deny
即可
首先查看当前的规则,并且打印出规则号
sudo ufw status numbered
每条规则前都有一个序号
sudo ufw delete [number]
也可以通过协议删除
sudo ufw delete allow http
# 等价于
sudo ufw delete allow 80
sudo ufw status verbose
sudo ufw show added
sudo ufw enable
sudo ufw disable
ufw 默认会开机启动,如果没有,手动设置
sudo systemctl start ufw
sudo systemctl enable ufw
sudo ufw logging on
sudo ufw logging off
sudo ufw logging low|medium|high # 指定日志级别 日志文件在 /var/log/ufw.log
日志的格式
其中前面列出了主机防火墙日志的日期、时间、主机名,后面的内容意思是:
[UFW BLOCK]:表示事件描述的开始以及是何种事件。在此例中,它表示阻止了连接。 IN:如果它包含一个值,那么代表该事件是传入事件 OUT:如果它包含一个值,那么代表事件是传出事件 MAC:目的地和源 MAC 地址的组合 SRC:IP数据包的源IP DST:目的地的IP LEN:数据包长度 TTL:数据 TTL,或称为time to live。 PROTO:数据包的协议 SPT:数据包的源端口 DPT:目标端口 WINDOW:发送方可以接收的数据包的大小 SYN URGP:指示是否需要三次握手。 0 表示不需要。
这条命令将禁用 ufw,并删除所有定义的规则
sudo ufw reset
默认情况下, ufw 会备份规则。
这里主要是介绍威联通 NAS 上面的 Virtualization Station (虚拟机工作站),这个应用能够在 NAS 上运行虚拟机,支持 Windows, Linux,Android 等等系统。威联通的虚拟机功能可以让用户在一台机器上同时运行多个系统。
Virtualization Station 支持通过 .ova, ovf, .qvm 或者 .ios 文件来安装虚拟化系统。
使用这个虚拟机非常容易,直接在应用中安装 Virtualization Station 即可,然后在桌面上点击打开,就能够见到基本的界面,如下图
安装虚拟系统的方法也很简单,只要有系统 ova, ovf, qvm, 或者 iso 镜像就可以。
和绝大部分虚拟机的需求一样,你可以在 NAS 的虚拟机上做任何事情,包括测试,备份,恢复等等。对于一个 7*24 小时都开着的机器来说,比如可以安装一个 Windows 虚拟机,将百度网盘的文件拖下来,使用 BT 软件挂机等等功能都可以被开发出来。
下面放一张图,可以解释为什么威联通里面有三个类似功能的 APP(Virtualization Station, Container Station, Linus Station) 他们的区别
总结来说 Virtualization Station 是一个虚拟机,在 NAS 上跑虚拟化的系统,虽然利用率,不错,但是可能比不上 Linus Station。而如果更加愿意使用单独的服务,比如跑 Docker ,那么 Container Station 其实更加适合。
因为威联通现在已经不支持百度云,所以在威联通上使用百度云非常的难受,只能够通过虚拟化 Windows 在 Windows 上跑百度云再将文件拉下来存到 NAS 上。
如今各种设备各种数据日益增多,当越来越多的私人数据需要存储时,NAS 进入了我的视线。早之前我以为云端存储可以涵盖我的一切,而我多年的数据也都安稳的存在互联网的各个领域,我的文件在 Dropbox,我的照片在 Google Photos,我的音乐原来在 Google Play Music,现在转移到了网易云音乐,我的书籍大部分都在 Kindle 上,也就是亚马逊的云上,我的文章、代码大都在 GitHub,我的笔记都在 WizNote,我的书签 Chrome 保存着,我的密码 LastPass 保存着。其实说实话原本这一切都是非常完美的,直到这两年网络越来越不稳定,互联网各种环境越来越糟糕,各种数据泄露让我原本一切都在云端的幻想破灭了,于是才有了这篇私有云储存。
为什么买这个 TS-453B mini,主要是便宜,4Bay 的 NAS 中价格是最低的,如果以后因为要升级容量可能会更加麻烦,至少 4Bay 的 NAS 我觉得近 5 年或者更远来说应该能够满足我个人的需求了。并且写下这篇文章的主要原因也是在初次使用 NAS 的时候需要解决的几个重要的问题,也就是我的主要需求。
从开始硬盘系统安装,到摸清楚其中的主要功能,也花了不少时间,写这篇文章的时候对这个威联通的 QTS 系统有并没有很深入的了解,唯一曾经看测评的时候就了解的功能就是他对虚拟化技术的使用,这是群晖所不拥有的。而其他同步文件,备份系统等等功能我以为应该是必须的功能,在威联通这边竟然有一丝丝的麻烦,我以为只需要安装一个同步软件或者工具就能够实现的功能而竟然还要稍微复杂一些些。不过这都不是什么问题,充分利用起他的硬件才是这篇文章想要探讨的事情。
在写这篇文章的时候 QNAP 发生了不知名错误,导致我无法登录 admin 页面,只能 reset,以至于丢失了我所有的设置和配置。只能从头再来,很麻烦。
首先用 admin - admin 登录进去,第一步就是修改密码,添加二步验证,然后切换语言。
启用 myQNAPcloud 这样可以外网访问,不过也别抱太高期望,这个连接速度真的很慢。
然后去 App Center 中安装各种需要的应用。
然后可以去添加 QNAP Club 这个第三方应用商店,地址是这个 https://www.qnapclub.eu/en/repo.xml
更多关于 QTS 4.3.x 系统的使用可以查看官方的用户文档
4.4.1 的官方文档
NAS 中非常重要的就是数据了,威联通在存储时引入了一些新概念。QNAP 引入了弹性磁盘区架构作为基础,包括了这些功能:
威联通的弹性磁盘区架构从底层到上层,分别是磁盘管理、存储池管理、磁盘区管理及共享文件夹管理
基本存储管理架构
威联通还提供了一种 Qtier 存储池(自动分层存储解决方案),由不同类型的硬盘(机械或 SSD)所组成而形成一个多硬盘磁盘区,在低负载期间或是根据您的计划, 将常用数据搬移到高性能硬盘(即 SSD)以达成高可用性或高 I/O 高速缓存吞吐量。将不常用的数据搬移到低成本的高容量硬盘(即 SATA 硬盘)以提高成本效益。
这其实是一个非常简单的需求了,不论是现在通过网络备份到 Google Photos 和 Flickr,还是说备份到小米的路由器上,都是一个非常容易实现的需求。在威联通的 QTS 上可以通过 Qfile 和 Qphoto 来实现。设置倒也简单。
自动备份照片的目的地址,千万不要选择 Qsync 的文件夹,选择 multimedia 或者其他文件夹,这样在 Linux SMB 访问的时候才能访问到。 QSync 文件夹内的内容是不支持 SAMBA,FTP,AFP 访问的。
QNAP 自带 MySQL Server 设置中启用即可,用的是 MariaDB ,这是 MySQL 开源社区维护的一个分支。然后可以安装 phpMyAdmin 来管理 MySQL,默认的用户名和密码是 root 和 admin(如果设置过 NAS 密码,可以尝试 NAS 密码),如果要修改密码,可以再 phpMyAdmin 安装完成之后在 phpMyAdmin 后台 -> 权限中,编辑 root 在 localhost 的密码。参考官网.
在“控制台” - “网络与文件服务” 中开启 Samba,然后在局域网中就能够通过 SMB 来挂载 NAS 中的文件夹。
在 QNAP 的系统中安装应用,QNAP 会维护一个应用列表在 /etc/config/qpkg.conf
, 而实际的应用则对应的安装在 /share/CACHEDEV1_DATA/.qpkg/
目录下。
为了提高 QNAP 系统的安全性,下面记录一下对 QNAP 系统的设置。
登录界面中隐藏固件版本,以及链接。
在 System -> General Settings 中选择 Login Screen,将如下两个选项勾选去掉。
RAID 全称 Redundant Array of Independent Disks,独立冗余磁盘阵列,将多块独立物理硬盘按不同方式组合形成一个逻辑硬盘,提供比单盘更高的存储性能和数据备份。RAID 是为了减少数据丢失而发明的一种方法。
至少需要两块物理硬盘,将数据以位或者字节分割,并行地读 / 写到磁盘(英文的术语叫做 stripe),但是没有数据冗余,当其中一块硬盘故障时,所有数据无法恢复。假设有两块物理硬盘前提下,读写速度提高 2 倍,数据安全性降低 2 倍。
RAID 0 不适用于数据安全性高的场合。
RAID 1 至少需要两块物理硬盘实现,通过磁盘数据镜像冗余,在成对的独立磁盘上互为备份,用简单的话讲就是通过冗余一份或多份数据的方式提高数据安全性。原始数据繁忙时,直接从镜像拷贝数据,RAID 1 可以提高读取性能。假设两块物理硬盘前提下,存储空间只能利用 50%,单位成本最高,提供很高的数据安全性和可用性,当其中一块硬盘故障时,可以自动切换到另一块磁盘读写。可以承受单个硬盘故障而不会造成数据丢失。当容错至关重要,而空间和性能不是关键要求时,通常采用 RAID 1。
RAID 1 适用于安全性要求比较高的场合。
至少需要三块物理硬盘,数据条块化分布不同硬盘,使用冗余的单块磁盘存放奇偶校验,当物理盘故障,奇偶盘和数据盘可以重新恢复数据,而如果奇偶盘故障则不影响数据使用。
RAID 3 可对连续数据读写提供很好的性能,但对于随机数据写操作可能成为瓶颈。
至少需要三块物理硬盘,提供热盘实现故障恢复,校验位会分布存放在三块磁盘中;当其中一块故障,则可以恢复数据;如果其中两块损坏,则所有数据都会损坏。
RAID 5 通过奇偶校验位提高了数据安全性,可实现单盘故障后的数据恢复。
RAID10 又被称为 RAID 1+0 或者 RAID 0+1,至少需要四块物理磁盘。RAID 01 则是 1,2 磁盘,3,4 磁盘先组 RAID 0,然后组起的两个 RAID 0 阵列组 RAID 1。 RAID 10 则是先组 RAID 1 然后组 RAID 0。在提供性能的同时提供一定的安全性能。
假设要写入的数据是{A1,A2,A3,……,A8},那么:
+--+--+--+--+--+--+--+--+
+-->|A1|A2|A3|A4|A5|A6|A7|A8|
+--+--+--+--+--+--+--+--+ | +--+--+--+--+--+--+--+--+
|A1|A2|A3|A4|A5|A6|A7|A8|-->| Disk0
+--+--+--+--+--+--+--+--+ | +--+--+--+--+--+--+--+--+
RAID 1 +-->|A1|A2|A3|A4|A5|A6|A7|A8|
+--+--+--+--+--+--+--+--+
Disk1
+--+--+
+-->|A1|A5|
| +--+--+
| Disk0
| +--+--+
+-->|A2|A6|
+--+--+--+--+--+--+--+--+ | +--+--+
|A1|A2|A3|A4|A5|A6|A7|A8|-->| Disk1
+--+--+--+--+--+--+--+--+ | +--+--+
RAID 0 +-->|A3|A7|
| +--+--+
| Disk2
| +--+--+
+-->|A4|A8|
+--+--+
Disk3
+--+--+--+--+
+-->|A1|A3|A5|A7|
| +--+--+--+--+
| Disk0
| +--+--+--+--+
+-->|A1|A3|A5|A7|
+--+--+--+--+--+--+--+--+ | +--+--+--+--+
|A1|A2|A3|A4|A5|A6|A7|A8|-->| Disk1|
+--+--+--+--+--+--+--+--+ | +--+--+--+--+
RAID 10 +-->|A2|A4|A6|A8|
| +--+--+--+--+
| Disk2
| +--+--+--+--+
+-->|A2|A4|A6|A8|
+--+--+--+--+
Disk3
+--+--+------+
+-->|A1|A4|B7->A7|
| +--+--+------+
| Disk0
| +--+--+------+
+-->|A2|A5|Q3->P3|
+--+--+--+--+--+--+--+--+ | +--+--+------+
|A1|A2|A3|A4|A5|A6|A7|A8|-- | Disk1(P3=B7 XOR A7 XOR B8 XOR A8 XOR Q3)
+--+--+--+--+--+--+--+--+ | +--+--+------+
RAID 5 +-->|A3|P2|B8->A8|
| +--+--+------+
| Disk2(P2=A4 XOR A5 XOR A6)
| +--+--+
+-->|P1|A6|
+--+--+
Disk3(P1=A1 XOR A2 XOR A3)
这些转换、计算过程,如果由 CPU 执行硬盘控制器的驱动程序代码完成,就是软RAID;如果由RAID卡上的主控芯片完成,就是硬RAID。
RAID | 最小磁盘数量 | 磁盘利用率 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|
RAID 0 | 2 | 100% | 成本低,提高磁盘读写 | 无冗余和修复能力,任何磁盘损坏将丢失所有数据 | 对读写性能要求较高,安全性要求不高的图形工作站 |
RAID 1 | 2 | 50% 或者 min(磁盘 1,磁盘 2) | 冗余备份,数据安全性高 | 成本高,磁盘利用率低 | 数据随机写入,安全性高的数据库服务器 |
RAID 3 | 3 | 2/3 | 专用奇偶校验磁盘冗余备份,数据安全性高 | 成本略高,磁盘利用率低 | 视频编辑,数据库 |
RAID 5 | 3 | 2/3 | 分布奇偶校验信息冗余备份,数据安全性高 | 成本略高,磁盘利用率低 | 金融,数据库等 |
RAID10 | 4 | 50% | 分布奇偶校验信息冗余备份,数据安全性中 | 成本略高,磁盘利用率低 | 日常等 |
最后推荐几个小工具,往往有些时候数据安全性和成本不能同时兼顾,所以当一旦想要使用 RAID,可以先考虑一下自己的需求,然后根据自己需要的容量,以及数据安全性综合考虑。
几个 RAID 容量计算小工具:
在整理之前那篇 [Git 分支管理]1 的时候接触了 git bisect
,用了那么长时间的 git 竟然又出现了一个不曾用过的命令,于是就看了下文档学习下使用。
git bisect
使用二分查找来快速定位出错的 commit,举个例子来说,假设线上正常运行的一个版本,之后进行了大量的开发,提交了成百上千次提交,而导致了线上其中一个小功能的失效。为了定位问题,你可能需要查看过去的提交。
在使用之前你需要知道两个前提,一个是已知的正常运行的版本,一个是出问题的版本,git bisect
会在两个版本之间使用二分查找,然后根据定位的 commit id 创建新的分支,然后在此分支上可以进行检查,是否有问题。
假设这个中间版本依然可以运行,那么通过 git bisect good
命令告诉 git,然后进行剩下一半的查找,以此类推,最终会快速的定位到问题所在 commit。因为每次都把提交历史切为两半,所以非常快,时间复杂度 log(n)
运行 git bisect 的整个过程
git bisect start # 告诉 git 开始二分查找
git bisect good [good-commit-id] # 告诉 git 该版本无问题
git bisect bad [bad-commit-id] # 告诉 git 出问题版本 git bisect bad HEAD
# 此时 git 就会检出中间版本,然后就可以去测试该版本
git bisect good/bad # 此时就会遇到两种可能,有问题或者无问题,使用 good/bad 来告诉 git
# 当找到第一个问题版本后,git 会告诉你 bisect 结束
git bisect reset # 返回到 git bisect 初始的版本
git bisect log # 显示最后一次完全成功的 git bisect 日志
看完整个过程就知道了为什么在 [Git 分支管理]1 那篇文章中要提到这个 bisect 了,因为如果在 master 上的提交每次都 rebase ,而不是使用 merge ,就会让 master 分支非常干净,而 bisect 去查找的时候就不会那么的费力,而如果 master 分支非常多的分叉,查找过程就会非常费力了。
YOURLS 是 Your Own URL Shortener,是一个使用 PHP 编写的,非常强大的短链接平台。
官网地址:http://yourls.org
cp /user/config-sample.php /user/config.php
vim config.php
,根据个人情况进行数据库、管理员账户等配置;/var/www/
等等;yourls 的用户名和密码是以字符串形式存放在配置文件中的,需要在设置时指定。
推荐使用 Docker 安装
可以使用 yourls 目录下的 docker-compose 启动。
基本的配置可以分为三个部分
配置文件在目录下 /user/config.php
/** MySQL 数据库用户名 */
define( 'YOURLS_DB_USER', 'your db user name' );
/** MySQL 数据库密码 */
define( 'YOURLS_DB_PASS', 'your db password' );
/** 用来存储 Yourls 数据的数据库 */
define( 'YOURLS_DB_NAME', 'yourls' );
/** 如果你不是用的标准 hostname 端口,请用'hostname:port'这种格式配置,例如 'localhost:8888' 或者 '127.0.0.1:666' */
define( 'YOURLS_DB_HOST', 'localhost' );
/** MySQL 表前缀字符 */
define( 'YOURLS_DB_PREFIX', 'yourls_' );
/** YOURLS 安装 URL -- 字母小写,并且结尾不带斜线
** 如果你想配置到 "http://sho.rt", 就不要在浏览器中用 "http://www.sho.rt"(反之亦然) */
define( 'YOURLS_SITE', 'https://your-own-domain.com' );
/** 服务器时区 GMT 值,北京时间 +8 */
define( 'YOURLS_HOURS_OFFSET', 8 );
/** YOURLS 语言
** 更改此项设置来使用你优先的语言翻译文件,默认语言为英语
** 翻译文件 (a .mo file) 需要提前放在 /user/language 目录下
** 通过查看 http://yourls.org/translations 获取更多翻译信息 */
define( 'YOURLS_LANG', '' );
/** 允许多个短链接对应同一原链接
** 设置为 true 则表示短链接和原链接一一对应(默认 Yourls 设置)
** 设置为 false 则允许多个短链接对应同一原链接(类似 bit.ly 表现) */
define( 'YOURLS_UNIQUE_URLS', true );
/** Private 表示后台管理需要密码登陆作为默认手段来实现管理
** 设置为 false 意味着对公众开放模式(例如在内网配置或者测试安装)
** 查看 http://yourls.org/privatepublic 获取更多细节 */
define( 'YOURLS_PRIVATE', true );
/** 用来加密 cookies 的一串随机哈希值,并不需要记住这个,要让它尽量长而复杂,可以从 http://yourls.org/cookie 来获取随机哈希值 **/
define( 'YOURLS_COOKIEKEY', 'modify this text with something random' );
/** 登陆管理站点的用户和密码,密码可以是纯文本或者加密的哈希值
** YOURLS 将会自动加密本文件中的纯文本密码
** 查看 http://yourls.org/userpassword 获取更多信息 */
$yourls_user_passwords = array(
'username' => 'password',
// 'username2' => 'password2',
// 你可以利用'login'=>'password'这种格式来添加更多行
);
/** 调试模式,用来输出一些内部信息
** 对于运行中的站点默认是 false,在编码或者获取提交信息时才会启用 */
define( 'YOURLS_DEBUG', false );
/** 链接缩短方式:36 或者 62 **/
define( 'YOURLS_URL_CONVERT', 36 );
/*
* 36: 生成数字和小写字母组成的短链接关键字(例如:13jkm)
* 62: 生成数字大小写混合的短链接关键字(例如:13jKm 或者 13JKm)
* 选择一个来设置,你开始创建连接之后最好别再更改
*/
/**
* 保留关键字(这样子在创建链接时就会屏蔽这些关键字)
* 这里会填上负面、潜在误导性的词语
*/
$yourls_reserved_URL = array(
'porn', 'faggot', 'sex', 'nigger', 'fuck', 'cunt', 'dick',
);
默认情况下如果安装了 yourls,那么 https://sho.rt 根目录是空的,如果不想要展示一个空空的根,可以在根目录下新建 vim index.php
加入以下内容
<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://yourdomain.com");
?>
yourls 中的密码可以直接修改 /user/config.php
文件中
<?php
$yourls_user_passwords = array(
'name' => 'md5:71688:0ce4',
);
直接修改后面密码 hash 部分,再下一次启动时 yourls 会自动加密该密码。
如果使用之前我的 Docker 方式安装的,需要在 docker-compose.yml 中设定好密码,这样重新启用 docker-compose 即可。
官方在 GitHub 上总结了非常多的插件,可以根据自己的需求找到想使用的插件。
使用插件的基本流程如下,所有的插件都可以使用这样的方式安装启用:
/user/plugins/插件名/
目录下官方默认插件,允许在短域名中加入 -
短横线,有些时候为了易读性加上字符分割还是非常易识别的。
默认 yourls 的短链接是数字递增的,随机短链接插件将短链接变成随机字符串。
将点击缓存,减少数据库读
YAPCache 是 Ian Barber’s YOURLS APC Cache 插件的 fork 版本,增加了缓存等等功能,不要同时安装这两个版本。
可以修改短域名的模式,比如将 https://sho.rt/abc 变为 https://sho.rt/m/abc 这样的模式,那么可以在 /m/
下显示一个工具栏,不推荐使用,影响用户体验。
在短链接后面添加 .qr
显示二维码
处理 http://sho.rt/https://google.com 这样的链接不指向 admin
在 admin 中可以添加 track 变量,这个插件会添加一些 Google Analysis 的参数 GA campaign info,对于需要大量追踪信息的商家来说很好的插件。
给 stats & admin page 添加 GA 分析,只有当访问 https://gtk.pw/ins+ 这样带 +
号的短链接才会被追踪到 Google Analytics
在将 plugin.php 放到 user/plugin/ganalytics 目录下之后,需要在 config 文件中定义
define(GANALYTICS_ACCOUNT, "UA-XXXXXX-UU");
另一个 GA track
短域名服务或许是兴起于 Twitter 只能写 140 个字开始,因为有限的文字数量,所以必须要非常有效的传递每一个信息,所有不能把文字浪费在长链接上,自从 t.co 开始就源源不断的开始涌现出各种各样的短链接服务,所以应该在什么时候使用这个服务呢,我总结了一下我个人用的几个情况
默认情况下 yourls 使用的是 301 跳转,但是这两个有着一定的区别,可能对于普通用户而言都是跳转,表现出来是一样的,但是对于搜索引擎,或者浏览器等等,他们的处理方式就有区别。
所以对于搜索引擎来说需要考虑是否要保留原始地址,或者是否要用新页面来替换老页面。而浏览器对于 301 跳转会进行缓存。
http://yourls.host/yourls-api.php
前段时间关注了一下域名生意,然后自己也是因为腾讯的优惠券买了一个 club 的域名,看了这么多天的域名,而现在顶级域名又原来越多,虽然 .com 域名依然占据着互联网的绝对位置,但随着未来大家对互联网的认识加深,应该会普及开其他通用顶级域名,所以我感觉其实也没有必要屯一些特殊的域名,除非真的能够买到 a.live
, youtube.tv
这样的域名,其他的域名真的已经不重要了,前两年可能还有千万的域名价格成交,这两年都已经听不到了。如果真的有域名的需求,不妨考虑下品牌的名字,能够有 .com 域名最好,不然 youtu.be
不是也挺好。
垃圾腾讯云要不是有优惠券才不会使他。
https://buy.cloud.tencent.com/domain?price=1
这是Google域名的价格,大部分都是非常统一的,续费和转入都非常方便,提供免费的隐私包含和免费的域名邮箱转发
https://support.google.com/domains/answer/6010092?hl=en
另一个比较著名的域名贩卖商
https://www.namecheap.com/domains.aspx#domain_tab_pricing
网址
https://name.com
网址
https://www.namesilo.com/
网站地址
https://tld-list.com/
可以查看一千多个顶级域名在各个网站上的价格。
网站地址
https://www.domcomp.com/
另一个域名比价网站,不管是新购还是renew都可以先上这两个网站看一眼,然后再选择转入到哪一家。
地址
https://ntldstats.com/
该网站上能看到全世界的域名注册量信息,包括注册局信息,顶级域名注册量信息。比如这里 就能看到Google刚开放的 .app
顶级域名的单日注册量。
fm 是密克罗尼西亚国家顶级域名,当然fm也可以是调频广播,fm域名后缀非常适合拿来做广播网站,音乐广播网站。
dianying.fm
douban.fm
lizhi.fm
last.fm
yuedu.fm
987.fm
tingshuo.fm
qingting.fm
360.fm
fm 域名相对较贵,基础年费 60 刀以上
.tv为吐瓦鲁国家及地区顶级域的域名,很容易让人联想到电视,视频等等,因此经常被用来做视频相关的站点。
也是一个国家的顶级域名,不过有些废,因为 pw 啥都沾不上,所以也就便宜。