frederickjoe 发布的文章

有时候我们需要通过业务逻辑限制用户对某些路径的访问,这件事情通过nginx配置本身是做不了的,例如登录用户校验之类的逻辑。举个栗子:

有一个文件,这个文件位于服务器的 /home/server/private_files/ 目录。只有高等级的用户才能获取下载路径,且下载路径有时效,过期则失效。

要实现此功能,我们得把它分为两部分:一部分是下载路径的生成和有效性判断,这部分是业务逻辑代码实现的;另一部分则是对这个文件的保护,只有通过业务逻辑校验的请求才有权拿到此文件。

此时我们就需要用到Nginx的内部重定向功能了。

我们需要知道的两个知识点:

  1. Nginx在做反向代理拿到服务端生成的结果时,会检查服务端返回的响应头(Response Header),检查此字段:X-Accel-Redirect。如果此字段设置了内容,Nginx则会根据其设置的重定向地址,直接请求此地址的数据,并将数据输出。
  2. Nginx的location配置可以使用internal标记,将此路径标记为只允许内部访问。内部访问的意思并不是说localhost就可以访问,而是说「一次请求的」内部。

那么如何配置呢?

首先,nginx需要加上如下配置:

location /get_file/ {
    fastcgi_pass xxxxx # 或 proxy_pass,用于将请求转发到服务端
}

location /private_files/ {
    # 内部路径,禁止直接请求
    internal;
    alias /home/server/private_files/
}

然后,在服务端实现对 /get_file/xxx 的处理逻辑,如果允许访问,则返回的响应头中,写入如下信息:(以php为例)

// And redirect user to internal location
header("X-Accel-Redirect: /private_files/a.txt");

用图来表示一下:

在用户直接请求 /private_files/a.txt

直接访问

在用户请求 /get_files/xxxx

合法请求

写Python的时候,最讨厌做的事情就是处理时间——从时间戳转换到时间字符串,加减天数、月数,每次都是不看文档写不出来。

举个最简单的例子,获取昨天0点的时间戳

Python的变态代码需要这么写:

# 先以当前时间获取昨天的这个时间
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
# 格式化到日
yseterday_ymd = yesterday.strftime("%Y-%m-%d")
# 再转换为时间戳
ts = int(time.mktime(time.strptime(yesterday_ymd, '%Y-%m-%d')))

每次写完都感觉身体被掏空。

自从接触了世界上最好的语言——PHP,每次处理时间都信手拈来

// 没错!就这一行,就这么短!
ts = (int)strtotime('0:00 yesterday');

php的strtotime的参数可以基本接近自然语言的描述,只要稍微看看文档,了解一下规则,写起代码来简直神清气爽。

当然有些坑得注意,比如

strtotime('20190131 +1 month');

php在这里处理时,认为应该是20190231,2月31日,但是没这个日期,所以进位到3月,变成3月3日。

Mac在很多人眼里应该是散热差的典型代表。我自己有台MacBook Pro Retina 13寸,2012年末的版本。CPU i5-3210M。这台电脑的散热布局和后来的13寸MacBook Pro都不一样,是双风扇的,后来的版本都是单风扇。

最近一段时间总觉得风扇转速有点高,照理说不进行大任务,风扇应该稳定保持最低转速2000 RPM的,然而风扇老是保持在3000 RPM左右。于是把电脑拆开来清灰,并换了一下硅脂(六年没换了)。

风扇转速果然下来了。

然后就想看看散热效果,下载了Intel Power Gadget。之前从来没关心过CPU的核心温度,不看不知道,一看吓一跳,居然高达80度,以我之前组装电脑时的思路,CPU超过75度,风扇就应该满转速了,结果此时的风扇还是最低转速。于是抱着「我比厂家的工程师聪明」的态度,使用Macs Fan Control,自定义设置了风扇转速:监测CPU核心温度,70度开始加速,最高85度。

然后就出问题了。

- 阅读剩余部分 -

2008年上大学的时候买了一台台式机,戴尔inspiron 530。配置如下:

硬件part详情
CPUCore 2 Quad Q6600
主板Intel G33
显卡8600GT
内存DDR2 800MHz 4G (1Gx4)
硬盘320GB 机械硬盘
电源350W

这台电脑用了大学四年,2012年本科毕业后就放在家里吃灰。

今年(2018年)十一假期,我爹问我那台电脑要不要扔到农村老家去,我才想起来这家伙已经躺在我房间里好几年没开过机了。于是把它重新通电开了个机。由于主板电池早就没电了,因此一开始就报CMOS校验出错。然而忽略此错误后,电脑居然奇迹般的引导进入了Windows。真是个老不死的。

于是我开始计划给这台老家伙重新修整一番。

- 阅读剩余部分 -

Memcache这玩意虽然也是用于php连接memcached服务的,但是十分古老了,而且貌似也不维护了。

如果需要从Memcache迁移到Memcached,就会涉及到兼容性的问题——这里的兼容性发生在线上升级的时候,一部分机器升级了Memcached,然而旧的机器缓存还是用Memcache写入的,Memcached读出来就会产生问题,导致升级过程中服务处于几乎不可用的状态。

问题1

Memcached默认会对超过一定长度的数据进行压缩,而Memcache是没有压缩的,因此调用Memcached的写入时,需要取消压缩:

$memcached->setOption(Memcached::OPT_COMPRESSION, false);

问题2

Memcached和Memcache在有多台memcached服务时,使用的默认散列算法不同。Memcache用的是crc32。因此需要把Memcached的散列算法也设置为crc32

$memcached->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

问题3

通过Memcache写入memcached服务中的数据被Memcached读出来会被错误解读,反之亦然

这是由于Memcache写入的时候,设置在memcached服务中的flag无论如何都是0,而如果用Memcached写入(默认方式),则可能为0(string)、1(int)、3(对象)、4(数组)等等。这是因为Memcache是先做序列化再写入的,读取后也会默认做一次反序列化。因此在调用Memcached::set的时候,需要给被存入缓存的数据做一次序列化变成string,这样flag就一定是0,读写就和Memcache一致了。

// 写入
$memcached->set($key, serialize($value), $expire);
// 读取
$raw = $memcached->get($key);
$value = unserialize($raw);