通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定
如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了。我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础。最开始接触dapr的时候,会在其官方首页看到这么一句话“Dapr is a portable, serverless, event-driven runtime ” 一个可移植的,服务器的,事件驱动的运行时。可移植很容易理解,事件驱动也有所体现。那这个无服务器(serverless)呢?今天我们就讲讲dapr是如何serverless的。
目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统
二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解
三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr
四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
五、通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理
六、通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
七、通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流
八、通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪
九、通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
十、通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定
附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址
serverless还是有必要提两嘴,知道的同学可以直接略过。直接翻开CNCF对serverless的定义:“Serverless 是指构建和运行不需要服务器管理的应用程序的概念”,这个概念说起来非常的大哈,实际上根据各家云平台提供的serverless服务来看,其主要作用是将开发者的应用程序和服务器操作系统环境进行了隔离,让开发人员不再关心服务器(而不是完全不需要服务器!),只需要通过云函数的方式编写特定的业务代码即可对外提供服务。每一个函数会被编译成一个容器镜像,当外部请求过来时Serverless会激活这个函数运行我们的镜像实例,当请求量激增时,Serverless会帮我们横向扩容多个实例来抗住请求。当一段时间没有请求后,Serverless又会帮我们逐步缩容云函数实例直到实例变为0。这样当没有请求时的大部分时间里云服务商不会收取你的CPU/内存/网络的费用,仅仅收取一个磁盘费用(托管云函数镜像需要)。这里面涉及到两个问题,一个是云函数的扩容/缩容机制,一个就是云函数本身如何调用其他服务比如我要持久化数据/发送邮件/写短信/订阅?在各家云商提供的Serverless架构里,扩容缩容自然是通过k8s来实现的,而调用外部服务则被封装成了自家的云服务(比如阿里云可以调用RDS读写数据库。调用OSS读写对象,相应的自家的Serverless架构都提供了相关函数的功能)。
那Dapr如何实现Serverless的呢?但凡熟悉k8s的同学应该对自动化扩容、缩容这部分比较容易理解,其基于k8s的HPA机制运作,dapr通过对KEDA集成实现了这部分的功能,不过这不是今天我们要讲的重点。另外一个问题,云函数如何调用外部服务?这就是今天我们要讲的重点——绑定机制的实现。dapr的绑定提供了非常多的外部组件访问支持,访问这个列表可以查询具体的支持情况,随着dapr的逐步迭代我相信这个列表还会逐步增加最终将覆盖主流的大部分我们会用到的服务组件。这样最终我们将无需和某个云服务商的Serverless做技术绑定,只需要dapr即可实现Serverless!而我们的应用程序将会变得非常轻量级,几乎不需要集成特定组件sdk(比如数据库访问sdk、sms短信sdk、ios消息推送sdk等等等等)。只需要提供一个对外服务的restapi,内部完成业务操作后其余的部分交给dapr帮我们完成即可。
今天就来看看我们通过dapr是如何完成对数据库访问的,这里依然使用我们的eshop进行举例,在eshop中我们试着访问我们的用户数据库的Account表。首先我们需要创建一个bingding类型的component,比较简单只需要申明这是一个bindings.postgres的Component,包含一个链接字符串指向我们的infrastructure下的postgres这个k8s service。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: accountpostgres
namespace: dapreshop
spec:
type: bindings.postgres
version: v1
metadata:
- name: url
value: user=postgres password=Mytestpwd#123 host=postgres.infrastructure port=5432 dbname=AccountDb sslmode=disable
接着我们编写代码来实现对该component进行访问,通过查询Account获取用户信息并打印到postman中
首先我们实现一个简单的http请求用于查询我们的绑定服务:
public class HttpHelper
{
private static async Task<string> GetResultAsync(string componentName, string sql)
{
var req = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:3500/v1.0/bindings/{componentName}");
req.Content = new StringContent(JsonSerializer.Serialize(new { operation = "query", metadata = new { sql = sql } }));
var resp = await new HttpClient().SendAsync(req);
if (resp.IsSuccessStatusCode)
{
var result = await resp.Content.ReadAsStringAsync();
return result;
}
else
throw new NotSupportedException($"component无效或不支持的sql查询语句");
}
public static async Task<List<T>> GetResultAsync<T>(string componentName, string sql) where T:class
{
var str = await GetResultAsync(componentName, sql);
var obj = JsonSerializer.Deserialize<List<object>>(str);
var result = new List<T>();
foreach (JsonElement item in obj)
{
result.Add(AccountConvetor(item) as T);
}
return result;
} static Infrastructure.PersistenceObject.Account AccountConvetor(JsonElement item)
{
var t = new Infrastructure.PersistenceObject.Account();
t.Id = Guid.Empty;//由于不知名的原因uuid的键读取出来的值并不是uuid而是一个数组
t.LoginName = item[1].GetString();
t.Password = item[2].GetString();
t.NickName = item[3].GetString();
t.State = (Domain.Enums.AccountState)item[4].GetInt32();
return t;
}
}
接着在AccountQueryService中创建一个GetAccountListByDapr用于暴露该服务到外部:
[AuthenticationFilter(false)]
public async Task<ApiResult> GetAccountListByDapr()
{
var result = await HttpHelper.GetResultAsync<Infrastructure.PersistenceObject.Account>("accountpostgres", "select * from public.\"Account\"");
return ApiResult.Ok(result);
}
然后我们通过postman发起一个访问:

可以看到成功的通过httpclient调用dapr获取到了数据库里的数据。这里还有些小的问题比如我的id是一个uuid格式,通过dapr读取出来变成了一个数组,还不知道是什么原因。不过大体思路就是这样了,至少目前通过dapr可以和阿里云oss、ios消息推送、mysql、kafka、mqtt、postgresql、rabbitmq、redis等等等等我们常用的耳熟能详的服务/组件进行集成,而你唯一需要关心的只是通过访问dapr的api来发送操作/获取数据仅此而已,dapr将组件集成的复杂度从应用层面迁移后,对于开发者来讲通过dapr要实现一个serverless至少从技术层面来看已经没有多少阻碍了。好了,今天的分享就到这里~
通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定的更多相关文章
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格
多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧
之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现
之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护
dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式
在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存
很久没有更新dapr系列了.今天带来的是一个小的组件集成,通过多级缓存框架来实现对服务的缓存保护,依旧是一个简易的演示以及对其设计原理思路的讲解,欢迎大家转发留言和star 目录:一.通过Dapr实现 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署
之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载
在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...
随机推荐
- 为什么是InfluxDB | 写在《InfluxDB原理和实战》出版之际
1年前写的一篇旧文,文中的分析,以及探讨的问题和观点,至今仍有意义. 从2016年起,笔者在腾讯公司负责QQ后台的海量服务分布式组件的架构设计和研发工作,例如微服务开发框架SPP.名字路由CMLB.名 ...
- 08、元组tuple
元组(tuple) 是一个有序且不可变的容器,在里面可以存放多个不同类型的元素 元组是在最后多一个逗号,用于表示它是一个元组 tuple = (11,22,'阿斯顿','媚媚',) #后面多加一个逗号 ...
- 在用free()函数释放指针内存时为何要将其指针置空
在通过free()函数释放指针内存之后讲其指针置空,这样可以避免后面的程序对与该指针非法性的判断所造成的程序崩溃问题.释放空间,指针的值并没有改变,无法直接通过指针自身来进行判断空间是否已经被释放,将 ...
- 【Django笔记0】-Django项目创建,settings设置,运行
Django项目创建,settings设置,运行 1,项目创建 通过pip下载Django以后,在cmd中cd到想要创建项目的路径,之后输入: django-admin startproject ...
- [源码解析] 并行分布式框架 Celery 之 worker 启动 (1)
[源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 0x00 摘要 0x01 Celery的架 ...
- 了解 Vue 的 Compsition API
在这篇文章中,我将讲讲 Vue 的 Composition API 为什么比之前的 Options API 要好,以及它是如何工作的. Options API 有什么问题 首先,这里不是要大家放弃 O ...
- 【DB宝46】NoSQL数据库之CouchBase简介、集群搭建、XDCR同步及备份恢复
目录 一. CouchBase概述 1.1.简述 1.2.CouchDB和CouchBase比对 1.2.1.CouchDB和CouchBase的相同之处 1.2.2.CouchDB和CouchBas ...
- (二)Struts2配置文件
一.web.xml文件 web.xml配置文件是一种J2EE配置文件,决定servlet容器的HTTP元素需求如何进行处理.它严格来说不是一个Struts2 配置文件,但它是Struts2 运作所需要 ...
- 重磅:谷歌强势回归! google大会报名
google退出中国已经很久了,有关google回归的消息也流传了很久,今天,我们迎来了回归的开幕式. 1.中国区开发者网站 不需要梯子,赶紧取感受下吧: https://developers.goo ...
- 并发编程(ReentrantLock&&同步模式之顺序控制)
4.13 ReentrantLock 相对于 synchronized 它具备如下特点 可中断 可以设置超时时间 可以设置为公平锁 支持多个条件变量,即对与不满足条件的线程可以放到不同的集合中等待 与 ...