前言
在对比RPC与restful时,大致有几点:
- 协议:http相对更规范,更标准,更通用,无论哪种语言都支持http协议;RPC协议性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能达到http的二倍
- 安全性:基于Http更安全一些,默认80端口,防火墙友好
防火墙友好
In TCP/IP protocol, reply are always thanks to a dynamic port. The client communicate with the server with port 135 or 111 and answer in done by a port dynamically opened by the client.
说RPC防火墙不友好,主要是应用IP与port的变化,都需要改变防火墙策略
- 一台物理机可能部署多个应用,开放多个端口
- 应用服务自动伸缩,对调用方无感知
- 如果是容器,那IP是动态的
这些情况,都会造成运维频繁变更防火墙策略,增加维护成本
应对
为了应对维护成本,在有防火墙时,可以让客户端绕行到固定的堡垒机上,这样防火墙规则就相对固定,不需要动态维护
在安全级别或者不同区域的跨区访问,需要绕行;比如同机房,或者客户端的安全级别超过了服务端安全级别,那就不需要绕行
当然如果有了绕行,客户端就能访问防火墙后面的所有服务,导致访问权限过大,就需要加入鉴权
实践
之前在《Service Mesh之Sidecar》中有过对游戏架构的说明
这儿更详细了点,加上了IDC与防火墙,就是当gameserver与跨服不在同一个IDC时,需要处理防火墙友好
对gameserver添加firewall配置项 规则格式为: idc-proxy的域名:端口|绕行白名单ip或子网掩码(多个间用,分隔) 如:idcb-cluster.proxy.com:9090|10.199.188.66/20,10.200.123.66/20
核心思想就是让需要跨区访问的client走特定的proxy-cluster,通过proxy-cluster访问背后的服务
这样防火墙策略也相对固定
逻辑
- 1.gameserver连接对应的跨服
- 2.sidecar-proxy检查有没有firewall配置项,若有,查看配置的proxy-cluster是不是域名 (一般都是域名)
- 3.通过域名nslookup找到LVS的所有IP列表
- 4.调用服务到LVS的IP
nslookup可以借助java的dnsjava:http://www.dnsjava.org/
1. try { 2. Lookup lookup = new Lookup(name, Type.A); 3. lookup.run(); 4. if (lookup.getResult() == Lookup.SUCCESSFUL) { 5. Record[] answers = lookup.getAnswers(); 6. if (answers != null && answers.length > 0) { 7. String[] addrs = new String[answers.length]; 8. for (int i = 0; i < addrs.length; i++) { 9. addrs[i] = answers[i].rdataToString(); 10. } 11. 12. return Arrays.asList(addrs); 13. } 14. } 15. } catch (TextParseException e) { 16. e.printStackTrace(); 17. }