Azure Service Fabric 踩坑日志

语言: CN / TW / HK

近期项目上面用到了Azure Service Fabric这个服务,它是用来做微服务架构的,由于这套代码和架构都是以前同学留下来的,缺少文档,项目组在折腾时也曾遇到几个问题,这里整理如下,以供参考。

我属于Service Fabric的初学者和使用者,很多概念也都是临时学习的,我们的工程师后续会更加细致的研究它。本文仅从故障排查经验总结的角度做了一点整理,有关这个服务的详细功能,或者官方推荐的最佳实践,请参考 https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-overview

  1. 有两种不同的service fabric可供选择。有条件(钱多)的话,可以选择 managed cluster, 省事,因为相当于在service fabric 基础上又封装了一层,简化了管理。

  2. 开发环境没有必要设置那么多node,除非你的钱真的富裕得难受了。以上 managed cluster 最少有5个 node(节点),我建议开发环境用原生的 service fabric,然后 1个node就可以了,但可以把虚拟机的尺寸稍微调高一点。它会提示你说这样的设置不适合生产环境,让它提示。

  3. 选择一个富裕一点的region,以便更快的扩容,如果真的有那么一天。例如目前 China Region 3 因为是新的,比较富裕。

  4. 选择新的操作系统,避免一些出现不必要的问题,如果能用container,更好。

  5. 这个 service fabric 是基于一个所谓的 vm scale set 来进行扩展的。这个scale set,你要随时注意它有没有问题。你可以通过调整下面的参考来改变node数量,但要做好心理准备,可能需要的时间比较长。但是正常情况下,你的服务应该不至于down,因为理论上它是逐个机器更新的。

  6. 创建service fabric 服务会出现一堆东西,你可能不了解它,但你不能随便删除它,万一有用呢

  7. 如果你修改了 vm scale set的东西,一定要及时查看 service fabric cluster的状态,如果它显示为 updating,那么恭喜你,它可能正在更新。但如果它一直显示为updating,你就可能要跟我们一样加几个班了。目前没有看到命令可以重启 service fabric,且错误日志不清晰,所以有时候会让人抓狂。

  8. 以上做好了,你可能以为就结束了。然鹅并不是。service fabric的资源中,虽然可以看到有一个 loadbalance的组件,而且也有一个对外的ip地址,但是它不能用来直接做微服务的对外访问,因为你的微服务可能会有N个(理论上),而每个微服务呢,建议要有独立的端口才行。这个无法在loadbalance组件中做设置。

  9. 所以你需要有一个Application Gateway 的东西,能接管前端的用户请求,并且做路由。我万万没想到,在这个环节会遇到一些挑战,教训非常惨痛。首先,你需要映射https的端口的话,当然需要准备证书。这个证书,我们建议放在 key vault中。这里要命的地方是,它在创建https listener时会让你上传一个pfx文件,并且必须要有一个password,而从key vault中导出的pfx,默认并不需要password。所以你可能需要下一段代码。

    点击查看代码
    Install-Module AzureRM
    Connect-AzureRMAccount -Environment AzureChinaCloud
    
    $vaultName = "xxxxx"
    $certificateName = "xxxxx"
    $pfxPath = [Environment]::GetFolderPath("Desktop") + "\$certificateName.pfx"
    $password = "pass@word1"
    $pfxSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $certificateName
    $pfxUnprotectedBytes = [Convert]::FromBase64String($pfxSecret.SecretValueText)
    $pfx = New-Object Security.Cryptography.X509Certificates.X509Certificate2
    $pfx.Import($pfxUnprotectedBytes, $null, [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
    $pfxProtectedBytes = $pfx.Export([Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $password)
    [IO.File]::WriteAllBytes($pfxPath, $pfxProtectedBytes)

先记录了这么多