背景
你已經(jīng)使用了微服務(wù)架構(gòu)。服務(wù)需要處理來(lái)自應(yīng)用客戶端的請(qǐng)求。將來(lái),服務(wù)有時(shí)必須協(xié)作起來(lái)處理這些請(qǐng)求。他們必須采用一種內(nèi)部通信協(xié)議。
限制
解決方案
使用RPI來(lái)進(jìn)行內(nèi)部服務(wù)通信??蛻舳瞬捎靡哉?qǐng)求 / 回復(fù)為基礎(chǔ)的協(xié)議請(qǐng)求其他服務(wù)。
示例
有一些RPI技術(shù)的例子:
微服務(wù)示例程序里的RegistrationServiceProxy是用Scala語(yǔ)言寫(xiě)的一個(gè)例子,它用Spring框架的RestTemplate發(fā)起REST請(qǐng)求。
@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的值通過(guò)外部配置提供
結(jié)果
這個(gè)模式有以下優(yōu)勢(shì):
- 簡(jiǎn)單,也被大家熟悉
- 請(qǐng)求 / 回復(fù)機(jī)制很簡(jiǎn)單
- 由于沒(méi)有中間件,系統(tǒng)更簡(jiǎn)單
這個(gè)模式有以下弊端:
- 通常僅僅支持請(qǐng)求 / 回復(fù)機(jī)制,而不支持其他交互模式,比如通知,請(qǐng)求 / 異步響應(yīng),發(fā)布 / 訂閱,發(fā)布 / 異步響應(yīng)
- 由于客戶端和服務(wù)在交互過(guò)程中必須可用,因此降低了整體可用性
這個(gè)模式有以下問(wèn)題:
- 客戶端必須發(fā)現(xiàn)服務(wù)實(shí)例的地址
相關(guān)模式
- 領(lǐng)域特定的協(xié)議 是個(gè)替代方案
- 消息 是個(gè)替代方案
- 外部配置 提供了服務(wù)的邏輯網(wǎng)絡(luò)地址,比如URL。
- 客戶端必須使用 客戶端發(fā)現(xiàn) 或者 服務(wù)端發(fā)現(xiàn) 的方式定位一個(gè)服務(wù)實(shí)例
- 客戶端通常需要采用 斷路器模式 來(lái)提高可靠性