搭建Grpc微服务集群
- 某单一的微服务,比如:micro_a, 部署在一台机器上挂掉后, 不管是微服务机器挂掉
- 还是consul_client挂掉,都会导致整个微服务不可访问,这时候我们就需要进行微服务的集群
- 也就是 micro_a 的微服务不能部署到一台机器上,比如拷贝出 micro_a_01, micro_a_02等
- 同样,部署在不同机器上的 micro_a_01 的服务连的 consul_client 也不是一台机器
- 而是多台(这里借助之前的consul集群实现)
- Grpc微服务集群主要实现的是微服务的负载均衡,实现同样的微服务部署在不同的服务器的功能
- 同一个微服务的不同应用使用同样的注册名
- 同一个微服务的不同应用注册服务的时候使用不同的id,不同的端口或者ip
- 微服务代码如下
1 )微服务1
consul.agent.service.register({id: "micro_a_01", // 这里id不同name: "micro_a", // 这里服务名保持相同address: "xx.xx.xx.xx", // 尽可能ip地址不同port: 8000,check: { // 配置健康检查tcp: "xx.xx.xx.xx:8000", // ip或端口不同,尽可能ip不同,部署在不同机器上interval: '10s',timeout: '5s',}
},(err)=>{if (err) throw err;console.log("micro_a服务注册consul成功 => micro_a_01")
})
2 ) 微服务2
consul.agent.service.register({id: "micro_a_02", // 这里id不同name: "micro_a", // 这里服务名保持相同address: "yy.yy.yy.yy", // 尽可能ip地址不同port: 8080,check: { // 配置健康检查tcp: "yy.yy.yy.yy:8080", // ip或端口不同,尽可能ip不同,部署在不同机器上interval: '10s',timeout: '5s',}
},(err)=>{if (err) throw err;console.log("micro_a服务注册consul成功 => micro_a_02")
})
-
当一台微服务挂掉,我们怎么让服务仍然正常运行,需要在客户端调用微服务前进行负载均衡的处理
-
consul 负载均衡微服务代码如下
// 下面用async await 写法更好,但仅仅作为一个演示, 就不改了 consul.health.service("micro_a").then((services) => {const servicesList = []; // 过滤存活的微服务for (let i = 0; i < services.length; i++) {if(services[i].Checks[1].Status == "passing") {servicesList.push(services[i])}}if (!servicesList.length) {console.log('服务已经全部挂掉 ~')return}const index = Math.floor(Math.random() * servicesList.length) // 在存活的服务中,随机选择一个const { Address, Port } = servicesList[index].Serviceconst host = Address + ":" + Port// 模拟调用微服务micro_a的某个接口const microAClient = new microAProto.microA(host, grpc.credentials.createInsecure())microAClient.getSomeOne({ id: 1 }, (err, data) => {if (err) throw err;console.log(data)}) })
-
这样,微服务集群已经配置好了,但是上述调用写法可以抽离出一个公共的方法包出来
-
在调用前基于健康的服务进行随机选择微服务机器进行调用,实现了微服务集群的负载均衡
-
我们同时借助了consul集群,保证了服务的稳定运行,但是我们还应当实现API网关的集群
- 正常我们调用微服务,一种是前端直接调用,前端直接调用会走API网关,也就是提供一个接口,接口来调用微服务
- 上面这个图示架构中,所有的微服务调用前都要设计一层API网关,由网关来调用微服务
- 而consul的客户端集群也实现了,在consul客户端只进行了转发,而consul服务端涉及保存配置信息和查询服务
- consul客户端一般不容易挂掉,但是我们也要实现它的集群,一般,一个micro_a服务和一个consul_client一一对应
- 比如:micro_a_01 对应 consul_client_01, micro_a_02 对应 consul_client_02, 都是micro_a的服务,部署在01和02机器上
- 都是consul_client也部署到不同的01和02机器上,只要一个链路挂掉,其他链路仍可保持访问畅通
- 而且在API网关层也实现了集群,一个网关对应一个consul_client, 与consul_client与micro_a服务是同样的设计
- 当客户端访问API网关前再加上一层Nginx,可以负载均衡不同的网关