前言
在对比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时,需要处理防火墙友好
代码语言:javascript复制对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/
代码语言:javascript复制try {
Lookup lookup = new Lookup(name, Type.A);
lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
Record[] answers = lookup.getAnswers();
if (answers != null && answers.length > 0) {
String[] addrs = new String[answers.length];
for (int i = 0; i < addrs.length; i ) {
addrs[i] = answers[i].rdataToString();
}
return Arrays.asList(addrs);
}
}
} catch (TextParseException e) {
e.printStackTrace();
}