增加服务发现功能

This commit is contained in:
zhl 2021-01-30 12:13:42 +08:00
parent 752083f1f5
commit b944d26044
4 changed files with 265 additions and 46 deletions

161
package-lock.json generated
View File

@ -272,6 +272,16 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true "dev": true
}, },
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"dateformat": { "dateformat": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
@ -290,6 +300,14 @@
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
}, },
"default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
"integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
"requires": {
"execa": "^5.0.0"
}
},
"denque": { "denque": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
@ -327,6 +345,22 @@
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"execa": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz",
"integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==",
"requires": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
"human-signals": "^2.1.0",
"is-stream": "^2.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1",
"onetime": "^5.1.2",
"signal-exit": "^3.0.3",
"strip-final-newline": "^2.0.0"
}
},
"express-fileupload": { "express-fileupload": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.0.tgz", "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.0.tgz",
@ -564,6 +598,11 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
}, },
"get-stream": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
"integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg=="
},
"glob": { "glob": {
"version": "7.1.6", "version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@ -594,6 +633,11 @@
"toidentifier": "1.0.0" "toidentifier": "1.0.0"
} }
}, },
"human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -621,16 +665,50 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
}, },
"internal-ip": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz",
"integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==",
"requires": {
"default-gateway": "^6.0.0",
"ipaddr.js": "^1.9.1",
"is-ip": "^3.1.0",
"p-event": "^4.2.0"
}
},
"ip-regex": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz",
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q=="
},
"ipaddr.js": { "ipaddr.js": {
"version": "1.9.1", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
}, },
"is-ip": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz",
"integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==",
"requires": {
"ip-regex": "^4.0.0"
}
},
"is-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
},
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
}, },
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"json-schema-traverse": { "json-schema-traverse": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@ -770,6 +848,11 @@
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true "optional": true
}, },
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
},
"middie": { "middie": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/middie/-/middie-5.2.0.tgz", "resolved": "https://registry.npmjs.org/middie/-/middie-5.2.0.tgz",
@ -793,6 +876,11 @@
"mime-db": "1.45.0" "mime-db": "1.45.0"
} }
}, },
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -914,6 +1002,14 @@
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==" "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw=="
}, },
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"requires": {
"path-key": "^3.0.0"
}
},
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@ -922,11 +1018,45 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"requires": {
"mimic-fn": "^2.1.0"
}
},
"p-event": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz",
"integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==",
"requires": {
"p-timeout": "^3.1.0"
}
},
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
},
"p-timeout": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
"requires": {
"p-finally": "^1.0.0"
}
},
"path-is-absolute": { "path-is-absolute": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
}, },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-to-regexp": { "path-to-regexp": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz",
@ -1118,11 +1248,29 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
}, },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"sift": { "sift": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
"integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
}, },
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"sliced": { "sliced": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
@ -1203,6 +1351,11 @@
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"dev": true "dev": true
}, },
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
},
"tiny-lru": { "tiny-lru": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.6.tgz", "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.6.tgz",
@ -1292,6 +1445,14 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}, },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
},
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

View File

@ -25,6 +25,7 @@
"fastify-jwt": "^2.2.0", "fastify-jwt": "^2.2.0",
"fastify-plugin": "^3.0.0", "fastify-plugin": "^3.0.0",
"fs-jetpack": "^4.1.0", "fs-jetpack": "^4.1.0",
"internal-ip": "^6.2.0",
"mime-types": "^2.1.28", "mime-types": "^2.1.28",
"mongoose": "5.10.3", "mongoose": "5.10.3",
"mongoose-findorcreate": "^3.0.0", "mongoose-findorcreate": "^3.0.0",

View File

@ -6,57 +6,62 @@ import fastify, {
} from 'fastify' } from 'fastify'
import helmet from 'fastify-helmet' import helmet from 'fastify-helmet'
import { Server, IncomingMessage, ServerResponse } from 'http' import { Server, IncomingMessage, ServerResponse } from 'http'
import {RouterMap} from './decorators/router'; import {RouterMap} from './decorators/router'
import {mongoose} from "@typegoose/typegoose"; import {mongoose} from "@typegoose/typegoose"
import logger from './logger/logger'; import logger from './logger/logger'
import {Config} from "./cfg/Config"; import {Config} from "./cfg/Config"
import {initData} from "./common/GConfig"; import {initData} from "./common/GConfig"
import { RedisClient } from './redis/RedisClient' import { RedisClient } from './redis/RedisClient'
import { initRobotCache } from './service/jcfw' import { initRobotCache } from './service/jcfw'
import { error } from './common/Debug' import { error } from './common/Debug'
import {
registerGracefulShutdown,
registService,
unRegistService
} from './utils/system.util'
const zReqParserPlugin = require('./plugins/zReqParser'); const zReqParserPlugin = require('./plugins/zReqParser')
const apiAuthPlugin = require('./plugins/apiauth'); const apiAuthPlugin = require('./plugins/apiauth')
const fs = require('fs'); const fs = require('fs')
const join = require('path').join; const join = require('path').join
let config: Config = require('../config/config.json'); let config: Config = require('../config/config.json')
require('./common/Extend'); require('./common/Extend')
export class ApiServer { export class ApiServer {
server: FastifyInstance<Server, IncomingMessage, ServerResponse>; server: FastifyInstance<Server, IncomingMessage, ServerResponse>
public constructor() { public constructor() {
this.server = fastify({logger: true}); this.server = fastify({logger: true})
this.registerPlugins(); this.registerPlugins()
} }
private registerPlugins() { private registerPlugins() {
this.server.register(require('fastify-formbody')); this.server.register(require('fastify-formbody'))
this.server.register(zReqParserPlugin); this.server.register(zReqParserPlugin)
this.server.register(apiAuthPlugin); this.server.register(apiAuthPlugin)
this.server.register( this.server.register(
helmet, helmet,
{ hidePoweredBy: false } { hidePoweredBy: false }
) )
this.server.register(require('fastify-cors'), {}); this.server.register(require('fastify-cors'), {})
} }
private registerRouter() { private registerRouter() {
logger.log('register api routers'); logger.log('register api routers')
let self = this; let self = this
for (let [controller, config] of RouterMap.decoratedRouters) { for (let [controller, config] of RouterMap.decoratedRouters) {
for(let data of config.data) { for(let data of config.data) {
logger.info('find api router', data.method || 'all', logger.info('find api router', data.method || 'all',
data.path, controller.name); data.path, controller.name)
// @ts-ignore // @ts-ignore
self.server[data.method || 'all'](data.path, { self.server[data.method || 'all'](data.path, {
preValidation: async function (request: FastifyRequest, reply: FastifyReply) { preValidation: async function (request: FastifyRequest, reply: FastifyReply) {
request.roles = config.roles; request.roles = config.roles
await this.apiAuth(request, reply); await this.apiAuth(request, reply)
} }
}, controller); }, controller)
} }
} }
} }
@ -64,38 +69,38 @@ export class ApiServer {
* controller * controller
*/ */
initControllers() { initControllers() {
logger.info('Bootstrap controllers...'); logger.info('Bootstrap controllers...')
const controllers = join(__dirname, 'controllers'); const controllers = join(__dirname, 'controllers')
fs.readdirSync(controllers) fs.readdirSync(controllers)
.filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/)) .filter((file: string) => ~file.search(/^[^.].*\.(ts|js)$/))
.forEach((file: any) => { .forEach((file: any) => {
logger.log(file); logger.log(file)
return require(join(controllers, file))}); return require(join(controllers, file))})
} }
async connectDB() { async connectDB() {
const options = {useNewUrlParser: true, const options = {useNewUrlParser: true,
poolSize: 5, poolSize: 5,
keepAlive: true, keepAlive: true,
keepAliveInitialDelay: 300000, keepAliveInitialDelay: 300000,
useUnifiedTopology: true}; useUnifiedTopology: true}
const uri = config.db_main; const uri = config.db_main
logger.info(`connect to ${uri} ...`); logger.info(`connect to ${uri} ...`)
try { try {
// await mongoose.createConnection(uri, options) // await mongoose.createConnection(uri, options)
await mongoose.connect(uri, options) await mongoose.connect(uri, options)
logger.log('DB Connected'); logger.log('DB Connected')
} catch (err) { } catch (err) {
logger.log(`DB Connection Error: ${err.message}`); logger.log(`DB Connection Error: ${err.message}`)
} }
let opts = {url: config.redis} let opts = {url: config.redis}
new RedisClient(opts) new RedisClient(opts)
} }
private setErrHandler() { private setErrHandler() {
this.server.setNotFoundHandler(function(request: any, reply: { send: (arg0: { errcode: number; errmsg: string; }) => void; }){ this.server.setNotFoundHandler(function(request: any, reply: { send: (arg0: { errcode: number, errmsg: string }) => void }){
reply.send({errcode: 404, errmsg: 'page not found'}) reply.send({errcode: 404, errmsg: 'page not found'})
}); })
this.server.setErrorHandler(function (error: FastifyError, request: FastifyRequest, reply: FastifyReply) { this.server.setErrorHandler(function (error: FastifyError, request: FastifyRequest, reply: FastifyReply) {
let statusCode = error && error.statusCode || 100; let statusCode = error && error.statusCode || 100
if (statusCode >= 500) { if (statusCode >= 500) {
logger.error(error) logger.error(error)
} else if (statusCode >= 400) { } else if (statusCode >= 400) {
@ -136,24 +141,36 @@ export class ApiServer {
error('error init robot info', err) error('error init robot info', err)
} }
} }
/**
* process意外退出
* @param {boolean} exit
* @param {Error} err
* @return {Promise<void>}
*/
public async gracefullyShutdown(exit: boolean = true, err?: Error) {
await unRegistService(config.port)
}
public async start() { public async start() {
let self = this; let self = this
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
await self.connectDB(); await registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));
await self.initCache(); await self.connectDB()
self.initControllers(); await self.initCache()
self.registerRouter(); await registService(config.port)
self.setErrHandler(); self.initControllers()
self.setFormatSend(); self.registerRouter()
initData(); self.setErrHandler()
self.setFormatSend()
initData()
this.server.listen({port: config.port}, (err: any, address: any) => { this.server.listen({port: config.port}, (err: any, address: any) => {
if (err) { if (err) {
logger.log(err) logger.log(err)
process.exit(0) process.exit(0)
} }
resolve && resolve(address); resolve && resolve(address)
}) })
}); })
} }

40
src/utils/system.util.ts Normal file
View File

@ -0,0 +1,40 @@
import { RedisClient } from '../redis/RedisClient'
import ip from 'internal-ip'
const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2']
const NODES_SET = 'poker:infosvr'
const discovery_channel = 'poker:infosvr:discovery'
export function registerGracefulShutdown(callback: (err?: Error) => void) {
/**
* Gracefully shutdown on uncaught errors
*/
process.on('uncaughtException', (err) => {
console.error(err)
callback(err)
})
signals.forEach((signal) => {
process.once(signal, () => callback())
})
}
async function getNodeAddress(port: number) {
const host = process.env.SELF_HOSTNAME || await ip.v4()
return `${ host }:${ port }`
}
export async function registService(port: number) {
const address = await getNodeAddress(port)
const client = new RedisClient()
await client.sadd(NODES_SET, address)
await client.publish(discovery_channel, `add,${address}`)
}
export async function unRegistService(port: number) {
const address = await getNodeAddress(port)
const client = new RedisClient()
await client.srem(NODES_SET, address)
await client.publish(discovery_channel, `remove,${address}`)
}