Linux 使用笔记(三)

1.系统迁移和备份

A:为了数据安全,我们需要对系统备份,换新电脑或者更换云服务时我们需要迁移系统。Linux 系统备份和迁移的方法很多,我这里打算使用 tar 。

系统备份

首先是根据自己的实际情况列出需要备份的目录,通常有:

  • /etc/
  • /home/
  • /var/spool/mail/
  • /var/spool/cron/
  • /root
  • /usr/local/bin

然后使用 tar 命令打包:

1
2
3
tar -jcv -f /backups/backup-system-20200902.tar.bz2 \
> --exclude=/root/*.bz2 --exclude=/root/*.gz --exclude=/home/loop* \
> /etc /home /var/spool/mail /var/spool/cron /root /usr/local/bin

系统恢复

首先可以将备份解压到 /tmp 目录,之后使用 rsync 命令复制到对应目录便可恢复。

1
2
3
4
5
6
7
tar -jxv -f /backups/backup-system-20200902.tar.bz2 -C /tmp
rsync -avuz /tmp/etc/ /etc
rsync -avuz /tmp/home/ /home
rsync -avuz /tmp/var/spool/mail/ /var/spool/mail
rsync -avuz /tmp/var/spool/cron/ /var/spool/cron
rsync -avuz /tmp/root/ /root
rsync -avuz /tmp/usr/local/bin/ /usr/local/bin
继续阅读

MySQL 使用笔记(二)

1.如何查看数据库中所有的存储过程?

A: mysql> show procedure status where db = 'db_for_mysql_crash_course'\G;;

Web API 的设计与开发--读书笔记

Web API 的设计与开发是开发者日常工作的重要内容,我们该如何来做好这项工作呢?我觉得一个务实的方法是先参考前辈们的做法,也就是站在巨人的肩上,理解消化后再尝试去突破,这样可能会事半功倍。经过一番搜索,找到了 <<Web API 的设计与开发>>, 我个人觉得这是一本对 Web API 进行全面、细致和深入剖析的书,对 Web API 的设计与开发很有帮助,值得一读。

书的内容是按照整分的逻辑组织,并依先易后难的顺序来讲解相关知识。下面我按自己的理解尝试对书中内容做个简单的总结。

Web API 是用于完成某种需求,由于需求会变化,所以一次就设计出完美 Web API 的想法是不现实的,所以一开始应该要给 Web API 的更改留有余地,这是很容易忽视的地方。推荐的做法是在 URI 中嵌入版本信息,典型的形式是 http://api.linkedin.com/v1/people

虽然一次就完美地设计 Web API 的想法不现实,但我们还是想尽量做好,减少 Web API 版本变更的次数,毕竟版本越多维护成本越高,那么我们该如何设计 Web API 呢?

Web API 通过 HTTP 协议来完成通信,在设计时我们应该最大程度地利用 HTTP 协议规范。基于标准协议设计的 API 至少要比使用私有协议设计的 API 更容易理解,还会减少使用时引入的 bug,使你的 API 得到更广泛的使用,提高利用已有的程序库或代码的可能。

有了整体设计原则后,我们来看下具体的请求和响应设计。API 的功能是为了完成项目的需求,最完备的请求会包含请求端点、请求方法、请求参数和请求数据体(Request Body),我们依次来审视请求的每个部分。

端点是指用于访问 API 的 URI,普适又重要的设计原则有:

  • 短小便于输入的 URI
  • 人可以读懂的 URI
  • 没有大小写混用的 URI
  • 不会暴露服务端架构的 URI
  • 规则统一的 URI

端点设计的注意事项:

  • 使用名词的复数形式
  • 注意所用的单词
  • 不使用空格及需要编码的字符
  • 使用连字符来连接多个单词

URI 和 HTTP 方法之间的关系可以认为是操作对象和操作方法的关系。如果把 URI 当作 API(HTTP) 的 “操作对象 = 资源”, HTTP 方法则表示 “进行怎样的操作”。通过用不同方法访问同一个 URI 端点,不但可以获取信息,还能修改信息、删除信息等,这样的思想正成为 Web API 设计的主流方式。

方法名 说明
GET 获取资源
POST 新增资源
PUT 覆盖已有资源
DELETE 删除资源
PATCH 更新部分资源
HEAD 获取资源的元信息

有时请求可能还需要传递参数,在设计 URI 时,必须决定是把特定参数放在查询参数里还是路径里,决策的依据有以下两点:

  • 是否是表示唯一资源所需的信息
  • 是否可以省略

请求数据体,个人认为可以采用面向对象编程的思想来设计,整个处理过程会轻松很多。

说完请求,让我们来看下响应。首先是正确使用状态码,国内由于历史原因遗留下来无论请求是否成功都一律返回 200 的问题,全站切换到 HTTPS 后,我们还是应该最大程度地利用 HTTP 规范,这样我们能受益于通用的 HTTP 程序库,减轻客户端的负担。

其次是数据格式,这里的数据格式是指该用怎样的形式来描述 API 返回的结构化数据,具体而言就是指 JSON、XML 等数据格式。关于这一点,事实上几乎没有可讨论的,因为我们通常就是使用 JSON 作为默认的数据格式,若有需求 API 也可以支持 XML 的格式,这是最贴近现实的做法。

再次是数据内部结构,我们重点看下数据应该以数组还是对象返回,作者更推荐使用对象来封装数据的方式,因为该方式有如下几个优点:

  • 更容易理解响应数据表示什么
  • 响应数据通过对象的封装实现了结构统一
  • 可以避免安全方面的风险

从次是各个数据的格式,各个数据项组成了最终的数据,只有掌握了如何处理单个数据项格式才能设计出合理的响应体数据格式。作者重点介绍了如何描述性别数据、日期格式和大整数,受益匪浅。

最后是出错信息的表示,同样,我们需要选择合适的状态码,出误信息建议以消息体的形式返回,出错信息应该包含详细的错误代码、人们能够读懂的相关信息,以及记载有详细说明的文档页面的 URI,如下所示:

1
2
3
4
5
6
7
{
  "error": {
      "code": 2013,
      "message": "Bad authentication token",
      "info": "http://docs.example.com/api/v1/authentication"
  }
}

如果想支持描述多个错误同时发生,可以返回出错信息数组,

1
2
3
4
5
6
7
8
9
{
  "errors": [
      {
          "code": 2013,
          "message": "Bad authentication token",
          "info": "http://docs.example.com/api/v1/authentication"
      }
  ]
}

以上是基础内容,作者最后还介绍进阶内容,开发牢固的 Web API,对我们把 Web API 设计和开发提高到新高度有非常大的帮助。