2018-08-30 14:28:46.0|分类: docker+node.js+zookeeper构建微服务|浏览量: 1341
前面讲述了service自动注册到zookeeper节点。 自注册:服务内部启动客户端,连接注册中心,写入服务信息。(前面代码使用了这种模式) 缺点:(1)服务注册框架与应用程序相耦合 (2)容器内部应用无法获取到容器外部的端口号。 (3)zookeeper中的服务无法自行删除节点 项目registration-service使用自注册,registration-service在spring-boot启动时候将server.address=0.0.0.0,server.port=8080 自动注册到zookeeper中 docker启动java镜像,8080是docker实例内部的端口号,外部端口号做了映射,zookeeper报错的ip+端口号没有实际使用意义,所以要想办法解决这个问题。 第三方注册(本文采用方式):采用协同进程的方式,监听服务进程的变化,将服务信息写入注册中心。 Registrator监控新建的Docker容器,并且检查判定这些容器提供的服务。docker宿主机器安装registrator,registrator监听docker宿主机器中启动的实例,并且将实例注册到服务中心zookeeper节点。结构设计图如下: docker run -d -v /var/run/docker.sock:/tmp/docker.sock --net=host --name=registrator gliderlabs/registrator -ip 192.168.99.100 zookeeper://192.168.99.1:2181/registry -v关联docker引擎运行时所产生的/var/run/docker.sock文件映射到registrator内部 --net为了确保zookeeper能链接到,并且能访问Registrator,使用host=net -ip当前宿主机所在的ip地址,另一个是zookeeper链接方式 查看zookeeper节点。/registry/registry是本地的registry,/registry/render-services是自己打包的服务 上图对应下面的位置 项目中更改node.js网关代码 var express = require('express'); var zookeeper = require('node-zookeeper-client'); var httpProxy = require('http-proxy'); var port = 1234; //zookeeper服务地址 var CONNECT_URL = "127.0.0.1:2181"; var REGISTRY_ROOT = "/registry"; //创建zookeeper连接 var zk = zookeeper.createClient(CONNECT_URL); zk.connect(); //创建http代理 var proxy = httpProxy.createProxyServer(); proxy.on('error', function (err, req, res){ res.end(); return ; }); //web var app = express(); app.use(express.static('public')); app.all('*', function (req, res){ if(req.path=='/favison.ico'){ res.end(); return ; } //获取服务名称,服务名称是zookeeper节点 var serverName = req.get('Service-Name'); console.log('Service-name is : '+serverName); if(!serverName){ console.log('Service-name is not exist '); res.end(); return ; } //组装服务节点路径 /registry/helloServce var servicePath = REGISTRY_ROOT +"/"+serverName; console.log('Service path is '+servicePath); //获取服务节点下面所有的节点,也就是服务实例列表 zk.getChildren(servicePath, function(error, addressNodes){ if(error){ console.log(error.stack); res.end(); return ; } var length = addressNodes.length; if(length==0){ console.log('address node is zero '); res.end(); return ; }else{ console.log('address node length is '+length); } //如果只有一个服务实例,直接使用,如果超过1个,则随机选择 var addressPah = ""; if(length==1){ addressPah = addressNodes[0]; }else{ addressPah = addressNodes[parseInt(Math.random()*length)]; } console.log('addressPah is '+addressPah); //获取服务实例的IP+端口号 //转发请求 proxy.web(req, res,{ target:'http://'+addressPah }); }); }); app.listen(port, function (){ console.log('server is running by ' + port); }); 浏览器执行 控制台打印: server is running by 1234 Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8881 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8880 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8880 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8881 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8880 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8881 Service-name is : undefined Service-name is not exist Service-name is : render-services Service path is /registry/render-services address node length is 2 addressPah is 192.168.99.100:8881 Service-name is : undefined Service-name is not exist |