一、 说明
正常流程:第一个请求miss ,在第一个请求store_ok以后,以后的请求再访问相同url则是hit。
折叠流程: 第一个请求处理miss回源过程中,还没有store_ok之前,第二个请求进来了。squid对该时期有两种做法,如下:
collapsed_forwarding on 第一个请求进入miss后,即创建storeentry,以后的请求来了,就会hit。
collapsed_forwarding off 第一个请求进入miss后, 在还没有处理源站响应包头之前。第二个请求也会miss。
二、详解
正常流程没什么可说的,来说说折叠流程。
在说之前先唠叨下squid中storeSetPrivateKey和storeSetPublicKey 。
storeSetPrivateKey: 将entry设置PRIVATE标志,通过storeKeyPrivate(url,method,id)hash 获得一个key,并且storeHashInsert(e,key)。 一般私有只能当前request用,其他request不可见。
storeSetPublicKey:将entry的PRIVATE标志清楚、通过storeKeyPublic(url,method)hash获得一个key,并且storeHashInsert(e,key)。这个可共用,在后来的请求判断是否命中时,都用publichash。
1、collapsed_forwarding on 折叠回源开启
第一个请求
a、进入miss,clientprocessmiss,http->entrty为null,clientCreateStoreEntry->storeCreateEntry->storeSetPrivateKey. 将新建entry打上私有标签
b、clientprocessmiss,进入Config.onoff.collapsed_forwarding条件分支,进入storeSetPublicKey。
c、storeSetPublicKey是将将之前的entry(当然此处没有,因为第一个嘛)变成private
,将当前的entry变成public。
第二个请求
a、进入clientProcessRequest, 进入clientProcessRequest2,e = http->entry = storeGetPublicByRequest(r),判断是否需缓存,如可缓存且entry不为null(当然不为null,第一个请求创建的),则hit。
b、当然如果源站有no_cache字段,第一个请求会给entry设置release标志且不会swapout,第二个请求会进入到内存命中,然后判断是否有release标志,如有则miss。
2、collapsed_forwarding off 折叠回源关闭
第一个请求
a、进入miss,clientprocessmiss,http->entrty为null,clientCreateStoreEntry->storeCreateEntry->storeSetPrivateKey. 将新建entry打上私有标签
b、读事件,httpReadReply->httpProcessReplyHeader -->switch (httpCachableReply(httpState, &ncr)(是否缓存)) { case 1(可缓存):httpMakePublic(entry);)--> storeSetPublicKey(同上)
c、在第一个请求的回源读事件前,可能有其他请求过来。
第二个请求
a、在第一个请求没有读到源站数据前进入clientProcessRequest,进入clientProcessRequest2,e = http->entry = storeGetPublicByRequest(r), 因第一个请求时用private key 插入道storehash,所以第二个请求用public key找不到entry,然后走miss流程。
b、这样第一个和第二个请求都miss回源,都会有自己的storeentry。第二个请求产生的storeentry也通过第一个请求处理的方式a 将storeentry打上私有标志并插入到storetable中。
c、参考第一个请求处理方式b,storeSetPublicKey将之前的entry变成storeSetPrivateKey,将当前的entry变成storeSetPublicKey。
3、源站no_cache
a、假如request2就是一个这样的请求,它发生在在request1拿到原站的数据之前,并找到了request1创建的StoreEntry,而且“以为”自己hit了。而回源的reply中有Cache-Control:no-cache,那么当request2在进入clientCacheHit时,它找到的StoreEntry中一定会有RELEASE_REQUEST这个标识。这个标识是httpCachableReply函数发现no-cache之后设置的。当发现这个标识的时候,就会从clientCacheHit转入clientProcessMiss,重新回源,不会跟request1取到相同的数据
b、进入miss,clientProcessMiss,http->entrty不为null但lock-- > 0,clientCreateStoreEntry->storeCreateEntry->storeSetPrivateKey.
c、接步骤b。此时可分折叠开或不开,但都会进入到storeSetPublicKey-->通过public key找到storetable中已存在的entry(第一个请求的),并将其设置成私有,然后将当前私有entry变成public,并插入到storetable
d、接步骤c。这样新的先hit后miss的请求所产生的entry永远是最新的与public key绑定。之前请求的entry都变成private,直到requestfree释放。