eureka-client-ts
Version:
118 lines (102 loc) • 3.13 kB
text/typescript
import { Eureka, EurekaClient } from 'eureka-js-client';
const address = require("address")
import client from './client';
import Pool from './pool';
import { sleep } from './utils';
interface IEureka {
port: number;
appName: string;
services: string[];
}
let NODE_ENV = process.env.NODE_ENV || 'dev';
export default class Eurekaclient {
private eureka: Eureka;
private opts: IEureka;
private pool: Pool;
constructor(options: IEureka) {
options.services.push(options.appName);
this.opts = options;
this.eureka = client(options);
this.pool = new Pool(this.eureka, this.opts.services);
}
/**
* 启动eureka
* @returns Promise<Eureka>
*/
async start() {
const { opts, eureka } = this;
if (NODE_ENV) eureka.start()
await sleep(5000)
// 如果是生产环境,开启服务掉线校验
this.checkServiceHasNeedRegistry(opts.appName)
}
/**
* stop
*/
stop() {
this.eureka.stop();
}
/**
* 获取指定应用的ip
* @param {(string | number)} name 应用名
* @param {(string)} localIp 客户端IP
* @param {string} [filterGroup] 要过滤的group service
*/
getHost(name: string | number, localIp: string, filterGroup?: string) {
if (!NODE_ENV) {
const ip = address.ip();
return `http://${ip}:${this.opts.port}`
}
return this.pool.getHost(name, localIp, filterGroup)
}
/** 获取代理信息(客户端IP, serviceGroupKey) */
getProxyInfoFromReq(req: any) {
const name = '_duibaServiceGroupKey';
const reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
// 获取多场景的cookie
let arr = [];
let serviceGroupKey = ''
if (req.headers.cookie && (arr = req.headers.cookie.match(reg))) {
serviceGroupKey = unescape(arr[2]);
}
// 获取客户端ip地址
let ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddres || req.socket.remoteAddress || '';
if (ip.indexOf('::ffff:') !== -1) {
ip = ip.substring(7);
}
return { ip, serviceGroupKey }
}
/**
* 获取所有eureka
*/
getAllEurekas(): EurekaClient.EurekaInstanceConfig[] {
return this.pool.getAllEurekas();
}
/**
* 获取所有实例下的host
*/
getAllHostName() {
return this.pool.getAllHostName();
}
/**
* 检查eureka服务是否掉线,掉线则重新注册服务
* @param {string} appName
* @memberof Eurekaclient
*/
checkServiceHasNeedRegistry(appName: string) {
let timer = null
// 服务开始注册后1分钟启动监听,每隔10s检查该服务是否不存在,如不存在重新注册
timer = setInterval(async () => {
const instances = await this.eureka.getInstancesByAppId(appName);
if (instances?.length === 0) {
console.log('服务出错')
global['Log']?.error(`eureka`, `${appName} 服务掉线`)
clearInterval(timer)
await this.eureka.start()
global['Log']?.error(`eureka`, `${appName} 重新注册`)
await sleep(10000)
this.checkServiceHasNeedRegistry(appName)
}
}, 10000)
}
}