29 Jul 2013
Squid定制开发(一)之怎样在不影响业务的情况下重新加载hosts文件
Squid定制开发(一)之怎样在不影响业务的情况下重新加载hosts文件
NOTE: 原创文章,转载请注明:转载自 blog.miaohong.org 本文链接地址: http://blog.miaohong.org/2013/07/29/squid_reconfig.html
最近我做的项目遇到一个需求,就是squid要经常重新读取hosts文件,之前的方案一直是 squid -k reconfigure 去重加载。但是这样做有很大的问题。
看了一下代码, 发现squid这块做的很糟糕(不如nginx),如下
void
clientHttpConnectionsClose(void)
{
int i = 0;
if (opt_stdin_overrides_http_port && reconfiguring)
i++; /* skip closing & reopening first port because it is overridden */
for (; i < NHttpSockets; i++) {
if (HttpSockets[i] >= 0) {
debug(1, 1) ("FD %d Closing HTTP connection\n", HttpSockets[i]);
comm_close(HttpSockets[i]);
HttpSockets[i] = -1;
}
}
NHttpSockets = 0;
}
发现squid会把所有客户端连接都干掉的。如果加载频繁,感觉明显会影响业务的。
解决思路:
借鉴squidclient给squid发送一个命令,squid接收到该命令后,就去读取hosts文件,再去刷新内存变量。
如 squidclient -t 1 -h 127.0.0.1 -p 18000 mgr:reconfig 其中reconfig就是自己定义的命令。
上面的方案可以在不断开客户端连接的情况下,起到重新加载配置的作用。
代码改动如下:
在src/stat.c中
//add by mh
static OBJH doReconfig;
//add by mh end
//add by mh
static void releaseSource()
{
ipcacheFreeMemory();
fqdncacheFreeMemory();
}
static void
doReconfig(StoreEntry * s)
{
//prevent memory leaks
releaseSource();
ipcache_init();
fqdncache_init();
parseEtcHosts();
debug_walkIptables();
}
//add by mh end
void
statInit(void)
{
int i;
debug(18, 5) ("statInit: Initializing...\n");
CBDATA_INIT_TYPE(StatObjectsState);
for (i = 0; i < N_COUNT_HIST; i++)
statCountersInit(&CountHist[i]);
for (i = 0; i < N_COUNT_HOUR_HIST; i++)
statCountersInit(&CountHourHist[i]);
statCountersInit(&statCounter);
eventAdd("statAvgTick", statAvgTick, NULL, (double) COUNT_INTERVAL, 1);
cachemgrRegister("info",
"General Runtime Information",
info_get, 0, 1);
cachemgrRegister("filedescriptors",
"Process Filedescriptor Allocation",
statFiledescriptors, 0, 1);
cachemgrRegister("objects",
"All Cache Objects",
stat_objects_get, 0, 0);
cachemgrRegister("vm_objects",
"In-Memory and In-Transit Objects",
stat_vmobjects_get, 0, 0);
cachemgrRegister("openfd_objects",
"Objects with Swapout files open",
statOpenfdObj, 0, 0);
cachemgrRegister("pending_objects",
"Objects being retreived from the network",
statPendingObj, 0, 0);
cachemgrRegister("client_objects",
"Objects being sent to clients",
statClientsObj, 0, 0);
cachemgrRegister("io",
"Server-side network read() size histograms",
stat_io_get, 0, 1);
cachemgrRegister("counters",
"Traffic and Resource Counters",
statCountersDump, 0, 1);
cachemgrRegister("peer_select",
"Peer Selection Algorithms",
statPeerSelect, 0, 1);
cachemgrRegister("digest_stats",
"Cache Digest and ICP blob",
statDigestBlob, 0, 1);
cachemgrRegister("5min",
"5 Minute Average of Counters",
statAvg5min, 0, 1);
cachemgrRegister("60min",
"60 Minute Average of Counters",
statAvg60min, 0, 1);
cachemgrRegister("utilization",
"Cache Utilization",
statUtilization, 0, 1);
#if STAT_GRAPHS
cachemgrRegister("graph_variables",
"Display cache metrics graphically",
statGraphDump, 0, 1);
#endif
cachemgrRegister("histograms",
"Full Histogram Counts",
statCountersHistograms, 0, 1);
ClientActiveRequests.head = NULL;
ClientActiveRequests.tail = NULL;
cachemgrRegister("active_requests",
"Client-side Active Requests",
statClientRequests, 0, 1);
//add by mh for reconfig
cachemgrRegister("reconfig",
"reconfig config file",
doReconfig, 0, 1);
//add by mh for reconfig end
}
其中debug_walkIptables是调试打印现在的hosts内容
void
debug_walkIptables()
{
int i;
hash_table *hid = ip_table;
hash_link *walker = NULL;
printf("-----ip_table->count = %d ------- \n", hid->count);
printf("---------hashkey_count = %d------\n", hashkey_count);
printf("walking hash table...\n");
for (i = 0; i < hashkey_count; i++) {
walker = hid->buckets[hashkey[i]];
printf("item %5d: key: '%s' \n", i, walker->key);
}
printf("done walking hash table...\n");
}