目录
一、跨语言体系带来的挑战
微博的主要开发语言是Java和PHP,近几年也有一些使用Go开发的系统。而使用不同的语言开发出来的微服务,在相互调用时会存在两方面的挑战
1.服务之间的通信协议选择合适的序列化方式
比如用Java开发一个RPC服务,使用的是Java原生的序列化方式。这种序列化方式对于其它语言并不友好,那么,你使用其它语言调用这个RPC服务时,就很难解析序列化之后的二进制流。建议在选择序列化协议时,考虑序列化协议是否对多语言友好,比如,你可以选择Protobuf、Thrift,这样一来,跨语言服务调用的问题,就可以很容易地解决了。
2.使用新语言开发的微服务无法使用之前积累的服务治理的策略
比如RPC客户端在使用注册中心订阅服务的时候,为了避免每次RPC调用都要与注册中心交互,一般会在RPC客户端缓存节点的数据。如果注册中心中的服务节点发生了变更,那么RPC客户端的节点缓存会得到通知,并且变更缓存数据。这些策略在开始的时候,都是使用Java语言来实现的,并且封装在注册中心客户端里提供给RPC客户端使用。如果更换了新的语言,这些逻辑就都要使用新的语言实现一套。
二、Service Mesh是如何工作的
1.什么是Service Mesh
Service Mesh主要处理服务之间的通信,它的主要实现形式就是在应用程序同主机上部署一个代理程序。一般来讲,我们将这个代理程序称为“Sidecar(边车)”,服务之间的通信也从之前的客户端和服务端直连。
RPC客户端将数据包先发送给与自身同主机部署的Sidecar,在Sidecar中经过服务发现、负载均衡、服务路由、流量控制之后,再将数据发往指定服务节点的Sidecar,在服务节点的Sidecar中,经过记录访问日志、记录分布式追踪日志、限流之后,再将数据发送给RPC服务端。这种方式可以把业务代码和服务治理的策略隔离开,将服务治理策略下沉,让它成为独立的基础模块。
业界提及最多的Service Mesh方案当属Istio
2.如何将流量转发到Sidecar中
使用iptables的方式来实现流量透明的转发,而Istio就默认了使用iptables来实现数据包的转发
假设服务的节点部署在9080端口上,Sidecar开发的端口是15001,那么流入流出流量的流向如下:
Iptables方式的优势在于对业务完全透明, 业务甚至不知道有Sidecar存在,这样会减少业务接入的时间。不过它也有缺陷,那就是它是在高并发下,性能上会有损耗,因此国内大厂采用了另外一种方式:轻量级客户端