通过Dapr实现一个简单的基于.net的微服务电商系统

本来想在Dpar 1.0GA时发布这篇文章,由于其他事情耽搁了放到现在。时下微服务和云原生技术如何如荼,微软也不甘示弱的和阿里一起适时推出了Dapr(https://dapr.io/),园子里关于dapr的文章不太多,所以今天就借这篇文章分享一下如何通过dapr跑起来一个简易的电商系统,让大家通过这个系统来观察dapr如何运作的,权当抛砖引玉。

 

首先第一个话题,什么是dapr?

要说dapr,首先我们得了解什么是服务网格,而要说服务网格还是得先讲讲微服务。微服务的概念相信现在大家已经耳熟能详了。在微服务体系中,开发者通过拆分设计不同的服务,通过服务间协同作业的方式聚合业务实现相关的功能。

服务与服务之间涉及服务调用、事件传播、状态流转等等概念,再细分相关功能会涉及到服务调用时限流、重试、降级,事件传播时确保一致性,对整个服务系统的拓扑追踪、监控等等功能。以java为例,一般是采用dubbo或者springcloud这样的侵入性框架,通过开发人员手动集成到项目里。并在外部搭建诸如zookeeper、eureka这样的分布式协调器来实现服务的注册、发现。通过网关如zuul、kong实现对外部对内部服务的调用,通过feign ribbon hystrix这样或那样的组件实现服务间通讯时负载均衡、熔断、限流、降级。通过设计eventbus来实现事件在服务间流转。

说了这么一大堆,和服务网格有什么关系呢?服务网格本质上就是微服务架构在云原生基础上对网络通讯相关的功能做了解耦和下沉。让运行于云原生之上的应用(一般呈现方式主要是容器)可以不再关心服务间通讯相关的一大堆技术实现。通过对每一个应用附加一个独立进程的代理(也叫sidecar)实现。

 

这样开发人员只关心应用如何实现具体的业务,而不用去关心具体的服务间治理,服务网格帮应用完成服务注册、发现、负载均衡、重试、限流等等相关功能。

所以dapr是什么就一目了然了,dapr就是服务网格的一种实现方式。只不过相比传统的服务网格关注的可能是流量治理来讲dapr更关注服务间状态变化,用官方的原话来讲“Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。”

 

什么是事件驱动?

什么是事件驱动?我们知道在一个分布式系统里,当某个服务需要其他服务协同作业时,有两种办法,一种就是通过强一致性的方式调用,比如RPC call或者restapi。这种方式有一个弊端,就是必须确保下游服务必须可用,否则可能会导致同步调用时调用过程超时、或者下游服务不响应导致的失败。

在分布式系统里由于网络IO不可靠等等因素,我们往往很难100%确保同步调用能够将一个业务在多个服务间协同完成,所以一般会采用订阅-发布的方式。也就是大家比较熟悉的事件总线这样的异步模型,通过将我们的请求以发布事件的方式灌入消息队列后不等待立即返回,通过订阅方订阅消息完成后续操作,若需要回滚同样发布事件,由发送方订阅失败消息进行补偿操作即可。

通过这样的方式我们可以构建一个以事件来驱动的异步的,最终一致性的响应式系统。而dapr则是将事件驱动在云原生层面发扬光大,通过对不同中间件的集成屏蔽了构建事件驱动架构的各种复杂性,让开发人员几乎不写或者少写代码的情况下完成一个事件驱动架构的分布式系统。

 

Dapr如何助力微服务设计落地的?

Dapr提供了哪些功能来助力我们微服务落地呢?可以从上图看到有7,8种功能,我们从左至右一个一个来讲。

 

第一个就是服务间调用,也就是常见的同步调用。dapr在服务间调用封装了服务注册发现、ssl、自动重试、熔断、限流(需单独配置支撑)。一般当应用请求下游服务时daprd会发起一个https请求、若超时会重试数次,若下游服务下线不可用则会返回一个友好的json格式的50x供上游服务做异常冗余处理。

第二个是状态管理,提供了对于存储键/值对的状态管理,同时对大部分主流的状态存储中间件进行了支持,而无需开发者去对特定中间件做相应的sdk集成。

第三个是订阅发布,通过该api可以轻松实现一个异构的语言无关的事件总线,同时和状态管理一样,它的订阅发布中间件是可插拔的。

第四个是资源绑定,带触发器的资源绑定通过接收和发送事件到任何外部源(如数据库、队列、文件系统等)来进一步构建事件驱动架构,以实现扩展性和弹性,此特性有一点Serverless的思想。

第五个是大名鼎鼎的actor模型,很多没接触过actor的同学可能会一头雾水的问actor模型是什么呢?简单来讲就是一个分布式的并发的无锁线程同步对象。举一个简单的例子它可以解决在并发下商品超卖的问题,假设我们有一个api可以通过访问来扣商品库存,在无锁无事务的情况下,由于读写数据库时间差的问题,一定会导致商品超卖,即便是我们将商品库存放在对象上通过内存保存,如果不引入原子操作,也一样会有线程同步导致的数据不一致问题,而actor则可以在不引入任何内部或外部api/sdk的情况下实现多线程访问下数据的完全一致性。简单来讲就是每一个actor是通过对mailbox队列来阻塞消费实现多线程访问下数据一致性的,具体大家可以多了解一下这个模型。而Dapr 在其 actor 运行时提供了很多能力,包括并发,状态管理,用于 actor 激活/停用的生命周期管理,以及唤醒 actor 的计时器和提醒器。

第六个是可观测性,dapr通过一些三方组件提供了诸如链路追踪和应用监控等等相关观测手段来方便开发人员更加直观的定位网络问题等等。

第七个是安全性,默认dapr之间调用不管是同步调用还是actor调用或者订阅发布,均会通过双向https的方式加密通讯,避免明文传递消息。

最后一个是丰富的扩展组件,熟悉dapr的开发者可以自定义各种组件通过中间件的方式插入到sidecar的pipline中去实现自定义功能的扩展。

另外需要关注的是dapr对上层应用提供了两种请求模式,一种是http api一种是grpc api,通过这种语言无关的方式我们可以轻易的在不同语言之间通过dapr搭建起一个异构的分布式系统而不用关心不同语言之间的差异。

 

Dapr与其他服务网格的区别

目前市场上的服务网格框架基本都被诸如linkerd、istio这样的老牌服务网格占据。这些服务网格的关注点和dapr有一定区别。如果非要说相同或者相似点的话那就是他们的架构都是由数据平面和控制平面组成,其中数据平面主要是由集群内的各种sidecar组成,而控制平面就是调度中心。另外一个相同点就是他们都实现了对应用程序的代码无侵入性(dapr提供了简单的sdk,只是对dapr api的简易封装,不是必选项),但是从功能层面来讲,两者的关注点则完全不一样了,例如service mesh霸主istio他提供了对流量切分、流量镜像、监控、智能路由、故障注入,自动化的度量指标、日志以及追踪等等功能,可以看到它更关心流量代理这部分逻辑。而dapr在这部分目前来讲还稍弱,但是dapr提供了其他服务网格几乎没有关心的状态服务、事件、actor模型等等功能,两者可以说是互补的(dapr是可以和istio这样的服务网格集成工作的,未来可期)

 

更多了解dapr

访问https://dapr.io了解更多

 

talk is cheap, show me the code!

说了那么多概念,最终还是需要落地到具体的系统设计上,我们就从这个电商系统开始吧。

技术概要、设计规范

整个电商系统分为两个具体的repo

https://github.com/sd797994/Oxygen-Dapr 

该repo是针对Dapr通讯相关的API统一了编程模型封装实现的一个rpc框架,类似于dapr提供的.net SDK,该repo我已经将打包到了nuget,所以电商系统不需要依赖该repo的源代码,有兴趣的朋友可以copy下来,可以的话请star一下。该框架基于.net5

https://github.com/sd797994/Oxygen-Dapr.EshopSample

该repo为本次演示电商系统源代码,其结构如下:

 

Depoly主要是一些yaml和bat方便读者朋友通过k8s快速启动之用。

Public包含一些领域业务的抽象(DomainBase)和工具层(InfrastructureBase)以及RPC的接口层(Remote-IApplicationService)以及前端(WebPage-www)及后端(WebPage-Admin)页面

Services文件夹包含后端的微服务,分为账户服务、商品服务、商城公共服务以及交易服务,另外包含两个通用支撑服务:图片服务以及作业服务。

业务微服务类主要是以清洁架构分层,清洁架构是领域驱动设计的一个概念:

 

整个代码结构是以Domain为核心,外部依次是应用层、基础设施,是一个从内及外的设计。

Domain包含了整个服务所需的具体的业务聚合,Domain的核心数聚合,包含聚合根、实体以及值对象,剩余部分则是围绕聚合形成的规约、DTO、领域服务、仓储抽象等等。
应用层通过读写分离的方式来实现对领域层的操作和对查询业务的操作,另外包含事件订阅器用于接收其他应用发起的领域事件。其结构如下:

用例(UseCaseService)类型的应用服务主要作用就是聚合操作当前服务的领域,同时调用基础设施层实现持久化以及事务,同时可以发送领域事件亦或是调用远程RPC。

查询(QueryService)类型的应用服务主要是对各种客户端发起的业务指令调用基础设施层的ORM或es或者dapr的statemanager或者远程RPC进行具体的操作查询。

事件订阅器(EventHandler)类型的应用服务主要是接收事件并进行业务操作,其操作逻辑和用例类似。

基础设施层则包含了对上层的一系列支撑,包括各种通用组件、工具、ORM、持久化实体、仓储实现等等,其中用到的外部持久化设备有postgres、elasticsearch以及redis,所有的业务表存储主要依赖于postgres,elasticsearch主要是包含移动端的商品列表查询,redis则主要是对dapr以及作业系统的持久化支撑。此处不再赘述。

Host作为服务启动的入口,主要是启动通用主机注入依赖注入框架,注入Oxygen框架初始化各种配置、AOP、鉴权服务等等来启动RPC服务。不再赘述

 

部署网络拓扑图

Tips:如何部署可以参考repo的readme.md

整个系统前、后端以及各种通用服务都是以容器化的方式运行在k8s之上的。其中在最前端是k8s的ingress-controller,由于这个场景相对比较简单,不需要各种复杂的流量切分逻辑,所以我目前选型的是k8s官方推荐的nginx。当请求从客户端发起的时候,流量最先流入ingress-controller,通过已配置好的ingress规则会再次发送到各个k8s service再流入具体的pod进行作业。

其中对www.dapreshop.com的访问会直接请求到后端页面pod、对m.dapreshop.com的访问会请求到移动端页面pod,这两个页面上发起的api.dapreshop.com则会统一先流入到一个叫apigateway的pod上,该pod附加了一个dapr的sidecar,该pod只是一个包含路由重写规则的nginx,它的作用是将源地址请求重新组装为dapr可识别的api地址并调用sidecar,这样通过sidecar和内网的其他挂载了sidecar的各种子服务进行相应的互操作。

 

如何运行它?

Tips:如何运行可以参考repo的readme.md

通过kubectl查询两个命名空间看到如下情况则代码系统已经完全启动完毕。

 

这个时候访问admin.dapreshop.com会进入该页面:

 

当初始化后会自动创建一个管理员、一个用于模拟下单的用户以及相关的权限、角色。

 

 

同时会自动创建商城的基础设置、商品分类、商品,以及随机创建几个商品的折扣活动。

 

 

 

此时访问m.dapreshop.com就能看到一个包含商品的下单页面了

 

随意选择几个商品,选择结算后,后端即可创建一个订单,后台就可以模拟订单的剩余流程、注意该订单会在5分钟内被作业系统取消,库存会回滚。

 

观察

当我们在前后端做了各种操作后,登录zipkin.dapreshop.com即可观察到流量的变化

 

可以观察到相应的请求和链路细节

 

以前端下订单为例:

 

流量通过网关路由到交易服务,交易服务会调用账户服务获取一个mock account、然后会调用商品RPC查询商品基础信息,接下来调用商品Actor对象做具体的库存减扣,最后发布事件,同时交易服务的交易记录订阅器和作业订阅器会订阅该事件做后续相关操作。由于所有的请求都通过daprd这个sidecar完成,所以所有的请求和流量都能通过zipkin直观的观察到。

 

最后我们可以在daprcli中通过dapr dashborad -k 来观测dapr目前控制平面的基本情况,此部分就不赘述了,大家可以登录dapr的官网多了解

 

 

 

以上就是本次关于dapr如何落地一个电商demo的入门级的相关分享,Dapr本身包含了太多的内容由于时间关系无法一一呈现还需要读者朋友们在实际使用中去挖掘,如果喜欢的话请给repo一个star,欢迎转发fork~

相关文章:

  • Dapr能否引领云原生中间件的未来?

  • 云原生 | 阿里巴巴的Dapr实践与探索

  • Dapr 可视化指南

  • Dapr 知多少 | 分布式应用运行时

  • Dapr 正式发布 1.0

  • Dapr 交通流量控制示例

  • Dapr是如何简化微服务的开发和部署

  • 微软开源微服务运行时Dapr,赋能云原生应用开发

  • Dapr微服务应用开发系列0:概述

  • Dapr微服务应用开发系列1:环境配置

  • Dapr微服务应用开发系列2:Hello World与SDK初接触

  • Dapr微服务应用开发系列3:服务调用构件块

  • Dapr微服务应用开发系列4:状态管理构件块

  • Dapr微服务应用开发系列5:发布订阅构建块

  • Windows环境下Dapr入门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/303458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Python 自建分布式高并发 RPC 服务

RPC(Remote Procedure Call)服务,也即远程过程调用,在互联网企业技术架构中占据了举足轻重的地位,尤其在当下微服务化逐步成为大中型分布式系统架构的主流背景下,RPC 更扮演了重要角色。Google 开源了 gRPC…

poj-1980 Unit Fraction Partition **

/* * 本以为这题剪枝会很难&#xff0c;没想到1A了。。32ms * 这个题的难点是分数的处理。。不要用double。。精度难以把握。。 **/#include <cstdio>#include <cmath>using namespace std;int p, q, a, n, tot; //如题目定义&#xff0c;tot为答案//p1/q1 和 …

java对象实例_深入理解Java对象实例生成的例子!(转)

深入理解Java对象实例生成的例子!(转)[more]代码如下:class A {public int Avar;public A() {System.out.println("AAA");doSomething();}public void doSomething() {Avar 1111;System.out.println("A.doSomething()");}}public class B extends A {publ…

程序员江湖鄙视链大全,看看你处于链条的哪一级?

有人的地方就有江湖。程序员&#xff0c;是一个知识、智商、都异于常人的 群体&#xff0c;有人总结了程序员江湖等级鄙视链的方法和流程。老婆漂亮的程序员鄙视老婆不漂亮的程序员鄙视有女友的程序员鄙视单身狗程序员而在单身狗之间&#xff0c;才有了语言&#xff0c;编辑器和…

java什么是静态_什么是java静态

什么是java静态java静态包括静态变量、静态方法、静态初始化块&#xff0c;以下是静态的详解。(推荐教程&#xff1a;java教程)1. 什么是静态变量大家都知道&#xff0c;我们可以基于一个类创建多个该类的对象&#xff0c;每个对象都拥有自己的成员&#xff0c;互相独立。然而在…

如何在 .NET 程序万种死法中有效的生成 Dump (上)

一&#xff1a;背景相信很多人都知道通过 任务管理器 抓取dump&#xff0c;虽然简单粗暴&#xff0c;但无法满足程序的无数种死法&#xff0c;比如&#xff1a;内存膨胀&#xff0c;程序爆炸CPU爆高&#xff0c;程序累死应用无响应&#xff0c;用户气死意外退出&#xff0c;和人…

Google上面关于cas的文章

http://code.google.com/p/j2eewiki/wiki/CASinstallServer转载于:https://blog.51cto.com/flash51/614827

74款app源码,值得你拥有的干货

最近&#xff0c;小编一直在整理一些app的源码&#xff0c;如&#xff1a;BiliClient&#xff08;仿bilibili客户端&#xff09;、WeChat高仿微信、知乎专栏App、Compass&#xff08;MIUI指南针的社区开源版&#xff09;等。现在小编打算将这些资料免费分享给大家&#xff01;&…

监控系统简介:使用 Prometheus 与 Grafana

注&#xff1a;本文虽以 Docker 进行演示&#xff0c;但 Docker 并不是必须的&#xff0c;相关软件也可以直接安装到计算机上背景如果我们是Web应用的开发者&#xff0c;会对响应时间、接口的稳定性等比较敏感&#xff0c;在站点尚未部署到生产环境时&#xff0c;我们有充足的时…

7500 cpuz跑分 i5_核心硬盘 i5 7500性能测试_DIY攒机酷品测试-中关村在线

下面我们进入CPU测试环节。为保测试性准确可靠&#xff0c;以下测试均采用Windows 10 1周年版 64位正版系统&#xff0c;且不对操作系统进行任何优化&#xff0c;用以获取最大的系统稳定性与兼容性。Intel 酷睿i5 7500i5 7500 CPU-ZFritz Chess BenchmarkFritz Chess Benchmark…

Android Ap 开发 设计模式第七篇:生成器模式

Builder Pattern 模式解读 生活在深圳这所高速发展的城市&#xff0c;高楼大厦林立。所谓万丈高楼平地起&#xff0c;在我们感慨楼层的高耸之外&#xff0c;更要配服楼层的建造者和设计者。大楼首先得打稳地基、搭建骨架&#xff0c;再由下往上一层层盖上去。而这样的架构从程序…

MySQL 创始人:写代码比打游戏还爽,程序员应该多泡开源社区

编者按&#xff1a;根据StackOverflow的最新调查&#xff0c;MySQL仍然是全世界最流行的数据库&#xff0c;受访的开发者中有44.3%的人在使用&#xff0c;超过了第二位的SQL Server 10多个百分点。可是你知道MySQL是怎么诞生的吗&#xff1f;openocean 的一篇有关MySQL开发者Mi…

tomcat如何修改java版本_Java程序员必备——Tomcat配置技巧Top10

一、配置系统管理(Admin Web Application)大多数商业化的J2EE服务器都提供一个功能强大的管理界面&#xff0c;且大都采用易于理解的Web应用界面。Tomcat按照自己的方式&#xff0c;同样提供一个成熟的管理工具&#xff0c;并且丝毫不逊于那些商业化的竞争对手。Tomcat的Admin …

祝福!微软 46 周年生日快乐!

46 年前的今天&#xff0c;即 1975 年 4 月 4 日&#xff0c;比尔盖茨&#xff08;Bill Gates&#xff09;和保罗艾伦&#xff08;Paul Allen&#xff09;共同创立了微软公司。他们是小时候认识的朋友及高中同学&#xff0c;并对电脑编程充满激情。1975 年 1 月&#xff0c;MIT…

如何将Emacs添加到右键菜单并显示为“烤肉”

1 运行regedit 2 在HKEY_CLASSES_ROOT\*\ 下新建一个"shell"项 3 在shell项新建一个"Emacs"项&#xff0c;并将其默认值修改为"烤肉" 4 在Emacs项下再新建一个"command"项&#xff0c;并将其值修改为 E:\emacs-23.3\bin\runemacs.exe …

荐书 | 没有数学思维的程序员不是好的问题解决者

今天小木给大家推荐以下五本关于数学历史或数学思维的名家著作。读者推荐&#xff1a;01《这才是最好的数学书》[日] 笹部贞市郎55.00赠&#xff1a;《谁谋杀了希尔伯特教授》数学漫画随机一本《神笔涂绘》内容简介&#xff1a;有人曾请教笹部贞士郎&#xff0c;是如何引领近代…

java反射sethaha_Java反射深度测试

通过反射API构造对象&#xff0c;并使用反射调用方式访问对象的public/private方法和字段。package lavasoft.test;/*** 测试的业务类** author leizhimin 2010-5-6 20:16:10*/public class MyService {private String msg;public MyService() {System.out.println("log: …

监控系统简介(二):使用 App Metrics 在 ASP.NET Web API 中记录指标

回顾在《监控系统简介&#xff1a;使用 Prometheus 与 Grafana》一文中&#xff0c;我们了解了什么是监控系统&#xff0c;Prometheus 这一监控工具及它提供的数据类型、PromQL 以及 Grafana 可视化工具的基本用法。今天这一篇我们将在 ASP.NET Web API 项目中进行实战&#xf…

剧透人生!你什么时候结婚换工作甚至狗带,Facebook都知道

来源&#xff1a;大数据文摘即将换工作&#xff1f;要结婚了&#xff1f;有亲人朋友要去世了&#xff1f;你关心的这些人生重大节点&#xff0c;有人希望比你提前知道它们何时发生&#xff0c;并基于此对你精准投放广告。惊悚&#xff1f;这是Facebook在2010年以来提交的一系列…

如何在 NET 程序万种死法中有效的生成 Dump (下)

一&#xff1a;背景 上一篇我们聊到了如何通过 procdump 抓取 cpu爆高 和 内存暴涨 两种情况&#xff0c;这一篇再聊聊如何去抓程序 挂死 和 意外退出。二&#xff1a;程序挂死 1. 定义程序挂死 简单的说就是程序没有响应&#xff0c;既然没响应了&#xff0c;可能 死锁, 可能 …