Skip to content

Commit aaa8c73

Browse files
authored
Merge pull request #283 from Tencent/release-1.2.3
Release 1.2.3
2 parents 66a5f0d + 615b7e5 commit aaa8c73

27 files changed

+773
-482
lines changed

bin/proxy/admin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ this.start = function () {
3131

3232
logger.info('start admin...');
3333

34-
server.listen(config.httpAdminPort, '127.0.0.1', function (err) {
34+
server.listen(config.httpAdminPort, config.httpAdminAddress, function (err) {
3535
if (err) {
3636
logger.info('admin listen error ${address}:${port}', {
3737
address: '127.0.0.1',

bin/proxy/config.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,25 @@ if (global[__filename]) {
2727
}
2828

2929
if (typeof processArgs.config === 'string') {
30-
cache.config = require(path.resolve(cwd, processArgs.config));
30+
cache.config = loadConfig(path.resolve(cwd, processArgs.config));
31+
} else if (typeof process.env.TSW_CONFIG_PATH === 'string') {
32+
cache.config = loadConfig(process.env.TSW_CONFIG_PATH);
3133
} else if (fs.existsSync(currConfig)) {
32-
cache.config = require(currConfig);
34+
cache.config = loadConfig(currConfig);
3335
} else if (fs.existsSync('/etc/tsw.config.js')) {
34-
cache.config = require('/etc/tsw.config.js');
36+
cache.config = loadConfig('/etc/tsw.config.js');
3537
} else if (fs.existsSync('/usr/local/node_modules/config.js')) {
36-
cache.config = require('/usr/local/node_modules/config.js');
38+
cache.config = loadConfig('/usr/local/node_modules/config.js');
3739
} else if (fs.existsSync('/data/release/node_modules/config.js')) {
38-
cache.config = require('/data/release/node_modules/config.js');
40+
cache.config = loadConfig('/data/release/node_modules/config.js');
3941
} else if (fs.existsSync(__dirname + '/../../conf/config.js')) {
40-
cache.config = require('../../conf/config.js');
42+
cache.config = loadConfig(__dirname + '/../../conf/config.js');
43+
}
44+
45+
function loadConfig(configFrom) {
46+
const config = require(configFrom);
47+
config.configFrom = configFrom;
48+
return config;
4149
}
4250

4351

bin/proxy/http.origin.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
module.exports = function(req, res) {
2+
3+
const url = require('url');
4+
const config = require('./config');
5+
6+
const origin = req.headers['origin'];
7+
const allowOriginHost = config.allowOriginHost;
8+
9+
let obj,
10+
i,
11+
originDomain,
12+
allowOrigin;
13+
if (origin && allowOriginHost) {
14+
allowOrigin = false;
15+
try {
16+
obj = {};
17+
obj = url.parse(origin, true);
18+
} catch (e) {}
19+
20+
if (obj.hostname) {
21+
originDomain = obj.hostname;
22+
23+
for (i = 0; i < allowOriginHost.length; i++) {
24+
if (allowOriginHost[i].host === undefined || allowOriginHost[i].host && hostMatch(req.headers.host, allowOriginHost[i].host)) {
25+
if (allowOriginHost[i].origin === undefined || hostMatch(originDomain, allowOriginHost[i].origin)) {
26+
// 允许跨域
27+
allowOrigin = true;
28+
break;
29+
}
30+
}
31+
}
32+
}
33+
34+
if (!res) {
35+
return allowOrigin;
36+
}
37+
38+
if (allowOrigin) {
39+
res.setHeader('Access-Control-Allow-Origin', origin);
40+
res.setHeader('Access-Control-Allow-Credentials', true);
41+
42+
if (req.method === 'OPTIONS') {
43+
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
44+
if (req.headers['access-control-request-headers']) {
45+
res.setHeader('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
46+
}
47+
res.writeHead(200, { 'Content-Type': 'text/html; charset=UTF-8' });
48+
res.end();
49+
50+
}
51+
} else {
52+
res.writeHead(403, { 'Content-Type': 'text/html; charset=UTF-8' });
53+
res.end();
54+
}
55+
56+
}
57+
58+
return allowOrigin;
59+
};
60+
61+
62+
function hostMatch(source, expList) {
63+
if (!source || !expList) {
64+
return false;
65+
}
66+
67+
if (typeof expList === 'string') {
68+
expList = [expList];
69+
}
70+
71+
for (let i = 0; i < expList.length; i++) {
72+
if (shExpMatch(source, expList[i])) {
73+
return true;
74+
}
75+
}
76+
77+
return false;
78+
}
79+
80+
function shExpMatch(source, exp) {
81+
if (!source || !exp) {
82+
return false;
83+
}
84+
85+
if (typeof exp === 'string') {
86+
if (exp.startsWith('*.')) {
87+
// *.xxxx 开头的
88+
return '*.' + source.split('.').slice(1).join('.') === exp;
89+
} else if (exp.startsWith('.')) {
90+
// .xxx开头的,右对齐匹配就ok
91+
return source.endsWith(exp);
92+
} else if (exp === '*') {
93+
return true;
94+
} else {
95+
// 字符串全等
96+
return source === exp;
97+
}
98+
} else if (typeof exp === 'object' && exp.test) {
99+
// 正则表达式
100+
return exp.test(source);
101+
}
102+
103+
return false;
104+
}

bin/proxy/http.proxy.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,10 @@ function heartBeat() {
385385
}
386386

387387
// 高负载告警
388-
if (global.cpuUsed80 === 4 && !config.isTest && !isWin32Like) {
389-
afterCpu80(global.cpuUsed);
388+
if (global.cpuUsed80 === 5 && !config.isTest && !isWin32Like) {
389+
if (global.cpuUsed >= config.cpuLimit) {
390+
afterCpu80(global.cpuUsed);
391+
}
390392
}
391393

392394
const currMemory = process.memoryUsage();

bin/proxy/http.route.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const CCFinder = require('runtime/CCFinder.js');
3131
const parseBody = require('util/http/parseBody.js');
3232
const TSW = require('api/keyman');
3333
const tnm2 = require('api/tnm2');
34+
const originCheck = require('./http.origin.js');
3435

3536

3637
module.exports = function(req, res) {
@@ -244,7 +245,7 @@ module.exports = function(req, res) {
244245
res.__hasClosed = true;
245246
logger.debug('response has close');
246247

247-
this.emit('done');// let it going
248+
// this.emit('done');// let it going
248249
});
249250

250251
res.once('done', function() {
@@ -373,11 +374,12 @@ module.exports = function(req, res) {
373374
try {
374375
res.writeHead(202);
375376
} catch (e) {
376-
logger.info(`response 202 fail ${e.message}`);
377+
logger.debug(`response 202 fail ${e.message}`);
377378
} finally {
378379
res.end();
379380
}
380381
res.emit('done');
382+
return;
381383
} else if (res.finished) {
382384
res.end();
383385
res.emit('done');
@@ -478,6 +480,10 @@ function doRoute(req, res) {
478480
statusCode: args[0]
479481
});
480482

483+
if (this.__hasClosed) {
484+
this.emit('done');
485+
}
486+
481487
return fn.apply(this, args);
482488
};
483489
})(res.writeHead);
@@ -527,6 +533,12 @@ function doRoute(req, res) {
527533
// +1
528534
req.headers['tsw-trace-steps'] = steps + 1;
529535

536+
originCheck(req, res);
537+
538+
if (res.headersSent || res.finished) {
539+
return;
540+
}
541+
530542
let modulePath = httpModMap.find(mod_act, req, res);
531543

532544
if (res.headersSent || res.finished) {

bin/proxy/master.js

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ function startServer() {
106106
}, 3000);
107107

108108
logger.info('start master....');
109+
logger.info(`config from: ${config.configFrom}`);
109110
logger.info('version node: ${node}, modules: ${modules}', process.versions);
110111

111112
if (serverOS.isLinux) {
@@ -140,6 +141,7 @@ function startServer() {
140141

141142
process.title = 'TSW/worker/node';
142143
logger.info('start worker....');
144+
logger.info(`config from: ${config.configFrom}`);
143145
require('./http.proxy.js');
144146
require('runtime/jank.watcher.js');
145147

@@ -181,28 +183,27 @@ function closeWorker(worker) {
181183
closeTimeWait = Math.max(closeTimeWait, config.timeout.keepAlive);
182184
closeTimeWait = Math.min(60000, closeTimeWait) || 10000;
183185

184-
if (worker.isClosing) {
186+
if (worker.exitedAfterDisconnect) {
187+
logger.info('worker.exitedAfterDisconnect is true');
185188
return;
186189
}
187190

188-
worker.isClosing = true;
189-
190191
if (workerMap[cpu] === worker) {
191192
delete workerMap[cpu];
192193
}
193194

194195
const closeFn = (function(worker) {
195196
let closed = false;
196-
const pid = worker.process.pid;
197197

198198
return function() {
199199
if (closed) {
200200
return;
201201
}
202202
try {
203-
process.kill(pid, 9);
203+
worker.kill(9);
204+
logger.info(`worker/${worker.cpuid} ${worker.process.pid} has killed`);
204205
} catch (e) {
205-
logger.info(`kill worker message: ${e.message}`);
206+
logger.info(`worker/${worker.cpuid} kill message: ${e.message}`);
206207
}
207208

208209
closed = true;
@@ -215,7 +216,7 @@ function closeWorker(worker) {
215216
try {
216217
worker.disconnect(closeFn);
217218
} catch (e) {
218-
logger.info(e.stack);
219+
logger.info(`worker disconnect message: ${e.message}`);
219220
}
220221
}
221222

@@ -225,19 +226,16 @@ function restartWorker(worker) {
225226
return;
226227
}
227228

228-
worker.hasRestart = true;
229229
const cpu = getToBindCpu(worker);
230-
231-
cpuMap[cpu] = 0;
232-
233230
logger.info('worker${cpu} pid=${pid} closed. restart new worker again.', {
234231
pid: worker.process.pid,
235232
cpu: cpu
236233
});
237234

238235
cluster.fork(process.env).cpuid = cpu;
239-
240236
closeWorker(worker);
237+
238+
worker.hasRestart = true;
241239
}
242240

243241
// 定时检测子进程存活,15秒未响应的采取措施
@@ -261,7 +259,7 @@ function checkWorkerAlive() {
261259
}
262260

263261
// 无响应进程处理
264-
if (now - worker.lastLiveTime > checkWorkerAliveTimeout * 3 && cpuMap[cpuid] === 1) {
262+
if (now - worker.lastLiveTime > checkWorkerAliveTimeout * 3) {
265263

266264
logger.error('worker${cpu} pid=${pid} miss heartBeat, kill it', {
267265
pid: worker.process.pid,
@@ -398,7 +396,6 @@ function masterEventHandler() {
398396
}
399397

400398
workerMap[cpu] = currWorker;
401-
cpuMap[cpu] = 1;
402399

403400
// 监听子进程发来的消息并处理
404401
currWorker.on('message', function(...args) {
@@ -421,11 +418,7 @@ function masterEventHandler() {
421418
cluster.on('disconnect', function(worker) {
422419
const cpu = getToBindCpu(worker);
423420

424-
if (worker.hasRestart) {
425-
return;
426-
}
427-
428-
logger.info('worker${cpu} pid=${pid} disconnect event fired. restart new worker again.', {
421+
logger.info('worker${cpu} pid=${pid} disconnect event fired.', {
429422
pid: worker.process.pid,
430423
cpu: cpu
431424
});
@@ -438,11 +431,7 @@ function masterEventHandler() {
438431

439432
const cpu = getToBindCpu(worker);
440433

441-
if (worker.hasRestart) {
442-
return;
443-
}
444-
445-
logger.info('worker${cpu} pid=${pid} exit event fired. restart new worker again.', {
434+
logger.info('worker${cpu} pid=${pid} exit event fired.', {
446435
pid: worker.process.pid,
447436
cpu: cpu
448437
});
@@ -451,7 +440,7 @@ function masterEventHandler() {
451440
});
452441

453442
process.on('reload', function(GET) {
454-
logger.info('reload');
443+
logger.info('reload event fired.');
455444
tnm2.Attr_API('SUM_TSW_WORKER_RELOAD', 1);
456445

457446
for (const key in workerMap) {
@@ -471,8 +460,15 @@ function masterEventHandler() {
471460
logger.info('cpu${cpu} send restart message', {
472461
cpu: cpu
473462
});
474-
worker.send({ from: 'master', cmd: 'restart' });
463+
try {
464+
worker.send({ from: 'master', cmd: 'restart' });
465+
} catch (e) {
466+
logger.info('cpu${cpu} send restart to worker, error message: ${e.message} while', {
467+
cpu: cpu
468+
});
469+
}
475470
}
471+
476472
restartWorker(worker);
477473
};
478474
})(worker, cpu), timeout);

bin/proxy/so.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ BIN_DIR=$(pwd)
1212
echo "BIN_DIR: ${BIN_DIR}"
1313

1414
NODE_PATH=$(node -p process.execPath)
15-
echo "use node:$NODE_PATH"
15+
16+
if [ -e "${NODE_PATH}" ]
17+
then
18+
echo "use node:${NODE_PATH}"
19+
else
20+
echo "node cmd is not found"
21+
exit 1
22+
fi
23+
1624
ln -sf $NODE_PATH ./TSW
1725
chmod +x ./TSW
1826

0 commit comments

Comments
 (0)