需要linux环境,这里采用虚拟机配置,采用xshell进行连接,好处是安装插件之后可以在任意目录与本地环境上传下载
常用端口查询命令:
lsof -i
lsof -i:端口号 查看端口pid
netstat -ntlp 查看所有端口
netstat -tunpl|grep 端口号 查看进程占用情况
kill -9 PID 强杀进程
yum install lrzsz
// rz 命令上传到Linux
// sz [path] 命令下载文件到本地
安装zookeeper首先需要安装jdk,然后安装zookeeper,详情见如下:
https://blog.csdn.net/kong1287988804/article/details/75639414
https://blog.csdn.net/kong1287988804/article/details/75661122
之后使用xshell连接到服务器,
./zkServer.sh start 顺利启动zookeeper服务,然后需要启动zookeeper客户端来添加节点,跳转到zookeeper所在目录的bin中
./zkCli.sh
ZooKeeper -server host:port cmd args
stat path [watch] // 查看节点状态
set path data [version] // set数据
ls path [watch] // 查看节点
delquota [-n|-b] path
ls2 path [watch] // 查看节点增强版
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version] // 删除节点路径
sync path
listquota path
rmr path // 递归删除
get path [watch] // 获取节点信息
create [-s] [-e] path data acl // 创建节点初始化数据
addauth scheme auth
quit
getAcl path
close
connect host:port
我们创建节点 /registry/HelloService/Baidu, 里面再包含name和url
create /registry data
create /registry/HelloService data
create /registry/HelloService/Baidu data
create /registry/HelloService/Baidu/name baidu
create /registry/HelloService/Baidu/url https://www.baidu.com
在根目录中新建一个文件夹zkClient,接着建文件
还是先把node环境配一下
// 在根目录 cd /
wget https://nodejs.org/dist/v12.18.1/node-v12.18.1-linux-x64.tar.xz // 下载
tar xf node-v12.18.1-linux-x64.tar.xz // 解压
mv node-v12.18.1-linux-x64 /apps/node-v12.18.1-linux-x64
vi /etc/profile
// 在最下面添加
export PATH=$PATH:/apps/node-v12.18.1-linux-x64/bin
source /etc/profile // 立即生效
[root@localhost ~]# node -v
v12.18.1
// 关闭防火墙
//centos从7开始默认用的是firewalld,这个是基于iptables的,虽然有iptables的核心,但是iptables的服务是没安装的。所以你只要停止firewalld服务即可:
sudo systemctl stop firewalld.service && sudo systemctl disable firewalld.service
// 如果你要改用iptables的话,需要安装iptables服务:
sudo yum install iptables-services
sudo systemctl enable iptables && sudo systemctl enable ip6tables
sudo systemctl start iptables && sudo systemctl start ip6tables
service iptables status
service iptables stop --停止
service iptables start --启动
// 查看端口
ifconfig -a

// client.js
var express = require('express');
var zookeeper = require('node-zookeeper-client');
var httpProxy = require('http-proxy');
var cluster = require('cluster');
var os = require('os');
var cache = {};
var CPUS = os.cpus().length;
var PORT = 8084; // 本服务,zk中转服务端口 随便
var CONNECTION_STRING = '127.0.0.1:2181'; // zk服务
var REGISTRY_ROOT = '/registry';
var app = express();
let whiteList = ['http://192.168.80.128:3000'] // 服务器ip+网站端口
app.use(function(req,res,next){
let origin = req.headers.origin;
if(whiteList.includes(origin)){
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Headers', 'Origin,Accept,Content-Type,X-Requested-With,Authorization,Referer,Access-Control-Allow-Origin,User-Agent,Service-Name,key');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTION,DELETE,PUT');
res.setHeader('Access-Control-Expose-Headers', '*');
}
next();
})
if (cluster.isMaster) {
for (var i = 0; i < CPUS; i++) {
cluster.fork();
}
}
else {
//连接zookeeper
var zk = zookeeper.createClient(CONNECTION_STRING);
zk.connect();
//创建代理服务器对象并监听错误事件
var proxy = httpProxy.createProxyServer();
proxy.on('error', function (err, req, res) {
res.end();//输出空白响应数据
});
//启动web服务器
//app.use(express.static('./'));
app.all('*', function (req, res) {
//处理图标请求
if (req.path == '/favicon.ico') {
res.end();
return;
}
//获取服务名称
var serviceName = req.get('Service-Name');
var key = req.get('key');
console.log(key);
console.log('ServiceName:%s', serviceName);
if (!serviceName) {
console.log('Service-Name request header is not exist');
res.end();
return;
}
//获取服务路径
var servicePath = REGISTRY_ROOT + "/" + serviceName;
console.log('ServicePath:%s', servicePath);
console.log('cache[serviceName]:'+JSON.stringify(cache));
if (cache[serviceName]) {
console.log("-----------cache---------------"+cache[serviceName]);
res.send(cache[serviceName])
//proxy.web(req, res, {
// target: 'http://' + cache[serviceName] //目标地址
//});
}else {
//获取服务路径下的地址节点
zk.getChildren(servicePath, function (error, addressNodes) {
console.log(addressNodes)
if (error) {
console.log(error.stack);
res.end();
return;
}
var size = addressNodes.length;
console.log(size)
if (size == 0) {
console.log('address node is not exist');
res.end();
return;
}
//生成地址容器
var addressPath = servicePath + "/";
if (size == 1) {
//若只有唯一地址,则获取该地址
addressPath += addressNodes[0];
} else {
//若存在多个地址,则获取key
addressPath += key; // 本例子中由于有name和url两个,所以取了key也就是url
}
console.log('addressPath:%s', addressPath);
//获取服务地址
zk.getData(addressPath, function (err, serviceAddress) {
if (error) {
console.log(error.stack);
res.end();
return;
}
console.log('serviceAddress:%s', serviceAddress);
if (!serviceAddress) {
console.log('serviceAddress is not exist');
res.end();
return;
}
cache[serviceName] = serviceAddress;
console.log("cache"+ serviceName+": "+cache[serviceName]);
res.send(cache[serviceName]);
//执行反向代理
//proxy.web(req, res, {
// target: 'http://' + serviceAddress //目标地址
//});
});
});
}
})
app.listen(PORT, function () {
console.log('server is running at %d', PORT);
})
}
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<div id="console"></div>
<div id="container">
<h1>
hello world
</h1>
</div>
<button id="btn" >点我一下调用服务</button>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(function () {
$("#btn").click(function () {
//alert("hello world");
$.ajax({
method: 'GET',
url: 'http://192.168.80.128:8084/hello',
headers: {
'Service-Name': 'HelloService/Baidu',
'key': 'url'
},
success: function (data) {
// 拿到的data是存的 https://www.baidu.com
$("#console").text(data);
//window.open(data)
}
})
});
})
</script>
</html>
// static.js
const express = require('express');
const app = express();
app.use(express.static('./'));
app.listen(3000, () => {
console.log('running at 3000');
})