我正在创建一个API网关,到目前为止,我可以设法使所有实例都可以工作,在这些实例中,我对要与我的API网关连接的服务器的IP和端口进行了硬编码。
我看到了几个如何使用Consul / Node.js完成服务发现的示例。
我确实找到了这个,并且我试图使它正常工作,但是我无法让观察者正常工作,并且无法将连接到该服务的IP:port组合传递给我。
以下所有文件只是一部分,而不是全部。重要的部分在那里。
这是我的app.js文件
app.listen(port, () => {
const CONSUL_ID = require('uuid').v4();
const ip = require('ip');
const my_IP = ip.address();
let options = {
name: 'api-gateway',
address: `${my_IP}`,
port: 8080,
id: CONSUL_ID,
check: {
ttl: '10s',
deregister_critical_service_after: '1m'
}
};
consul.agent.service.register(options, function(err) {
if (err) throw err;
console.log(`Registered service with ID of ${CONSUL_ID}`);
});
setInterval(() => {
consul.agent.check.pass({id:`service:${CONSUL_ID}`}, err => {
if (err) throw new Error(err);
});
}, 5 * 1000);
process.on('SIGINT', () => {
console.log(`SIGINT. De-Registering service with ID of ${CONSUL_ID}`);
consul.agent.service.deregister(CONSUL_ID, (err) => {
if(err) console.log(`Error de-registering service from consul, with error of : ${err}`);
if(!err) console.log(`De-registered service with ID of ${CONSUL_ID}`);
process.exit();
});
});
console.log(`API gateway server running express started on port ${port}.`);
});
我还有另外两个测试服务正在运行,上面我的app.js和这些测试服务之间的唯一区别是它们的服务名称为name: 'test-service',
。
这是我的路线文件
var consul = require("consul")({host: '10.0.1.248'});
var known_data_instances = [];
const apiAdapter = require('./apiAdapter')
// Keep a list of healthy services
var watcher = consul.watch({
method: consul.health.service,
options: {
service:'test-service',
passing:true
}
});
watcher.on('change', data => {
console.log('received discovery update:', data.length);
known_data_instances = [];
data.forEach(entry => {
known_data_instances.push(`http://${entry.Service.Address}:${entry.Service.Port}/`);
});
});
watcher.on('error', err => {
console.error('watch error', err);
});
const BASE_URL = known_data_instances[Math.floor(Math.random()*known_data_instances.length)];
// const api = apiAdapter(BASE_URL + ':8081');
const api = apiAdapter(BASE_URL);
// router.get('/login', isAuthorized, (req, res) => {
router.get('/login', (req, res) => {
api.get(req.path).then(resp => {
res.send(resp.data);
});
});
API适配器文件
const axios = require('axios');
module.exports = (baseURL) => {
return axios.create({
baseURL: baseURL,
});
};
从领事那里获取IP和端口后,我希望能够使用axios向不同服务器上不同服务的HTTP端点发送请求。
实际结果是:
(node:3230) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
在我看来,它没有选择URL,并且默认返回到本地主机端口80。
由于我从未使用过consul构建应用程序,因此我有点迷失了,尽管consul.io文档很棒,但在线上没有太多的指南可以简化此学习。
猜猜问题归结为,如何获得我的api适配器向我的不同服务(在这种情况下为test-service
发出请求)?