1 #include <sys/types.h>
2 #include <sys/time.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <pthread.h>
10 #include "fastcommon/logger.h"
11 #include "fdfs_global.h"
12 #include "tracker_global.h"
13 #include "tracker_mem.h"
14 #include "tracker_proto.h"
15 #include "fastcommon/http_func.h"
16 #include "fastcommon/sockopt.h"
17 #include "tracker_http_check.h"
18
19 static pthread_t http_check_tid;
20 bool g_http_check_flag = false;
21
http_check_entrance(void * arg)22 static void *http_check_entrance(void *arg)
23 {
24 FDFSGroupInfo **ppGroup;
25 FDFSGroupInfo **ppGroupEnd;
26 FDFSStorageDetail **ppServer;
27 FDFSStorageDetail **ppServerEnd;
28 char url[512];
29 char error_info[512];
30 char *content;
31 int content_len;
32 int http_status;
33 int sock;
34 int server_count;
35 int result;
36
37 g_http_check_flag = true;
38 g_http_servers_dirty = false;
39 while (g_continue_flag)
40 {
41 if (g_http_servers_dirty)
42 {
43 g_http_servers_dirty = false;
44 }
45 else
46 {
47 sleep(g_http_check_interval);
48 }
49
50 ppGroupEnd = g_groups.groups + g_groups.count;
51 for (ppGroup=g_groups.groups; g_continue_flag && (!g_http_servers_dirty)\
52 && ppGroup<ppGroupEnd; ppGroup++)
53 {
54
55 if ((*ppGroup)->storage_http_port <= 0)
56 {
57 continue;
58 }
59
60 server_count = 0;
61 ppServerEnd = (*ppGroup)->active_servers + (*ppGroup)->active_count;
62 for (ppServer=(*ppGroup)->active_servers; g_continue_flag && \
63 (!g_http_servers_dirty) && ppServer<ppServerEnd; ppServer++)
64 {
65 if (g_http_check_type == FDFS_HTTP_CHECK_ALIVE_TYPE_TCP)
66 {
67 sock = socketClientAuto((*ppServer)->ip_addr,
68 (*ppGroup)->storage_http_port,
69 g_fdfs_connect_timeout, O_NONBLOCK, &result);
70 if (sock >= 0)
71 {
72 close(sock);
73 }
74
75 if (g_http_servers_dirty)
76 {
77 break;
78 }
79
80 if (result == 0)
81 {
82 *((*ppGroup)->http_servers+server_count)=*ppServer;
83 server_count++;
84 if ((*ppServer)->http_check_fail_count > 0)
85 {
86 logInfo("file: "__FILE__", line: %d, " \
87 "http check alive success " \
88 "after %d times, server: %s:%d",
89 __LINE__, \
90 (*ppServer)->http_check_fail_count,
91 (*ppServer)->ip_addr, \
92 (*ppGroup)->storage_http_port);
93 (*ppServer)->http_check_fail_count = 0;
94 }
95 }
96 else
97 {
98 if (result != (*ppServer)->http_check_last_errno)
99 {
100 if ((*ppServer)->http_check_fail_count > 1)
101 {
102 logError("file: "__FILE__", line: %d, "\
103 "http check alive fail after " \
104 "%d times, storage server: " \
105 "%s:%d, error info: %s", \
106 __LINE__, \
107 (*ppServer)->http_check_fail_count, \
108 (*ppServer)->ip_addr, \
109 (*ppGroup)->storage_http_port, \
110 (*ppServer)->http_check_error_info);
111 }
112
113 sprintf((*ppServer)->http_check_error_info,
114 "http check alive, connect to http " \
115 "server %s:%d fail, " \
116 "errno: %d, error info: %s", \
117 (*ppServer)->ip_addr, \
118 (*ppGroup)->storage_http_port, result, \
119 STRERROR(result));
120
121 logError("file: "__FILE__", line: %d, %s", \
122 __LINE__, \
123 (*ppServer)->http_check_error_info);
124 (*ppServer)->http_check_last_errno = result;
125 (*ppServer)->http_check_fail_count = 1;
126 }
127 else
128 {
129 (*ppServer)->http_check_fail_count++;
130 }
131 }
132 }
133 else //http
134 {
135 sprintf(url, "http://%s:%d%s", (*ppServer)->ip_addr, \
136 (*ppGroup)->storage_http_port, g_http_check_uri);
137
138 result = get_url_content(url, g_fdfs_connect_timeout, \
139 g_fdfs_network_timeout, &http_status, \
140 &content, &content_len, error_info);
141
142 if (g_http_servers_dirty)
143 {
144 if (result == 0)
145 {
146 free(content);
147 }
148
149 break;
150 }
151
152 if (result == 0)
153 {
154 if (http_status == 200)
155 {
156 *((*ppGroup)->http_servers+server_count)=*ppServer;
157 server_count++;
158
159 if ((*ppServer)->http_check_fail_count > 0)
160 {
161 logInfo("file: "__FILE__", line: %d, " \
162 "http check alive success " \
163 "after %d times, url: %s",\
164 __LINE__, \
165 (*ppServer)->http_check_fail_count,
166 url);
167 (*ppServer)->http_check_fail_count = 0;
168 }
169 }
170 else
171 {
172 if (http_status != (*ppServer)->http_check_last_status)
173 {
174 if ((*ppServer)->http_check_fail_count > 1)
175 {
176 logError("file: "__FILE__", line: %d, "\
177 "http check alive fail after " \
178 "%d times, storage server: " \
179 "%s:%d, error info: %s", \
180 __LINE__, \
181 (*ppServer)->http_check_fail_count, \
182 (*ppServer)->ip_addr, \
183 (*ppGroup)->storage_http_port, \
184 (*ppServer)->http_check_error_info);
185 }
186
187 sprintf((*ppServer)->http_check_error_info, \
188 "http check alive fail, url: %s, " \
189 "http_status=%d", url, http_status);
190
191 logError("file: "__FILE__", line: %d, %s", \
192 __LINE__, \
193 (*ppServer)->http_check_error_info);
194 (*ppServer)->http_check_last_status = http_status;
195 (*ppServer)->http_check_fail_count = 1;
196 }
197 else
198 {
199 (*ppServer)->http_check_fail_count++;
200 }
201 }
202
203 free(content);
204 }
205 else
206 {
207 if (result != (*ppServer)->http_check_last_errno)
208 {
209 if ((*ppServer)->http_check_fail_count > 1)
210 {
211 logError("file: "__FILE__", line: %d, "\
212 "http check alive fail after " \
213 "%d times, storage server: " \
214 "%s:%d, error info: %s", \
215 __LINE__, \
216 (*ppServer)->http_check_fail_count, \
217 (*ppServer)->ip_addr, \
218 (*ppGroup)->storage_http_port, \
219 (*ppServer)->http_check_error_info);
220 }
221
222 sprintf((*ppServer)->http_check_error_info, \
223 "http check alive fail, " \
224 "error info: %s", error_info);
225
226 logError("file: "__FILE__", line: %d, %s", \
227 __LINE__, \
228 (*ppServer)->http_check_error_info);
229 (*ppServer)->http_check_last_errno = result;
230 (*ppServer)->http_check_fail_count = 1;
231 }
232 else
233 {
234 (*ppServer)->http_check_fail_count++;
235 }
236 }
237 }
238 }
239
240 if (g_http_servers_dirty)
241 {
242 break;
243 }
244
245 if ((*ppGroup)->http_server_count != server_count)
246 {
247 logDebug("file: "__FILE__", line: %d, " \
248 "group: %s, HTTP server count change from %d to %d", \
249 __LINE__, (*ppGroup)->group_name, \
250 (*ppGroup)->http_server_count, server_count);
251
252 (*ppGroup)->http_server_count = server_count;
253 }
254 }
255 }
256
257 ppGroupEnd = g_groups.groups + g_groups.count;
258 for (ppGroup=g_groups.groups; ppGroup<ppGroupEnd; ppGroup++)
259 {
260 ppServerEnd = (*ppGroup)->all_servers + (*ppGroup)->count;
261 for (ppServer=(*ppGroup)->all_servers; ppServer<ppServerEnd; ppServer++)
262 {
263 if ((*ppServer)->http_check_fail_count > 1)
264 {
265 logError("file: "__FILE__", line: %d, " \
266 "http check alive fail " \
267 "after %d times, storage server: %s:%d, " \
268 "error info: %s", \
269 __LINE__, (*ppServer)->http_check_fail_count, \
270 (*ppServer)->ip_addr, \
271 (*ppGroup)->storage_http_port,\
272 (*ppServer)->http_check_error_info);
273 }
274 }
275 }
276
277 g_http_check_flag = false;
278 return NULL;
279 }
280
tracker_http_check_start()281 int tracker_http_check_start()
282 {
283 int result;
284
285 if (g_http_check_interval <= 0)
286 {
287 return 0;
288 }
289
290 if ((result=pthread_create(&http_check_tid, NULL, \
291 http_check_entrance, NULL)) != 0)
292 {
293 logCrit("file: "__FILE__", line: %d, " \
294 "create thread failed, errno: %d, error info: %s", \
295 __LINE__, result, STRERROR(result));
296 return result;
297 }
298
299 return 0;
300 }
301
tracker_http_check_stop()302 int tracker_http_check_stop()
303 {
304 if (g_http_check_interval <= 0)
305 {
306 return 0;
307 }
308
309 return pthread_kill(http_check_tid, SIGINT);
310 }
311
312