whale-nest-nacos
Version:
If you are a nest micro service architecture, you can use the SDK, so as to realize service discovery based on nacos, distributed load balancing strategy
168 lines • 9.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNacosClientGrpc = void 0;
const grpc = __importStar(require("grpc"));
const LoadBalanceService_1 = __importDefault(require("./LoadBalanceService"));
const TierService_1 = __importDefault(require("./TierService"));
const constant_1 = require("../constant");
const interface_1 = require("../interface");
const log_1 = require("../nacosLogger/log");
const getNacosClientGrpc = (_a) => __awaiter(void 0, void 0, void 0, function* () {
var { mode = interface_1.Mode.Config, localEnvString = 'localhost', localhost, group = 'GRPC', serviceName, packageName, protoPath, loadBalance } = _a, grpcOptions = __rest(_a, ["mode", "localEnvString", "localhost", "group", "serviceName", "packageName", "protoPath", "loadBalance"]);
let loadBalanceInstance;
// 如果BFF部署的tier环境
if (constant_1.TIER_VERSION && constant_1.TIER_ENVIRON && constant_1.TIER_NAMESPACE) {
loadBalanceInstance = new TierService_1.default(Object.assign({ group,
serviceName,
packageName,
protoPath,
loadBalance }, grpcOptions));
}
else {
loadBalanceInstance = new LoadBalanceService_1.default(Object.assign({ group,
serviceName,
packageName,
protoPath,
loadBalance }, grpcOptions));
}
// 如果传入localhost,则创建连接并返回连接实例,当前端本地直连后端ip地址时,可采用此方法
if (localhost && process.env.NODE_ENV === localEnvString) {
return loadBalanceInstance.createClientGrpc(localhost, packageName, protoPath);
}
yield loadBalanceInstance.ready();
// 本地开发环境,且mode为Config,则使用nacos的配置创建连接,不走负载均衡策略
if (process.env.NODE_ENV === localEnvString && mode === interface_1.Mode.Config) {
yield loadBalanceInstance.getConfig(serviceName, packageName, protoPath);
return loadBalanceInstance.singleClientGrpc;
}
// 获取nacos实例,创建实例连接池
yield loadBalanceInstance.buildConnectioPool(serviceName, packageName, protoPath);
if (loadBalanceInstance.hasInstance) {
// 订阅实例变更
loadBalanceInstance.subscribe(serviceName, packageName, protoPath);
}
// 服务跨集群
if (loadBalanceInstance.hasInstance && loadBalanceInstance.serviceClusterName !== constant_1.WHALE_CLUSTER_INFO) {
yield loadBalanceInstance.getGrpcProxyConfig(packageName, protoPath);
}
// 订阅配置变更
yield loadBalanceInstance.getConfig(serviceName, packageName, protoPath);
return {
getService: function (serviceName) {
return new Proxy({}, {
get: (target, key) => {
let client;
// 没有获取到实例则无需走负载均衡决策流程
if (loadBalanceInstance.hasInstance) {
client = loadBalanceInstance.selectOneConnectionByLoadbalance();
// 跨集群
if (loadBalanceInstance.serviceClusterName !== constant_1.WHALE_CLUSTER_INFO) {
const proxyClient = loadBalanceInstance.proxyClientGrpc;
const service = proxyClient === null || proxyClient === void 0 ? void 0 : proxyClient.getService(serviceName);
return (...args) => {
const metadata = new grpc.Metadata();
let metadataArgs;
if (args && args.length > 1) {
metadataArgs = args[1];
const metaMap = metadataArgs.getMap();
for (const key in metaMap) {
metadata.add(key, metaMap[key]);
}
}
// @ts-ignore
metadata.add('x-envoy-original-dst-host', client === null || client === void 0 ? void 0 : client.url);
args[1] = metadata;
(0, log_1.log)("请求信息:", {
serviceName: loadBalanceInstance.serviceName,
mode: 'proxy',
clusterName: loadBalanceInstance.serviceClusterName,
clusterName_bff: constant_1.WHALE_CLUSTER_INFO,
// @ts-ignore
"grpc-proxy": proxyClient.url,
interface: key,
params: args
});
return service[key](...args);
};
}
else {
(0, log_1.log)("请求信息:", {
serviceName: loadBalanceInstance.serviceName,
// @ts-ignore
ip: client === null || client === void 0 ? void 0 : client.url,
interface: key,
mode: 'Pods',
connectionPool: loadBalanceInstance.instancePool
});
const service = client === null || client === void 0 ? void 0 : client.getService(serviceName);
return service[key];
}
}
else {
client = loadBalanceInstance.singleClientGrpc;
(0, log_1.log)("请求信息:", {
serviceName: loadBalanceInstance.serviceName,
// @ts-ignore
ip: client === null || client === void 0 ? void 0 : client.url,
interface: key,
mode: 'config'
});
if (!client) {
throw new Error(`服务${loadBalanceInstance.serviceName}没有可用连接,请确认nacos是否存在该服务配置`);
}
const service = client === null || client === void 0 ? void 0 : client.getService(serviceName);
return service[key];
}
}
});
}
};
});
exports.getNacosClientGrpc = getNacosClientGrpc;
//# sourceMappingURL=getNacosClientGrpc.js.map