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