0%

15年前, 我在qq空间写博客, 10年前, 我在新浪博客上写, 5年前我在WordPress上写. 今天, 我又换了一种不同的方式.

前言

距离六月份这个博客正式建立好, 又过去了两个月, 我终于记得把这篇建设之初就应该发上来的博文写好.

我特意起了这么一个有年代感的标题. 说是年代感而不是时代感是因为, 这个标题不是为了蹭上最新的热度而起的. 而是希望在多年以后重新翻捡出来时, 能看到过去岁月的痕迹. 在那些年里, 我认为有价值的东西, 我希望有些东西在过去很多年以后, 也还能保有价值.

理念

在这个博客建设之初, 我已经想好了一些原则, 这些是我从过往的经历中提炼出, 我认为重要的事情. 过去, 我没有太多选择的权利. 但如今, 作为一个互联网上的自由人, 我有充分的资源来实践这些我认为重要的理念.

  • 数据独立保存

    博文是发布在网络上的数据. 但没有一种网络是持久稳定的, 诚然时至今日, 不管是新浪微博还是qq空间都还存在. 但那也只是凑巧我在过去选了两家还算靠谱的博客站点. 不过从长远考虑, 我还是希望自己掌握内容.

    基于同样的理由, 对于数据的格式, 我也希望是开放的格式, 如纯文本、markdown或是html, 而不是word、Evernote或者某个网站数据库里的一个字段.

  • 好用的编辑器和轻量、便捷的发布流程

    各个站点稀奇古怪的富文本编辑器是很令我苦恼的东西, 每每面对都感觉是一场恶战, 更别提图文混排等要求. 我相信有朝一日web端的文本编辑工具可以做的和本地应用一样好(而且可能在数据同步等方面更有优势), 但显然还需要时间.

    而若是使用本地的文本编辑工具, 有一套便捷的发布流程是必要的. 在word中写完整篇博文, 排完版, 再复制粘贴到某个网页端的富文本编辑器中, 再处理一次格式问题, 这显然不是我希望的形式. 而且一旦存在数据两端存储的问题, 保持内容的一致就成了一件很烦人的事情.

实践

基于上述原则, 选定方案并不是很艰难的事情. 包括以下几点

  • 使用markdown格式写博文.

    纯文本太单调, 富文本又太重, 简单的markdown已经够用了. 虽说在几类简化的标记语言中, 相比md我更喜欢emacs的org mode, 但markdown已经够用, 而且更加流行, 眼下没有理由花额外的effort选择org mode, 而即使以后想换, 从简单的markdown切换到org mode, 我想一定比反过来更容易.

  • 单独建立博文仓库

    我的博文存放在blog这个仓库, 这个仓库很干净. 除了一个pipeline的配置文件以外, 其余的全部是内容产物. 而与博客站点相关的基础设施代码则放在hexo-site这个仓库. 后者相对而言不是那么重要, 假以时日如果我不用hexo了, 完全可以用另外一套基础设施来替换.

  • 使用git&原生的markdown编辑器撰写

    用git来管理内容, 完成跨平台的需求. 周末我可以在家里用windows电脑写; 工作日我可以在办公室里在MacBook上写; 出差或出游时, 我可能在平板电脑(Android或是iPad)上写; 甚至碎片时间, 我可以在手机上写. 用git做数据同步在碎片时间的利用并不如诸如Evernote等同步笔记软件方便, 但我更倾向于保留这种选择软件的自由.

    顺便一提, 在windows和mac上, 我一般用typora, 但也不排除会用vs code. 平板电脑和手机上通常用jotpad.

  • 使用pipeline发布博客

    2019年, 要说最大的不同是什么, 就是devops工具链终于可以应用到各方各面. 几年前静态博客流行的时候, 并非没有考虑过用git+jekyll的组合, 但没有devops pipeline的配合, 每次敲命令生成网站再手动发布的过程实在不像在写博客.

    好在这在现在都不是事了. 免费的Travis CI(针对开源仓库)就已经非常好用了. 我因为有私有仓库发布的需求, 所以用的是azure pipeline. 但从流程上来说是类似的. 因为有独立的两个仓库, 所以需要一个发布流水线拉去两个仓库的代码, 将博文放在合适的目录下, 并调用hexo生成站点. 最后再将站点发布到s3. (关于流水线搭建的内容比较多, 这里就不展开讲了, 后续再详细些吧.)

以后

每次尝试重新开始写博客, 感觉上都是一次新的历险, 有时可以走的很远, 有时会半途而废. 我希望这次能走的足够远, 因为这一次我规划了很长时间.

我期望在很远的未来, 还能看到过去留在这里的文字, 在整个互联网成为遗迹, 风干了以后, 这里还会留存可以凭吊当年的化石.

继上篇最后给s3增加了cdn之后, 访问性能其实还算堪堪够用, 剩下倒是些细枝末节的优化. 虽然俗话说过早的优化是万恶之源. 不过身为程序员的代码洁癖还是让我忍不住把这些问题处理掉.

发现问题

如何发现性能问题是第一步. 对于网页访问的响应速度分析, 最简单的粗暴的做法是通过浏览器控制台自带的响应时间捕捉数据. 以chrome开发工具为例

屏幕快照 2019-06-14 上午11.34.40

这里我测试的是加载部署在aws ec2上的hexo博客的情况, 并且使用的是手机4g作为热点. 可以看到加载时间长达27秒. 其中dom文档下载花费了15秒, 而所有资源(主要是图片)则是耗时长达27秒.

另外一个选项, 对于互联网网页, 可以用google的pagespeed insights对网页进行彻底的分析. 使用这个分析的另一个好处是, 在pagespeed insights上获得高评分有利于提高在搜索引擎上获得的权重.(即seo优化)

下图是本博客在优化前的评分情况.

pagespeed

除了提供评分以后, pagespeed insights还提供了很多优化建议. 比如延迟加载屏幕外图片, 在header中增加cache时间, 使用gzip做文本压缩等.

性能优化

优化图片加载

那么优化的第一步就以图片为例, 图片加载的优化路子有很多. 比如这里的图片大小高达800kb,虽然这已经是我在原始照片的基础上做了有损压缩的结果, 但是对于网页而言, 这个尺寸还是大了一点. 比较合适的做法应该是在网页上提供一个低保真的缩放(将图片分辨率降低比如800x600的尺寸, 并降低图片质量), 同时提供如点击后浏览大图的功能. 这也是我认为比较好的一个策略.

实施这一做法也有很多办法. 我搜到一个比较新奇的做法是用aws lambda做实时的图片处理. 这个做法的优势在于可以做任意尺寸的图片缩放. 但是采用实时压缩, 我个人觉得在响应速度上并不存在优势. 另一个做法是在hexo生成博客的时候, 同时生成多份图片资源, 比如生成如xx_tumb.jpg格式的缩略图供内嵌页面使用, 并在点击查看大图时, 使用xx.jpg的链接.

遗憾的是似乎没有现有的hexo插件可以提供这一功能, 暂时性的, 我使用的是hexo-lazyload-image这个插件, 间接避免了加载过多图片的问题. 当然这个插件依旧不能避免当首页有大图时的问题, 这个问题就留给以后优化了.

增加缓存时间

在header中增加CacheControl的做法有很多种. 这里我的做法是在将文件上传到s3时增加相应标签. 使用的部署插件是自己改写的s3部署插件, 然后注意在cloudfront中保留原始的header内容.

完成后通过浏览器访问, 并在控制台查看header中是否有对应内容即可.

增加gzip压缩

gzip压缩主要针对html页面或是js脚本等, 能提供比较客观的流量压缩. 如果是使用nginx或者apache等web服务器的话, 一般都有实时的gzip压缩功能. 不过遗憾的是s3并没有这个功能. 本来想着可以在部署阶段先通过gzip压缩, 然后再发布到s3上. 同时在header中增加encoding=gzip. 这当然也是一个可选的做法, 但是这么做的话, 如果客户端使用不支持gzip格式的浏览器(虽然可能性几乎为0), 那么就无法访问了.

好在s3虽然没有提供压缩功能, 但是cf提供了. 在cf中将压缩选项打开, 就会自动根据资源类型进行压缩.(只压缩html、js脚本等资源)

cf的变更需要一定时间生效. 稍后通过浏览器查看, 同样可以在response header中看到encoding相关内容. 另外, 也可以与压缩前的文件大小做对比, 文本文件通常可以降低2/3的大小.

复核pagespeed insights评分

pagespeed insights的评分有一定滞后性, 可能是google会对网页做缓存的缘故. 下图是上述优化都生效以后的评分情况.

屏幕快照 2019-06-14 上午11.15.11

这时候的评分就理想多了. 虽然还存在一个首次有效绘制时间过晚的问题. 猜测是next这个主题引起的, 要等到页面相关的资源(html、css、js等)全部就位以后才会绘制页面.

这个就暂时不管了, 等有时间研究next主题了, 再来考虑这个优化.

博客搭完之后, 博文还没写几篇, 站点托管的事情倒是折腾了很久. 在这通折腾之前 ,这个博客是架在aws ec2上, 用hexo自带的http server启动. 看起来用一个vps来部署博客看起来已经足够了, 为什么要这么折腾呢. 简单分析一下, 用静态托管的方式来做网站还是有不少好处的:

  1. 运维的时间成本, 需要管理的是纯粹的站点文件, 不需要关心服务器是什么
  2. 运维的金钱成本, s3托管按照文件大小和流量计费, 要比vps整机便宜
  3. s3结合cdn使用, 在访问速度上必然要好过固定机房的

当然一台vps除了做站点以外还可以提供其他应用, 这一点是静态托管做不到的. 这里就不详细展开了.

除了aws以外, 阿里云也提供对象存储(oos)做静态站点托管. 不过限于国内政策的原因, 需要网站备案才可以使用. 而由于我用的这个me域名在国内没有备案, 所以暂时没有选择阿里云来做站点托管, 不过从实现上来讲都是类似的.

下面是做静态站点托管的主要步骤:

注册域名

托管在s3上的文件, 默认会使用s3的域名(与区域有关), 在实际使用中, 一般会使用自己注册的域名. 原来我这个域名是托管在godaddy上, 为了配合aws的相关功能使用, 也顺势转到了aws 的router 53上, 在实际配置中还是有一定便利性. 另外如果是部署在阿里云上, 自定义域名是必须的, 阿里云oos默认的域名在访问时, 会被作为文件下载, 而不是网站.

域名注册的流程避开不谈, 不过强烈建议使用云服务商自带的域名托管.(比如aws就用router 53, 阿里云就用阿里云的域名托管). 在实际使用中肯定会方便不少.

创建s3 bucket托管站点

整体步骤都可以参考aws官方提供的指南

  1. 首先创建s3 bucket. 可以先评估一下各个机房的访问速度再做决定.(如果后续还使用cdn的就没有必要的). 注意这里有个小坑, s3 bucket的名字必须取成和站点域名一样的名字, 否则在router 53注册别名时会检索不到

  2. 创建完成之后先在bucket设置中将权限->访问控制列表Everyone组加上读取权限. 并在属性中配置静态网站托管.选择使用此存储桶托管网站, 并设置索引文档(如index.html).

  3. 由于s3上传文件在默认情况下是私有的, 因此还需要在权限->存储桶策略中配置访问权限

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "AddPerm",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::example.com/*"
    }
    ]
    }
  4. 设置完成之后就可以上传站点文件了, 直接在网页上操作就好了. 后续自动部署的事情以后再做介绍.

  5. 此时应该已经可以使用s3自带的域名进行访问了. 地址格式为:<bucket-name>.s3-website-<AWS-region>.amazonaws.com. 要注意的一点是, s3自带的域名可能会被墙, 需要科学上网来验证是地址被墙了, 还是配置没生效.

  6. 到此, 部署到s3上的步骤结束, 如果测试没有问题, 那么接下来可以配置自定义的域名解析

配置域名解析

以router 53为例, 在管理界面的托管区域中选择自己要使用的域名, 选择创建记录集,名称中设置自己想要使用的子域名(如果想直接使用顶级域名, 那么名称可以不写), 类型选择A - IPv4地址, 勾选别名, 选择刚才创建的s3bucket即可.

注意这里创建的域名名字必须和s3 bucket名字一样, 否则在别名中是无法检索到的. 如果使用的而不是router 53而是其他服务, 那么我理解这里应该选择创建的是一个CNAME, 然后配置s3的域名即可.

DNS生效可能需要一点时间, 可以通过ping 域名的方式检查dns解析是否生效. 生效以后, 就可以通过自己的站点域名访问s3的资源了.

(可选) 配置CDN加速

在配置完S3以后, 我简单测试了访问的速度, 感觉上比预想的要差. 于是想到了结合cdn做加速. 以下依旧以aws的cloud front为例, 阿里云的cdn加速也可以实现类似的功能(而且可能在国内访问会更快).

  1. 如果网站想支持https访问, 那么需要在cloud front中配置ssl证书. aws也有提供ssl证书服务. 在证书管理中申请就好. 选择dns验证, 如果使用的是router 53, 那么界面上点击即可配置验证dns的cname. 如果是其他dns服务商, 那么需要自行配置cname. 配置完成后, 同样是等待一段时间等dns生效验证即可. 此时域名对应的证书就已经生成好了.(建议申请泛域名证书, 即*.example.com这种格式的域名证书, 否则申请的单个证书只针对单域名有效, 子域名还需要重新申请.

  2. 在aws控制台登录cloud front控制页面, 在分配菜单中选择创建分配, 然后选择Web. **注意这里不要直接选列出的s3存储桶.**这里的一个小问题是, hexo生成的所有页面, 都遵从default root=index.html这一规则. 在s3的静态站点托管中, 我们已经配置了这一规则. 但是cloudfront中的default root object只适用于根目录, 而对于子目录(比如每天博文的独立页面)是不生效的. 手动输入s3的endpoint地址可以避免这个问题.(可以看到这个地址和自动列出的s3 bucket地址存在一些不同)

  3. 分配设置备用域名中, 填入自定义的域名, 并选择自定义SSL证书, 可以直接检索到创建的证书, 直接点选即可. 其他选项可以都使用默认配置, 或者自己按需修改.

  4. 配置完成后, 需要等待一段时间等cdn分发完成.

  5. 此时会获得一个cdn的地址, 如xxxxxxx.cloudfront.net这样的格式. 需要在域名解析中用这个地址, 替换原来s3的别名.

  6. 等cdn生效以后, 就可以再次访问, 可以看看速度有没有提升.

如何验证结果是从cdn发来的呢?

打开浏览器的控制台窗口, 在网络标签下, 在response headers中查看X-cache一项, 从could front发来的数据带有Hit from cloudfont的标签, 如果缓存没有命中, 数据从s3获取, 则会有类似miss from cloudfront的标记.

后续优化

上面这些都做完以后, 访问速度还是不理想怎么办呢, 其实还是有不少内容可以优化的, 最近也在逐项实践, 等有时间会再发上来.

新的博客, 第一篇正好来说说最近装机的事情好了。旧的台式机还是2011年在学校的时候装的,I5 2500的cpu虽然老迈,不过说实话实际应用中几乎是完全够用的。而其他部件,内存加到了16GB,硬盘后来换了算是SATA SSD中顶级的intel 530,显卡前几年换了GTX1060,都是当前服役都算稳妥的配置。

换机的原因也只是DNF这个奇葩游戏打团居然会卡顿,我能想到的也就是CPU主频不够可能造成的。虽然I5 2500也能上到4Ghz,按理说频率也不差。不过算了,毕竟是老电脑了,换就换了吧。能提升一点是一点,此前公司的办公电脑从3代I3升级到6代I7的时候,本来以为区别不大,实际用起来系统响应还是流畅了不少的。

因为是时隔八年的装机,想了想干脆一步到位,免得以后折腾了,于是大部分配置都直接拉满了。

部件 名称
CPU I9 9900K
主板 华硕ROG M11G
内存 影驰HOF 3600 8Gx2
硬盘 三星970pro+INTEL 530(旧)
电源 海韵 PRIME ULTRA 650W
散热 猫头鹰 D15S
显卡 技嘉1060 6G(旧)
机箱 迎广301黑色
机箱风扇 猫头鹰F12x3

301这个机箱不是什么新货,不过几年前看到的时候就比较喜欢这个外观,决定下一台电脑一定要用这个机箱,而实际选配置的时候还是纠结了好一会。因为9900K这个大火炉,不知道这个小机箱能不能压住(事后证明是多虑了)。

9900K当然是因为是顶配的关系,也顺利成章地选了华硕ROG的主板。唯一一款MATX的旗舰主板,而且有我比较需要的蓝牙和wifi。不过这款主板只有两个内存插槽的设计还是让我犹豫了很久,特别是看了下内存单条16G的价格。整机16G内存在现在也只能说是够用而已,如果这台新机也打算用上个5年8年的话,那是绝对不够的。如果有4插槽,那么以后想扩展内存配到32G就很容易。而32G在我看来是一个未来5年都比较安全的数字。但除了降规格选其他主板,似乎没什么好办法。想了想,就是充钱的事情,以后换两条16G的就完事了,就不纠结了。难得上一次顶配,不想有奇怪的缩水了。

第二个比较麻烦的是这个散热器,因为和301机箱的限高几乎一样,可能就装不进机箱了。另外也可能有挡其他配件的可能性,于是还买了一个U12S备用。其实301是一个支持水冷的机箱,上一体水冷可能是个更好的选择,在装机的时候更容易一些。不过考虑到水冷5年以后的可靠性,我还是选择装机的时候麻烦一点吧。

20190220_111353394_iOS

新硬件全家福,比预想的要少,机箱的盒子比较大,拆了就不装回去了。这里散热器是先到的U12S,但实际装机用的是D15S,后者规模更大。机箱也比预想的要大,其实就是常见的机箱大小,可能是一般DIY偏好的中塔ATX机箱都比较大的关系,显得迎广这种大小中规中矩的机箱也算比较小了,也可能是我看惯了一般品牌机ITX机箱大小的关系。迎广这个机箱一把风扇都不带,于是额外买了三把猫扇,这个开支也不小。

这个机箱常规的风道设计是下进风,前后出风。算是比较照顾显卡散热的一个风道,因为进风离显卡非常近。但在我这套配置里,主要的发热大户是CPU,所以我很自然的改成了前进风,后出风,显卡靠自带风扇排风。在实际使用中,显卡大部分时候根本不用风扇,甚至自带的风扇都是停转的。而主机内包含CPU风扇在内一共4把风扇,实际使用中基本没有风噪。只有都开起aida64单烤FPU的时候能感受到风扇噪音。作为噪音敏感用户,对这个效果我是满意的。

20190221_124810616_iOS

因为一些原因,这个装机流程横跨了整整一周,期间所有东西都堆在地板上,我不得不把扫地机器人的定时任务也停掉了。关于装机过程中的麻烦事主要来自这个机箱和散热器。对于选择风冷侧吹散热真的是比预想的要痛苦。简单描述一下装机过程中的问题就是,我把主板在机箱里固定好之后,安装过程必须严格按照先装内存,再装散热器,然后装散热器风扇,接着插显卡,最后按照电源,这个顺序来进行。装散热器前先装了电源呢,散热器的风扇就扣不进去。先装散热器再插内存呢,卡槽被挡住了。

其中有一次,装完散热器我发现显卡走线不对想拆了显卡重装。于是不得不先拆掉电源,然后拆散热器风扇,然后拆散热器,最后才能拔显卡,一个步骤都不能少。于是就这么反复折腾了好几趟。另外这个电源自带的CPU供电线只有一条8pin的,而华硕这个超规格主板给CPU提供了8pinx2的供电,于是我又上淘宝买了定制线。既然买了定制线,就顺便把显卡的8pin供电线也买了,因为自带的是双8pin的接口,空出一个看着难受。定制线确实对于狭窄空间内走线确实帮助很大,不过301这个机箱空间并不算机箱,所以最后也没有把所有的线都换成定制线。另外选择海韵这款电源也有一些帮助,因为这个电源比标准ATX电源短一些,机箱上部留的走线空间就相对多一些。

20190226_144313136_iOS

裸机测试点亮。某次拆卸机箱的时候,把机箱侧板的卡扣拆坏了,提给京东报修。然后后面我就把这堆东西裸放在桌子上用了两天。。。

20190228_163021826_iOS

全部装完的样子。走线方面我也算尽力了,正面的线材基本都绕在主板边缘布线解决。机箱预留的开口一个也没开,全部用原有的开口解决。不得不说风冷的巨大散热器对于整体布局结构真是巨大的破坏,如果换成水冷,机箱内部能清爽不少吧。

整机搭建完成,装完系统以后单烤FPU测试了一下,温度稳定在83度左右,烤了十几分钟,实际散热器也不是很热,估计稳定也差不多就这温度了。至于超频啥的,9900K也算官超比较猛了,进一步压榨意义也不大了。

最近觉得超频这事就像加班一样。招人的时候,如果对方说可以接受加班,甚至高强度加班,可能确实是个加分项。但实际工作中又不见得真的会让人去这么加班,加班多也未必就能代表高产能,超频也是这么回事吧。