通信:远程过程调用(RPI)

背景

你已经使用了微服务架构。服务需要处理来自应用客户端的请求。将来,服务有时必须协作起来处理这些请求。他们必须采用一种内部通信协议。

限制

解决方案

使用RPI来进行内部服务通信。客户端采用以请求 / 回复为基础的协议请求其他服务。

示例

有一些RPI技术的例子:

  • REST
  • gRPC
  • Apache Thrift

微服务示例程序里的RegistrationServiceProxy是用Scala语言写的一个例子,它用Spring框架的RestTemplate发起REST请求。

@Component
class RegistrationServiceProxy @Autowired()(restTemplate: RestTemplate) extends RegistrationService {

  @Value("${user_registration_url}")
  var userRegistrationUrl: String = _

  @HystrixCommand(commandProperties=Array(new HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="800")))
  override def registerUser(emailAddress: String, password: String): Either[RegistrationError, String] = {
    try {
      val response = restTemplate.postForEntity(userRegistrationUrl,
        RegistrationBackendRequest(emailAddress, password),
        classOf[RegistrationBackendResponse])
      response.getStatusCode match {
        case HttpStatus.OK =>
          Right(response.getBody.id)
      }
    } catch {
      case e: HttpClientErrorException if e.getStatusCode == HttpStatus.CONFLICT =>
        Left(DuplicateRegistrationError)
    }
  }
}

user_registration_url的值通过外部配置提供

结果

这个模式有以下优势:

  • 简单,也被大家熟悉
  • 请求 / 回复机制很简单
  • 由于没有中间件,系统更简单

这个模式有以下弊端:

  • 通常仅仅支持请求 / 回复机制,而不支持其他交互模式,比如通知,请求 / 异步响应,发布 / 订阅,发布 / 异步响应
  • 由于客户端和服务在交互过程中必须可用,因此降低了整体可用性

这个模式有以下问题:

  • 客户端必须发现服务实例的地址

相关模式

  • 领域特定的协议 是个替代方案
  • 消息 是个替代方案
  • 外部配置 提供了服务的逻辑网络地址,比如URL。
  • 客户端必须使用 客户端发现 或者 服务端发现 的方式定位一个服务实例
  • 客户端通常需要采用 断路器模式 来提高可靠性

你可能感兴趣的:(通信:远程过程调用(RPI))