.Net 微服务架构技术栈的那些事

1、前言

你们一直都在谈论微服务架构,园子里面也有不少关于微服务的文章,前几天也有一些园子的朋友问我微服务架构的一些技术,我这里就整理了微服务架构的技术栈路线图,这里就分享出来和你们一块儿探讨学习,同时让新手对微服务相关技术有一个更深刻的了解。html

2、技术栈

2.1 工欲善其事,必先利其器

如今互联网盛行的年代,互联网产品也层出不穷,受欢迎的互联网产品都有一个比较牛的技术团队,我这里分享下.net 微服务架构技术栈图以下:
node

俗话说得好:工欲善其事,必先利其器。一个优秀的工程师应该善于使用框架和工具,在微服务这一块的技术选型并不是一蹴而就,须要通过日积月累和落地的项目才能完善。
下文我会一一分享技术栈中的主要框架和工具的使用场景,这篇文章就不一一分享实战例子。linux

2.2 微服务

微服务如何“微”?

微服务,固然核心是主题是“微”,怎么微呢?应该如何微呢?在我刚来杭州的时候接触过一个电商系统的单体架构,系统比较庞大,结合了各类电商该拥有的业务逻辑和场景,
代码也比较难于维护,前先后后接手的人也比较多,代码耦合度过高,改个业务逻辑基本上是牵一发而动全身,跟我上个月分享的关于
Asp.Net Core 中IdentityServer4 受权中心之应用实战的文章中的电商系统最初的架构图相似,以下:

那针对这个架构就有可“微”之谈了。ios

这里针对该单体架构能够作以下几个原则上进行“微”服务:git

  • 根据业务来进行拆分,一个业务一个服务原则进行拆分,作到通用性业务服务模块,这样业务之间能够作到高内聚低耦合。后面随意改动哪一块业务,只须要去改动这一块的业务微服务便可,其余业务不会受到影响。
  • 一个业务模块一个独立的数据库为原则,相互平行的业务作到不须要相互依赖调用。
  • 外层API网关进行业务逻辑的整合。
  • 一个业务数据库一个微服务为原则。
  • 结合分布式服务,能够快速版本迭代,发布平滑发布,不受时间影响,没时每刻均可以发布,无需半夜等到12点进行发布。(比较痛苦的发布,犹如三日凌空般(有点夸张),曾经有段时间是每周都有那么几个晚上痛苦的发布,一发布就多是凌晨4,5点,不少时候发布完,还要通过各类测试,最后发现问题还得线上改bug,咱们回去的时候别的同事已经来上班了;当时咱们的技术大佬说过这么一句话:“他连续一周都没看到过他的儿子,回去的时候,他儿子早就睡着了,起来上班的时候,他儿子已经去学校了”,你们必定也有过这样的发布经历。)

按照上面的原则后,原来的电商单体架构微服务改造升级后架构图以下:
github

架构图粗略的画了下,可以代表意思便可,微服务、Dockerk8s那一块简要的归纳,没有详细画出具体的图。web

微服务集群

微服务已经“微”好了,那须要一个服务发现的数据中心,这里就该用到Consul了,Consul主要用来注册服务,及服务发现,以及服务的健康检查,咱们能够根据须要针对某些业务服务进行自动扩容,添加服务器及扩张服务集群,一台服务挂了,Consul会自动选择可用的服务节点进行链接使用,这样总体电商系统稳定性大大增大。
须要了解Consul更加详细的特性和搭建,能够点击5分钟看懂微服务架构下的Consul 特性及搭建 一文阅读。sql

微服务如何保证数据的一致性

之前单体架构应用,对于业务之间的耦合是经过事务保证数据的一致性的,那对于微服务而言怎么作到数据的一致性呢?上门也说了,微服务应该作到业务之间没有依赖关系,每个业务都是独立的一个服务,那这样怎么保证业务与之间的数据的一致性也存在很大的一个问题,也是业界对微服务争议比较大的一个话题,那到底该如何保证数据的一致性?docker

在分布式系统架构中有一个CAP理论:任何分布式系统只可同时知足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两点,无法三者兼顾。对于分布式系统来讲,分区容错性是基本要求,不然就失去了价值。所以,就只能在可用性和一致性之间作出选择。若是选择提供一致性须要付出在知足一致性以前阻塞其余并发访问的代价。这可能持续一个不肯定的时间,尤为是在系统已经表现出高延迟时或者网络故障致使失去链接时。依据目前的成功经验,可用性通常是更好的选择,可是在服务和数据库之间维护数据一致性是很是根本的需求,微服务架构中选择知足最终一致性。数据库

最终一致性是指系统中的全部数据副本通过一段时间后,最终可以达到一致的状态。
这里所说的一段时间,也要是用户可接受范围内的一段时间。

从一致性的本质来看,就是在一个业务逻辑中包含的全部服务要么都成功,要么都失败。那咱们又该如何选择方向,来保证成功仍是保证失败呢?就是就须要根据业务模式作出选择。实现最终一致性有三种模式:可靠事件模式、业务补偿模式、TCC模式,这里就再也不延伸,后面有机会再来分享学习。

2.3 微服务开源框架

我这里微服务架构使用的是开源微服务框架 core-grpc 开源框架源代码地址:https://github.com/overtly/core-grpc
前面我分享过一篇关于 【.net core】电商平台升级之微服务架构应用实战(core-grpc)
中简单描述了微服务的基本概念和利弊,这里就再也不分享,具体应用也能够点击【.net core】电商平台升级之微服务架构应用实战(core-grpc) 阅读

2.4 ORM框架

微服务中使用的ORM Dapper ,而使用的的第三方开源组件是core-data,开源做者对dapper 进行了一次封装,开源框架源代码地址:https://github.com/overtly/core-data

core-data主要优点:

  • 官方建议使用DDD 领域驱动设计思想开发
  • 支持多种数据库,简单配置添加连接的配置便可
  • 多数据库的支持
  • 支持分表操做,自定义分表策略的支持
  • 支持表达式方式编写,减小写Sql语句机械性工做
  • 可对Dapper 进行扩展
  • 性能依赖于Dapper 自己的性能,Dapper 自己是轻量级ORM ,官方测试性能都强于其余的ORM

2.5 分布式跟踪系统

随着微服务架构的流行,一些微服务架构下的问题也会愈来愈突出,好比一个请求会涉及多个服务,而服务自己可能也会依赖其余服务,整个请求路径就构成了一个网状的调用链,而在整个调用链中一旦某个节点发生异常,整个调用链的稳定性就会受到影响,因此会深深的感觉到 “银弹” 这个词是不存在的,每种架构都有其优缺点 。

对以上状况, 咱们就须要一些能够帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,可以快速定位和解决问题,这时候 APM(应用性能管理)工具就该闪亮登场了。
目前主要的一些 APM 工具备: Cat、Zipkin、Pinpoint、SkyWalking,这里主要介绍 SkyWalking ,它是一款优秀的国产 APM 工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

2.6 系统日志集成

庞大的系统中离不开日志系统,排查问题,记录相关敏感信息等都须要一个日志系统,这里选择使用ExceptionLess 日志系统,日志写入到ES中,并支持可视化UI进行日志管理,查询,日常遇到问题,直接经过日志管理后台进行排查。

2.7 消息队列

消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。使用较多的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。

2.8 任务调度

这里主要使用的是Quartz.Net 进行做业任务调度,任务调用有什么用处呢?,好比咱们须要统计一个数据,可是实时统计须要一大堆的连表查询,而且比较损耗数据库的性能,所以能够选择使用任务调度的方案进行数据统计做业,半夜某个时间点去统计前一天的数据。

2.9 NoSql

Nosql 主要是非关系型数据库,好比MongDB、 Redis、Memcache等,能够用来在API网关和数据库层面作一层数据缓存,访问一些不是常常更新的数据,把它缓存起来,每次网络请求过来就能够先经过从分布式缓存中进行数据读取,减小对数据库的查询压力,提升系统的吞吐量。

2.10 可视化数据管理及分析(Kibana)

Kibana 是为 Elasticsearch设计的开源分析和可视化平台。你可使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互。你能够很容易实现高级的数据分析和可视化,以图标的形式展示出来。
Kibana 的使用场景,应该集中在两方面:

实时监控
经过 histogram 面板,配合不一样条件的多个 queries 能够对一个事件走不少个维度组合出不一样的时间序列走势。时间序列数据是最多见的监控报警了。
问题分析

关于 elk 的用途,能够参照其对应的商业产品 splunk 的场景:使用 Splunk 的意义在于使信息收集和处理智能化。而其操做智能化表如今:
搜索,经过下钻数据排查问题,经过分析根本缘由来解决问题;
实时可见性,能够将对系统的检测和警报结合在一块儿,便于跟踪 SLA 和性能问题;
历史分析,能够从中找出趋势和历史模式,行为基线和阈值,生成一致性报告。

2.11 Prometheus

Prometheus是一套开源的系统监控报警框架。Prometheus做为新一代的云原生监控系统,相比传统监控监控系统(Nagios或者Zabbix)拥有以下优势。

优点
  • 易于管理
  • 轻易获取服务内部状态
  • 高效灵活的查询语句
  • 支持本地和远程存储
  • 采用http协议,默认pull模式拉取数据,也能够经过中间网关push数据
  • 支持自动发现
  • 可扩展
  • 易集成

好了到了这里,大多已经介绍完了,其余几个你们都是比较常见常使用的技术,就不一一介绍了。

2.12 .Net Core 虚拟化

.Net Core 新一代的.Net Core 跨平台开发框架,能够脱离windows 环境,搭建在linux等平台上,那怎样搭建呢?固然可使用当前比较流行的Docker容器,把.net core 项目虚拟化 搭建在Docker 容器中运行,不依赖于任何平台和环境,只须要经过命令制做好镜像便可,同时也能够借助K8s来进行多容器应用部署、编排、更新等。

什么是k8s呢?

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单而且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

Kubernetes一个核心的特色就是可以自主的管理容器来保证云平台中的容器按照用户的指望状态运行着(好比用户想让apache一直运行,用户不须要关心怎么去作,Kubernetes会自动去监控,而后去重启,新建,总之,让apache一直提供服务),管理员能够加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提高工具以及人性化方面,让用户可以方便的部署本身的应用(就像canary deployments)。

如今Kubernetes着重于不间断的服务状态(好比web服务器或者缓存服务器)和原生云平台应用(Nosql),在不久的未来会支持各类生产云平台中的各类服务,例如,分批,工做流,以及传统数据库。

在Kubenetes中,全部的容器均在Pod中运行,一个Pod能够承载一个或者多个相关的容器,在后边的案例中,同一个Pod中的容器会部署在同一个物理机器上而且可以共享资源。一个Pod也能够包含O个或者多个磁盘卷组(volumes),这些卷组将会以目录的形式提供给一个容器,或者被全部Pod中的容器共享,对于用户建立的每一个Pod,系统会自动选择那个健康而且有足够容量的机器,而后建立相似容器的容器,当容器建立失败的时候,容器会被node agent自动的重启,这个node agent叫kubelet,可是,若是是Pod失败或者机器,它不会自动的转移而且启动,除非用户定义了 replication controller。

用户能够本身建立并管理Pod,Kubernetes将这些操做简化为两个操做:基于相同的Pod配置文件部署多个Pod复制品;建立可替代的Pod当一个Pod挂了或者机器挂了的时候。而Kubernetes API中负责来从新启动,迁移等行为的部分叫作“replication controller”,它根据一个模板生成了一个Pod,而后系统就根据用户的需求建立了许多冗余,这些冗余的Pod组成了一个整个应用,或者服务,或者服务中的一层。一旦一个Pod被建立,系统就会不停的监控Pod的健康状况以及Pod所在主机的健康状况,若是这个Pod由于软件缘由挂掉了或者所在的机器挂掉了,replication controller 会自动在一个健康的机器上建立一个一摸同样的Pod,来维持原来的Pod冗余状态不变,一个应用的多个Pod能够共享一个机器。

咱们常常须要选中一组Pod,例如,咱们要限制一组Pod的某些操做,或者查询某组Pod的状态,做为Kubernetes的基本机制,用户能够给Kubernetes Api中的任何对象贴上一组 key:value的标签,而后,咱们就能够经过标签来选择一组相关的Kubernetes Api 对象,而后去执行一些特定的操做,每一个资源额外拥有一组(不少) keys 和 values,而后外部的工具可使用这些keys和vlues值进行对象的检索,这些Map叫作annotations(注释)。

Kubernetes支持一种特殊的网络模型,Kubernetes建立了一个地址空间,而且不动态的分配端口,它能够容许用户选择任何想使用的端口,为了实现这个功能,它为每一个Pod分配IP地址。

现代互联网应用通常都会包含多层服务构成,好比web前台空间与用来存储键值对的内存服务器以及对应的存储服务,为了更好的服务于这样的架构,Kubernetes提供了服务的抽象,并提供了固定的IP地址和DNS名称,而这些与一系列Pod进行动态关联,这些都经过以前提到的标签进行关联,因此咱们能够关联任何咱们想关联的Pod,当一个Pod中的容器访问这个地址的时候,这个请求会被转发到本地代理(kube proxy),每台机器上均有一个本地代理,而后被转发到相应的后端容器。Kubernetes经过一种轮训机制选择相应的后端容器,这些动态的Pod被替换的时候,Kube proxy时刻追踪着,因此,服务的 IP地址(dns名称),历来不变。

全部Kubernetes中的资源,好比Pod,都经过一个叫URI的东西来区分,这个URI有一个UID,URI的重要组成部分是:对象的类型(好比pod),对象的名字,对象的命名空间,对于特殊的对象类型,在同一个命名空间内,全部的名字都是不一样的,在对象只提供名称,不提供命名空间的状况下,这种状况是假定是默认的命名空间。UID是时间和空间上的惟一。

2.13 自动化集成部署

为何须要自动化集成部署?

我从如下几点来分析为何须要自动化集成部署:

  • 你要相信的是全部的人工部署、发布、更新都是不可靠的,自动化智能部署能够减小事故率。
  • 人为备份、发布更新都是效率很是低的。
  • 若是某个项目须要更新,可是这个微服务有十几台负载,那你人为一台一台服务器更新发布是否是很繁琐,更加容易出事故呢?

什么是自动化集成部署?

经过jenkinsgitlabdocker等工具,以及依赖事先写好的脚本监听代码提交动态、自动化构造项目镜像、推送镜像到镜像仓库、Docker 拉起镜像、启动项目等系列自动化脚本处理,能够平滑的一台一台服务中止而且更新;一切操做无需人为的干预,甚至出现问题能够一键回滚操做。

自动化集成部署有哪些优点

  • 一切自动化,无需人为干预,提升效率,专业的人作专业的事情,开发作好开发的事情便可,运维作好运维的事情。
  • 发布可追溯
  • 随时人为干预回滚(经过脚本回顾上一步自动化备份的项目镜像)
  • 平滑发布,不影响用户体验,一台一台服务器切断,发布更新。

3、结束语

今天写的有点多了,画了一张图就停不下来了,本文分析了.net core 微服务架构中用到的系列技术使用场景和用途,没有一点实战性东西,目的是让小白有一个明确的技术方向,进一步掌握微服务架构相关的技术;也让本身对以往的经验进行梳理和总结,这样才能朝着更大的目标前进。后面我会持续给你们带来更多的干货和实战性东西,欢迎关注【dotNET博士】微信公众号

相关文章
相关标签/搜索