除去一开始对所要做的东西的理上的偏差,修改这个key在代码量上不是很巨大。cache在nginx中有proxy_cache和memcached,即文件缓存和内存缓存。文件缓存将访问过的页面拷贝到缓存文件中下一次访问根据key如果命中的话直接从缓存文件中读取而不需要再访问上流服务器。内存缓存顾名思义是将文件缓存到内存中。
因为对于memcached,一直以来都无法断到,无法调试,所以就先用proxy_cahce来修改key的生成规则,这个过程中比较有趣的一点是,将key当做字符串后,那这个操作就成了字符串操作,对字符串操作不存在难以克服的障碍。但需要引起重视的是cache_key的生成规则在nginx.conf中可以进行配置,所以灵活性很高,并且按照要求,要清除掉key中某几个字段,这几个字段也是要写入配置文件中的,所以del_args这几个参数的灵活性也是非常高的。这么分析下来,按照硬写死字符串操作将会对后续操作产生不利影响。所以这个规则继续向下分析。
将这个问题抽象下,从和nginx中紧密相关的细节中抽出要解决的模型,本质上还是个字符串处理问题。
字符串A,字符串的形式与URL的形式很相似,最完整的包括$scheme$domain$uri$is_args$args,这样的 ,按照最长的掺水列表进行 ,随后的配置表只会比最长的key减少参数。
字符窜B,要从key中删除的关键字,是URL中的参数部分的key, 类似 name,age,birth 这样的,用来清除 127.0.0.1/index.html?name=**&age=**中出现过的字符,那么就拆分这个,拆分之后再重新组合。
为什么要这么费事的把A拆来拆去再重新拼凑?因为读取的cache_key, 包括ngx_http_request_t中,无论是读取配置的cache_key,还是这个结构体本身内存在的url,args参数,是定义为ngx_string_t类型,这个类型中的data, 是u_char*类型的,里面的字符串是存储在全局常量中,只读,所以在修改的时候,要重新建立新的用来存储的字符串,并且在函数内被操作完赋值给新的Key之后,这个内容还不能消失,所以设置成static,搞成静态量,存储位置换成了全局数据区。不过这么做也会存在一个隐患,设置成static之后,这个值就只会有这么一个,本次修改之后,赋值给Key, 如果立即使用还好,否则一旦另外的进程或现成修改这个值,那里面的内容就被替换,但是如果为了防止这种情况对其加锁,那锁的开销就要被考虑进去,综合起来似乎还不如不用static的量,直接在调用上层设置一个变量,调用生成key的函数在这个作用域内,处理完之后,该变量在栈中被处理。
另外一个,就是关于效果展示的,很奇观竟然需要在前端界面上直接看出是是否命中cache,之所以要求这个,我推测一方面是因为谁都不愿意改变自己,尤其是改变自己的习惯,无论这习惯是否奇葩或者对自己是否有利或者对于自己的技术造诣是否提高,只是习惯罢了;另一方面,如果往好的方面看,应该是要建立监控系统,直接在前端监控服务器状态,如果是这个原因,那开发量就会剧增,这个,开发时间就需要继续往里加。
总的来说,Nginx设计的模块还算清晰,其中有毛病的地方,改天细说,这玩意写的时候就跟爬一座巨大的屎山似得,一座摇摇欲坠马上快要崩溃的屎山。