您所在的位置:一起开源 >> 草根开源

基于微软Azure、.NET Core和Docker的博客系统

        首先简要介绍一下目前的站点功能吧。右图就是本站的主页效果,我做得很简洁,没有用太多花哨的图片,也没有用走马灯。明眼人一看就知道这是基于ASP.NET MVC而开发的Web应用程序,使用了Bootstrap。不错,基本答对!需要强调的是,这个博客站点以及后端的RESTful服务,全部都是基于ASP.NET Core完成的,.NET Core运行时版本为1.1.0,运行在Docker容器中。哎,说着说着又到技术上了,功能还没介绍完呢。说到功能,目前功能很简单:主页列出了我自己原创或者翻译的所有文章,读者可以注册用户帐号,注册用户可以发表评论,也可以在用户管理页面中更改自己的昵称。好了,目前功能就这么多,别看功能少,我可是前前后后陆陆续续花了2个月的时间,才做到目前这个样子。当然,我会继续更新这个站点,让它的功能变得更加完善。

提到ASP.NET Core,有没有吊起你的技术胃口呢?不用着急,接下来我就介绍一下整个站点中各部分的技术选型,看完后,或许你会知道为什么我花了2个月的业余时间,才整出来这么个简单的玩意儿。

1.png

站点技术介绍

整体架构

整个网站所采用的所有基础设施全部运行在微软云(Windows Azure)中,使用了部分托管资源,以及一些非托管的Azure VM。大致情况如下:

  • 图片存储服务:由Azure Blob Storage Service托管

  • 数据库系统:由Azure SQL Database托管(未启用Geo-Replication,因为没钱)

  • 邮件服务:由Azure SendGrid Account托管(Pricing Tier为F1,每月可以免费发送25000封邮件)

  • 应用服务器:基于Azure构建的Ubuntu 16.04.1 LTS虚拟机,运行了两个Docker容器:blog-web和blog-service,分别托管前端Web站点和后端RESTful服务。后端RESTful API服务没有做任何认证和授权,Web站点通过内部子网访问RESTful API服务,Docker容器运行在非托管环境中

  • 持续集成系统:Jenkins,基于Azure构建的Windows Server 2012 R2一台(Master),和一台Ubuntu 16.04.1 LTS(Slave)。站点的前端和后端都在后者(Ubuntu)中完成编译、打包以及Docker镜像的发布,实现了一步到位的部署方式

  • 代码库:Github

有人会问:为什么使用了非托管的Azure VM环境运行应用系统?我也考虑过这个问题,理论上讲,基于云的系统架构最好选用托管的PaaS服务,这样不仅可以得到纯天然的高可用性(包括灾备,比如AWS的跨AZ部署,某些服务跨区域的可用性,以及负载均衡),而且还可以得到专业的技术支持。只有当存在老系统向云迁移的需求,并需要迎合老系统的特定运行环境要求时,才考虑使用IaaS服务。虽然虚拟机等这些资源是由Azure负责创建并运行的,在这一层面Azure可以保证虚机的可用性,但虚机内部运行的任何程序的状态,以及所使用的数据,Azure等云服务是无从得知的,对这部分东西的监控也会变得很麻烦。出于安全考虑,通常云服务供应商是不会,也不应该获得类似虚机内部的客户程序的运行数据的,使用虚拟机服务所产生的程序运行风险,客户需要自己承担。这也就是著名的责任共担原则。

看起来用虚拟机运行应用不是太靠谱嘛,然而我却选择这么使用了。有几个原因:

  • 为何不使用Azure Web App?一方面Jenkins做自动化部署,直接把编译好的应用推送到Azure Web App中好像不是太顺手,要写一些PowerShell的代码,可是我的编译系统是Linux,不过现在已经有Linux版的PowerShell了,而且Azure SDK Command Line Interface也有Linux版,所以这个理由有点牵强,更合理的解释是:劳资不会!另一方面,我没有在服务端做认证和授权,仅通过子网向外界提供服务,所以我希望我的Web App也运行在子网内部,然后向外暴露80端口供外界访问。这样一来,Azure Web App又如何部署到我自己的子网内?这是一个技术问题,我相信一定有解决方案,但是我也没太多时间和精力去细究如何实现,自己的第一反应也无非是将前后端全部部署在Azure Web App中,然后打开后端的认证机制。但这样做又要花一些额外的工夫。好吧,还是这个理由:劳资不会

  • 为何不使用Azure Container Service?Azure Container Service会在你指定的Resource Group(资源组)中创建一整套网络部署,包括好几台虚拟机、公网IP、两个负载均衡器等等,我想你一定知道我为什么没有选择Azure Container Service了,原因就是:劳资没钱

理由够充分吧?微软Windows Azure提供的这些服务都很赞,我没选不是说它们不好用,而是出于自己的实际情况考虑:

  1. 某些服务的学习成本

  2. 经济成本

  3. 暂时没必要做到99.99999%的高可用率

  4. 即使应用挂了,恢复的成本很小:数据完全不需要恢复,托管的SQL Database、Blob Storage会保证我的数据不丢失,应用程序恢复也很简单:重新运行Docker容器就完事儿

OK,从整体架构上看,我的选择即是如此而已,这样的选择当然不一定完全正确,但我觉得至少合适,仅供参考。下面附上本站点的整体架构图。

2.png

作几点注解:

  1. 三台VM位于同一个Virtual Network的subnet中,每台VM的虚拟网卡上都套有独立的Network Security Group(NSG),在NSG上设置了Inbound/Outbound Endpoints,严格限制了端口访问的IP地址。三台VM之间使用subnet IP地址访问

  2. Windows Server 2012 VM宿主了Jenkins Master,以及Seq日志服务。它向公网暴露8080端口和5342端口,分别用于访问Jenkins服务和Seq管理界面

  3. 第一台Ubuntu VM运行了Jenkins Slave,它不向公网暴露任何端口,仅向Jenkins Master机器暴露22端口,用于Jenkins Slave Agent的执行调度

  4. 第二台Ubuntu VM运行了博客系统的两个Docker容器:前端应用程序blog-web和后端RESTful API服务程序blog-service。web通过子网IP地址访问service,VM仅向公网暴露80端口,后台service无法从公网访问

  5. 两个Docker容器所运行的应用(blog-web和blog-service)都可以访问托管的Azure SQL database、Azure Storage blob和SendGrid Account服务

  6. 整个部署的拓扑结构有可能不太合理,比如没有做负载均衡,没有使用托管的应用宿主服务(比如Azure Web App、Container Service等),没有使用Scaleset。因为目前没必要而且没钱



更多说明,详见作者的博客:http://daxnet.me/blogposts/post/221

软件首页 软件下载
  • 开发语言:C#
  • 收录时间:2016-12-06
  • 授权协议:未知
  • 支持的操作系统:Windows,Linux,Mac
  • 软件评级: 软件评级 软件评级 软件评级 软件评级 软件评级
相关软件