1.前言微服务架构大家都在说。园子里也有很多关于微服务的文章。前几天有园友问我关于微服务架构的问题。技术方面,我在这里整理了微服务架构的技术栈路线图,在这里分享给大家一起讨论学习,同时让新手对微服务相关技术有更深入的了解。2.技术栈2.1工欲善其事,必先利其器。现在互联网已经普及,互联网产品层出不穷。流行的互联网产品都有比较好的技术团队。我将在这里分享.net微服务架构。技术栈图如下:俗话说:工欲善其事,必先利其器。一个优秀的工程师应该善于使用框架和工具。微服务的技术选型不是一蹴而就的,需要日积月累的积累和实施才能完成项目。下面我将技术栈中主要框架和工具的使用场景一一分享。本文不会一一分享实际例子。2.2微服务微服务如何“微”?微服务,当然核心主题是“微”,怎么微?应该怎么微?刚来杭州的时候,接触了一个电商系统的单体架构。系统比较大,结合了各个电商企业应该有的业务逻辑和场景。很多,代码耦合度太高,改业务逻辑基本牵一发而动全身。和我上个月分享的关于IdentityServer4授权中心在Asp.NetCore中的实际应用一文中原来的电商系统架构图类似,如下:然后有一个“微”说说这个架构。在这里,我们原则上可以针对这个单体架构做如下“微”服务:按业务拆分,一个业务一个服务原则拆分,实现一个通用的业务服务模块,让业务实现高内聚低耦合.后面要随意更改任何部分业务,只需要更改这部分业务微服务即可,其他业务不受影响。一个业务模块,一个独立的数据库为原则,并行业务之间不需要相互依赖。外层API网关集成业务逻辑。一个业务数据库,一个微服务是原则。结合分布式服务,可以快速迭代版本,平滑发布,不受时间影响。随时可以放,不用等到半夜12点才放。(更痛苦的释放就像三天的排球(有点夸张)。曾经有一段时间每周都有那么多痛苦释放的夜晚。释放可能是在凌晨4或5点。我们必须经历各种测试,终于找到问题,只好在线修复bug,回去的时候其他同事已经来上班了;当时我们的技术老大说了这么一句话:“他一个星期没见了.儿子,他回去的时候儿子已经睡着了,起床上班的时候儿子已经去上学了”,这样的出版经历想必大家都有过吧。)遵循以上原则后,原电商单体架构微服务改造升级后的架构图如下:架构图大概画出来了,表达意思就够了。微服务、Docker、k8s简单总结一下,具体的图就不详细画了。微服务集群微服务已经是“微”的,所以需要一个服务发现的数据中心,这里要用到Consul。Consul主要用于注册服务、服务发现、服务健康检查。我们可以自动对某些业务服务进行扩容,增加服务器,扩展服务集群。如果某个服务出现故障,Consul会自动选择可用的服务节点进行连接和使用,从而大大增加了整个电子商务系统的稳定性。如果需要了解Consul更详细的特性和构建,可以5分钟阅读微服务架构下Consul特性和构建的文章。微服务如何保证数据的一致性?以前对于单体架构的应用,业务之间的耦合是通过事务来保证的。如何实现微服务的数据一致性?上面说了,微服务应该是业务之间没有依赖关系,每个业务都是一个独立的服务。如何保证业务与业务之间数据的一致性也是一个很大的问题,这也是业界的一个难题。微服务比较有争议的一个话题,如何保证数据的一致性?分布式系统架构中有一个CAP理论:任何分布式系统只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)两点,无法兼顾三者。对于分布式系统,分区容错是一个基本要求,否则就失去了价值。因此,唯一的选择是在可用性和一致性之间。如果选择提供一致性,则需要付出阻塞其他并发访问的代价,直到满足一致性为止。这可能会持续不确定的时间,尤其是在系统已经表现出高延迟或网络故障导致连接丢失的情况下。从目前的成功经验来看,可用性一般是更好的选择,但是维护服务和数据库之间的数据一致性是一个非常基础的需求,微服务架构选择满足最终一致性。最终一致性是指系统中的所有数据副本经过一段时间后最终可以达到一致的状态。这里所说的时间段,也是用户可以接受的时间段。从一致性的本质来看,一个业务逻辑中包含的所有服务要么成功,要么失败。那么如何选择方向才能确保成败呢?只需要根据商业模式做出选择即可。实现最终一致性有三种模式:可靠事件模式、业务补偿模式、TCC模式,这里不再展开,以后有机会再分享学习。2.3微服务开源框架我使用的开源微服务框架core-grpc开源框架源码地址:我分享了一篇关于【.netcore】电商平台升级微服务架构应用实践(core-grpc)的简单介绍微服务的概念和优缺点,这里就不分享了。具体应用也可以点击【.netcore】电商平台升级之微服务架构应用实战(core-grpc)阅读2.4ORM框架微服务中使用的ORMDapper,使用的第三方开源组件为core-数据。开源作者曾经封装过dapper。开源框架源码地址为core-data。支持多数据库,简单配置和添加链接配置多数据库支持支持表操作,支持自定义表策略支持表达式编写,减少编写Sql语句的机械工作可以扩展到Dapper性能取决于Dapper本身的性能,Dapper本身是一个轻量级的ORM,官方测试性能强于其他ORM2.5分布式跟踪系统。随着微服务架构的普及,微服务架构下的一些问题会越来越突出。例如,一个请求涉及多个服务,服务本身也可能依赖于其他服务。整个请求路径构成了一个网络调用链。一旦整个调用链中的某个节点出现异常,就会影响到整个调用链的稳定性,因此会深感“银弹”二字并不存在,每种架构都有其优缺点.针对以上几种情况,我们需要一些能够帮助理解系统行为和分析性能问题的工具,以便在出现故障时能够快速定位并解决问题。这时候APM(ApplicationPerformanceManagement)工具应该登场了。目前主要的一些APM工具有:Cat、Zipkin、Pinpoint、SkyWalking。这里主要介绍SkyWalking,这是一款优秀的国产APM工具,包括分布式跟踪、性能指标分析、应用和服务依赖分析等。2.6系统日志集成日志系统离不开一个庞大的系统。排查问题和记录相关敏感信息都需要日志系统。这里,我们选择使用ExceptionLess日志系统,将日志写入ES,支持可视化UI进行日志管理。查询,一般遇到问题,直接通过日志管理后台查看。2.7消息队列消息队列中间件是分布式系统中的一个重要组件,主要解决应用耦合、异步消息、流量切割等问题。实现高性能、高可用性、可扩展性和最终一致性的架构。使用最多的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。2.8任务调度这里主要使用Quartz.Net进行job任务调度。任务调用有什么用?,比如我们需要统计一条数据,但是实时统计需要大量的链表查询,比较数据库的性能,所以我们可以选择使用任务调度方案进行数据统计操作,以及统计前一天半夜某个时间点的数据。2.9NoSqlNosql主要是非关系型数据库,如MongDB、Redis、Memcache等,可以用来在API网关和数据库层面做一层数据缓存,访问一些不经常更新的数据,以及缓存它。可以先从分布式缓存中读取数据,以减轻数据库的查询压力,提高系统的吞吐量。2.10可视化数据管理与分析(Kibana)Kibana是一个为Elasticsearch设计的开源分析与可视化平台。您可以使用Kibana搜索、查看存储在Elasticsearch索引中的数据并与之交互。您可以轻松实现高级数据分析和可视化,并以图标的形式展示。Kibana的使用场景应该侧重于两个方面:通过直方图面板进行实时监控,不同条件的多个查询可以针对一个事件在多个维度上组合不同的时间序列趋势。时间序列数据是最常见的监控告警。问题分析关于elk的使用,可以参考其对应商业产品splunk的场景:使用Splunk的意义在于让信息采集和处理智能化。而其运营智能化表现在:通过数据下钻搜索、排查问题,通过根因分析解决问题;实时可见性,可以结合系统检测和警报以促进SLA和性能问题的跟踪;历史分析,从中可以识别趋势和历史模式、行为基线和阈值,以及生成一致性报告。2.11PrometheusPrometheus是一个开源的系统监控告警框架。Prometheus作为新一代云原生监控系统,相较于传统监控系统(Nagios或Zabbix)具有以下优势。优点易于管理,易于获取服务内部状态高效灵活的查询语句,支持本地和远程存储使用http协议,默认拉取方式拉取数据,也可以通过中间网关推送数据支持自动发现可扩展和easytointegration好了说到这里,大部分都已经介绍完了,其他的技术都比较普通,大家也常用,就不一一介绍了。2.12.NetCore虚拟化.NetCore新一代.NetCore跨平台开发框架,可以脱离windows环境,构建在linux等平台上,那么如何构建呢?当然也可以使用目前流行的Docker容器,将.netcore项目虚拟化,运行在Docker容器中。它不依赖于任何平台和环境。你只需要通过命令创建一个好的镜像,你也可以使用K8s来执行多个任务。容器应用程序部署、编排、更新等。什么是k8s?Kubernetes是一个开源软件,用于管理云平台中多个主机上的容器化应用程序。Kubernetes的目标是让部署容器化应用变得简单高效(功能强大)。Kubernetes提供了应用部署、规划、更新和维护的机制。Kubernetes的一个核心特性是可以独立管理容器,保证云平台中的容器按照用户的期望运行(比如用户希望Apache一直运行,用户不需要关心怎么做,Kubernetes会自动监控然后去Restart,新建一个,总之就是让apache一直提供服务),管理员可以加载一个微服务,让planner找一个合适的位置,在同时,Kubernetes还改进了系统工具和人性化,让用户可以轻松部署自己的应用程序(如金丝雀部署)。现在Kubernetes专注于不间断的服务状态(如web服务器或缓存服务器)和原生云平台应用(Nosql),并在不久的将来支持各种生产云平台中的各种服务,如批处理和工作流,以及传统数据库。在Kubenetes中,所有的容器都运行在Pod中,一个Pod可以承载一个或多个相关的容器。在后一种情况下,同一个Pod中的容器将部署在同一台物理机上,可以共享资源。一个Pod也可以包含O个或多个磁盘卷组(volumes)。这些卷组会以目录的形式提供给一个容器,或者被Pod中的所有容器共享。对于用户创建的每一个Pod,系统都会自动选择健康且容量充足的机器,然后创建一个类似于容器的容器。当容器创建失败时,容器会被nodeagent自动重启。这个节点代理称为kubelet。但是,如果Pod发生故障或机器发生故障,它将不会被自动转移和启动,除非用户定义了一个复制控制器。用户可以自己创建和管理Pod,Kubernetes将这些操作简化为两个操作:基于同一个Pod配置文件部署多个Pod副本;当Pod挂起或机器挂起时创建替代Pod。KubernetesAPI中负责重启、迁移等行为的部分称为“复制控制器”。它根据一个模板生成一个Pod,然后系统根据用户的需求创建大量的冗余。这些冗余的Pod形成了整个应用程序,或者说是一个服务,或者是服务中的一层。Pod创建后,系统会持续监控Pod的健康状况和Pod所在的主机。如果Pod由于软件原因或Pod所在机器挂掉,replicationcontroller会自动运行在一个健康的Pod上。在机器上创建一个相同的Pod,保持原有的Pod冗余状态,一个应用的多个Pod可以共享一台机器。我们经常需要选择一组Pod。比如我们想限制一组Pod的某些操作,或者查询一组Pod的状态。作为Kubernetes的基本机制,用户可以为KubernetesApi中的任意对象附加一组key:value标签,那么我们就可以通过标签选择一组相关的KubernetesApi对象,然后进行一些特定的操作,每个资源都有一组额外的(许多)键和值,然后外部工具可以使用这些键和vlues值检索对象。这些Map被称为注解(comments)。Kubernetes支持一种特殊的网络模型。Kubernetes创建地址空间,不动态分配端口。它允许用户选择他们想要使用的任何端口。为了实现这个功能,它为每个Pod分配了一个IP地址。现代互联网应用一般都包含多层服务,如网页前台空间、用于存储键值对的内存服务器,以及相应的存储服务。为了更好的服务于这样的架构,Kubernetes提供了服务抽象,提供了固定的IP地址和DNS名称,而这些动态的关联了一系列的Pod,通过前面提到的标签进行关联,所以我们可以关联任何我们想要的Pod想关联一下,当一个Pod中的容器访问这个地址时,请求会被转发到本地代理(kubeproxy),每台机器都有一个本地代理,然后转发到对应的后端容器。Kubernetes通过轮训机制选择相应的后端容器。当这些动态Pod被替换时,Kube代理会跟踪它们。因此,服务的IP地址(dns名称)永远不会改变。Kubernetes中的所有资源,例如Pod,都通过称为URI的东西来区分。这个URI有一个UID。URI的重要组成部分是:对象的类型(如pod)、对象的名称、对象的命名空间。对于特殊的对象类型,同一命名空间中的所有名称都是不同的。在对象只提供名称不提供命名空间的情况下,这种情况假定为默认命名空间。UID在时间和空间上是唯一的。2.13自动化集成部署为什么需要自动化集成部署?我从以下几点分析为什么需要自动化集成部署:你要相信的是,所有手动部署、发布、更新都是不可靠的,自动化智能部署可以降低事故率。人工备份和发布更新是非常低效的。如果某个项目需要更新,但是这个微服务有十几个负载,你手动更新发布每个服务器是不是很麻烦,而且更容易出现意外?什么是自动化集成部署?通过jenkins、gitlab、docker等工具,以及依靠预先写好的脚本监控代码提交动态、自动构建项目镜像、推送镜像到镜像仓库、Docker拉取镜像、启动项目等,一系列自动脚本处理可以很顺利。服务停止并更新;所有操作无需人工干预,甚至出现问题也可一键回滚。自动化集成部署有什么优势一切都是自动化的,无需人为干预,提高效率,专业的人做专业的事,开发够了就做好开发,运维做好运维。发布可随时回溯通过人工干预回滚(通过脚本查看上一步自动备份的项目镜像)在不影响用户体验的情况下顺利发布,一台一台服务器断掉,一个更新已发布。3.结语如果本文对你有帮助,别忘了给我三连,点赞、转发、评论,我们下期见!获取方式:点赞、评论、关闭~了解更多JAVA知识技能,关注并私信博主(666)
