2018-11-18
这周刚巧基友在爬国学网站,爬出来的都是json,于是他想到了存在mongodb中,然后再导出为PDF。因为他跟我提了这件事情,联想到腾讯的招聘要求中有一条加分项就是了解过mongodb,心想自己也得去研究一下(于是???最后也没看mongo是怎么玩的是么?【逃】)。于是准备安装。在mac下直接使用brew install mongodb
结果炸了:
1 | php@7.0 |
1 | sudo apt install apt-transport-https ca-certificates curl software-properties-common |
但是当这些操作完了之后还是没能安装上docker,软件源中压根没有这个。查了下,发现因为ubuntu cosmic用的是debian 10的内核,换言之,lsb_release -cs 这个命令取到的是buster,这个版本太新了docker还没有适配。然后在这边找到了答案,其实很简单,把系统版本直接写死,也就是想这样: sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
即可开心地食用,起码我还没遇到啥不能用的bug。另外值得一提的是,parallels使用默认的shared network模式即可实现宿机主机之间通讯,其实通过ifconfig查看也能发现端倪:
1 | en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 |
vnic0就是parallels虚拟出来的网卡了,类似的宿机上也有这么一块虚拟网卡。不过一开始调试的时候并不痛,捣鼓了半天才发现是我之前偷懒在linux的.profile文件(用户登录时自动加载一次,但是alias命令貌似无效)中export了http_proxy和https_proxy,所以所有的流量都走代理了,当访问10.xxx的时候走了代理所以就不通了。
既然踩完了这几个坑,自然就想这样要总结一下,所以想要写个博客记录一下。突然想到一直以来欠着的就是一个静态资源服务器。先不说现在的各种OSS有多坑,对象存储机制下的key-value管理非常地不方便,当想要迁移的时候也总是因为各种适配性问题,各种组织不同导致以前写博客时的图片全都很难维护或者失去维护,除了这一点我自己的服务器已经是CN2 GIA线路了,速度应该还是可以的很快的,所以完全可以用静态文件托管的方式来维护博客相关的图片和附件。
能想到的方案有golang写一个文件服务器,然后自动去掉前缀进行访问,例如https://blog.d0zingcat.xyz/fileserver/aaa/xxx.png 就访问对应的静态目录下的aaa文件夹下的xxx.png文件(自动移除fileserver前缀)。这么做的好处是通过访问网址来判断是否访问静态资源服务器(而对应的文件直接食用rsync命令同步到服务器上即可),而且因为走的还是blog.d0zingcat.xyz这个域名,所以可以沿用这个域名的https证书。但是坏处是静态资源依赖于这个域名,存在误导性。而且还有个问题是这个需要写nginx的location规则,然额我nginx玩的少不会写。所以只能放弃。那么文件就很简单了,只有新搞一个域名,申请上https证书(因为我的博客开了全站https且是强制开启的,如果引入http的静态资源的话会没法加载)。
但是主要矛盾是穷(就跟上面想到用docker来玩mongodb一个意思),我觉得再为单独一个域名来申请证书代价有点昂贵,而这个域名还是我心血来潮搞的。所以就想到免费的https证书签发组织letsencrypt。但是之前用这个都是用的官方的工具certbot,非常地庞大和臃肿,不够清真。所以就想到了以前在一个博主(现在记不得网址了)那边看到dehydrated这个工具,可以很轻便地签发ACME证书。食用方法差不多如下:
- 克隆dehydrated项目
- 在dehydrated目录下创建config(文本文件,示例如下)、challenge(文件夹)、domains.txt(文本文件,示例如下)
- 需要配置对应的nginx。如果没有,可能需要装一个。配置nginx跳转访问well-known目录下的对应文件。示例如下。但是值得注意的是配置了^~这条规则就不要配置普通的 location/ {} 这个块,否则会冲突导致无法正常访问到well-known目录下的文件。当然,也可以在这个目录下新建一个test.txt,随便写点什么,方便测试看是否配置正确。至于是什么机理导致的,我也不清楚。
- 需要映射对应的路径到容器中,命令为
docker run --rm -d -v /home/d0zingcat/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/d0zingcat/dehydrated/challenge:/var/www/dehydrated -p 80:80 -p 443:443 nginx
,通过这个来启动对应的容器。/home/d0zingcat是我的$BASEDIR,另外包括dehydrated也在这个目录下。 - 使用命令
./dehydrated --register --accept-terms
来完成注册 - 使用命令
./dehydrated -c
来完成签约
我的config
值得注意的是CA字段在自己尝试的时候最好改成带“-staging-”的这个,不然可能会因为测试次数频繁而被封(我是没达到过,以前可能有);
另外就是如果使用了staging的这个CA且测试成功签发了对应的证书,那也没啥用的,不能拿来部署的,只是测试用。但是如果就简单改一下CA再重新签发还是会续签这个测试证书,比较好的解决方法就是直接把dehydrated目录下的accounts、chains、certs目录全部都移除。
我也试过使用自签的csr和private key,但是签约POST的时候失败了(400,不是合理的JSON),没有深究,也懒得管了。如果你有兴趣那么尽可以复现这个问题,然后去项目下面提一个issue好了。
1 | ######################################################## |
我的domains
我只签单域名的,且不涉及别名和通配,所以这边看起来会比较简单一些。你可以看项目的docs下的domains_txt.md这个文档,有很详尽的介绍。
1 | files.d0zingcat.xyz |
我的nginx.conf
1 | server { |
签约s协议完成之后会在dehydrated目录下看到多了account、chains、certs三个文件夹,但是我们只用的到certs文件夹。里面会有注册的域名,比如我的files.d0zingcat.xyz。进去找到privkey.pem(私钥)和fullchain.pem(注册密钥),复制出去到对应的nginx目录下(为了方便区分特地修改了名字)。然后修改docker的启动脚本为docker run --add-host="localhost:172.17.0.1" --rm -d -v /home/d0zingcat/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/d0zingcat/nginx/data/files.d0zingcat.xyz.key:/var/www/https/files.d0zingcat.xyz.key -v /home/d0zingcat/nginx/data/files.d0zingcat.xyz.crt:/var/www/https/files.d0zingcat.xyz.crt -v /home/d0zingcat/dehydrated/challenge:/var/www/dehydrated -p 80:80 -p 443:443 nginx
,nginx对应的配置为:
1 | user nginx; |
这个尽可照着改就是,不会有太大的问题,然后至此重启服务器就完成了服务器端的https的访问。就是90分钟要激活一次,那也挺累的。虽然隐隐约约还记得有hook机制,但是没精力去搞了,顶多就是到时候90天续期一次嘛。可以看道nginx的配置文件有反代了localhost:9000这个地址,这个就是我拿go写的很简单的静态资源服务器啦,源代码如下:
1 | package main |
编译了拿到服务器上使用命令nohup ./directory-browser "static" "/home/d0zingcat/blog/data/blog.d0zingcat.xyz.crt" "/home/d0zingcat/blog/data/blog.d0zingcat.xyz.key" &
来运行静态资源(需要提前建好static文件夹)。然后本以为这个起好或者nginx也启动好,那么久万事大吉了。但是一次又一次的失败(502 bad gateway),让我焦头烂额不知道怎么处理。突然就有了一个要检查的项,不知道咋回事。但是
把GCTT的golang系列教程全部看完了,因为直接看GOPL实在是太慢了,一方面全英文理解起来没有中文快,另外就是大师就是大师,书籍中的知识深度、广度都非常深远、辽阔,涉及了太多的点就算泛读要一个个弄清楚(比如我就没有做书后的exercise)实在太废劲,就先拿一个浅显易懂的教程整体撸一遍。当然,如果英语好的话可以看原文。
因为总算看到了golang的信号量和协程,就写了个爬图的脚本看看多线程的威力。记得以前写的爬图脚本是用的python+bs4,单线程爬了要有好几个小时(当然,也跟电脑配置,网络环境有关系)。但是这次写的是直接解析html正则匹配出来之后直接多线程下载,1600张图片一共耗时2分半,非常的快,而且失败率也很低。关键代码可以见这个:
1 | package spider |
在看GOPL的过程中呢,看到了struct中匿名嵌入其他结构的用法,方法自推导的机制,方法也可以作为一个变量实现了类似于托管的机制。不过在往下推进的时候看到了Bit Vector,书中源码如下:
1 | // An IntSet is a set of small non-negative integers. |
有点没看明白这个intset的机制,于是开始查资料。
Hashmap
- hashmap不线程安全、效率高、key,value可以为null
- hashset线程安全、效率低、key,value不能为空
Hashmap是一个数组链表,容量始终都是2的N次方(大于当前实际负载),阀值=负载因子*容量,当实际容量大于阀值时,就会进行扩容。
put时如果key为null,则取第一个bucket的entry,并根据链表一直往下找到key为null的,将value设为对应的值,否则新建一个entry。
如果key不为null,首先根据hashCode()方法获取key的哈希值,然后使用indexFor(hash,table.length)获取table中要存放的位置并存储。当两个元素的key的hashcode相同时,则在该位置上存放新的entry,并且指向原有的entry。所以对于一个table的某个位置而言,可能会存放多个键值对,但是最新的在最前面。
get时如果key为null则调用getForNullKey()方法,否则根据hash函数取到hash值,并根据indexFor()得到i的值,之后便利链表。如果有则返回对应的value。
Author: d0zingcat
Link: https://infloop.life/2018/11/18/2018-11-18/
License: 知识共享署名-非商业性使用 4.0 国际许可协议