大数据引发的小悲剧(二)

和上一次的现象差不多:数据量小时一切正常,稍微大一点monitord就会没响应。

 

具体跟踪之,发现如下现象:

(1)MonitorServer给monitord发送请求,一切都正常;但是没有收到monitord返回的响应;

(2)monitord收到并解析请求,一切正常;

(3)monitord执行请求,一切正常;

(4)最后一步:monitord更新配置文件,超时。

 

崩溃。。。

写文件居然会超时?这得多大的数据量阿,俺们的数据量也没达到这么恐怖的底部呀?

废话少说,扒开代码一看,彻底拜服:

 1 static int set_threshold_cfg()
 2 {
 3     ...
 4     
 5     int i=0;
 6     for(;i<num; i++)
 7     {
 8         ConfigSetKey();
 9     }
10     ...
11 }
12 
13 int  ConfigSetKey(void *CFG_file, void *section, void *key, void *buf)
14 { 
15     FILE *fp1, *fp2; 
16     char buf1[MAX_CFG_BUF + 1]; 
17     int  line_no, line_no1, n, ret, ret2; 
18     char *tmpfname; 
19     
20     ret = ConfigGetKey(CFG_file, section, key, buf1); 
21     if(ret <= CFG_ERR && ret != CFG_ERR_OPEN_FILE) return ret; 
22     if(ret == CFG_ERR_OPEN_FILE || ret == CFG_SECTION_NOT_FOUND) 
23     { 
24         
25         if((fp1 = fopen((char *)CFG_file, "a")) == NULL) 
26             
27             return CFG_ERR_CREATE_FILE; 
28         
29         if(fprintf(fp1, "%c%s%c\n", CFG_ssl, section, CFG_ssr) == EOF) 
30         { 
31             fclose(fp1); 
32             return CFG_ERR_WRITE_FILE; 
33         } 
34         if(fprintf(fp1, "%s=%s\n", key, buf) == EOF) 
35         { 
36             fclose(fp1); 
37             return CFG_ERR_WRITE_FILE; 
38         } 
39         fclose(fp1); 
40         return CFG_OK; 
41     } 
42     if((tmpfname = tmpnam(NULL)) == NULL)
43     {
44         return CFG_ERR_CREATE_FILE; 
45     }
46     if((fp2 = fopen(tmpfname, "w")) == NULL)
47         return CFG_ERR_CREATE_FILE; 
48     ret2 = CFG_ERR_OPEN_FILE; 
49     
50     if((fp1 = fopen((char *)CFG_file, "rb")) == NULL) goto w_cfg_end; 
51     
52     if(ret == CFG_KEY_NOT_FOUND) 
53         line_no1 = CFG_section_line_no; 
54     else /* ret = CFG_OK */ 
55         line_no1 = CFG_key_line_no - 1; 
56     for(line_no = 0; line_no < line_no1; line_no++) 
57     { 
58         ret2 = CFG_ERR_READ_FILE; 
59         n = FileGetLine(fp1, buf1, MAX_CFG_BUF); 
60         if(n < 0) goto w_cfg_end; 
61         ret2 = CFG_ERR_WRITE_FILE; 
62         if(fprintf(fp2, "%s\n", buf1) == EOF) goto w_cfg_end; 
63     } 
64     if(ret != CFG_KEY_NOT_FOUND) 
65         for( ; line_no < line_no1+CFG_key_lines; line_no++) 
66         { 
67             ret2 = CFG_ERR_READ_FILE; 
68             n = FileGetLine(fp1, buf1, MAX_CFG_BUF); 
69             if(n < 0) goto w_cfg_end; 
70         } 
71         ret2 = CFG_ERR_WRITE_FILE; 
72         if(fprintf(fp2, "%s=%s\n", key, buf) == EOF) goto w_cfg_end; 
73         while(1) 
74         { 
75             ret2 = CFG_ERR_READ_FILE; 
76             n = FileGetLine(fp1, buf1, MAX_CFG_BUF); 
77             if(n < -1) goto w_cfg_end; 
78             if(n < 0) break; 
79             ret2 = CFG_ERR_WRITE_FILE; 
80             if(fprintf(fp2, "%s\n", buf1) == EOF) goto w_cfg_end; 
81         } 
82         ret2 = CFG_OK; 
83 w_cfg_end: 
84         if(fp1 != NULL) fclose(fp1); 
85         if(fp2 != NULL) fclose(fp2); 
86         if(ret2 == CFG_OK) 
87         { 
88             ret = FileCopy(tmpfname, CFG_file); 
89             if(ret != 0) return CFG_ERR_CREATE_FILE; 
90         } 
91         remove(tmpfname); 
92         return ret2; 
93 } 

每写入一项配置就执行一次“打开/关闭文件”操作,算下来每个请求大概要执行几万次打开/关闭文件操作,超时也就不奇怪了。

 

找到问题根源,就很好解决了:将写配置文件函数重写,只执行一次打开/关闭文件操作。具体过程略。

posted @ 2012-05-11 15:39    阅读(267)  评论(0编辑  收藏  举报