通过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 ...
随机推荐
- Matplotlib图例中文乱码
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签 plt.rcParams['axes.unicode_minus']=False #用来正 ...
- golang 实现两数组对应元素相除
func ArrayDivision(arr1 []float64,arr2 []float64) (arr3 []float64) { //两数组对应元素相除 for p:=0;p< len( ...
- 关于github的使用学习心得
先写先介绍一下如何用github上创建一个项目吧. 用户登录后的界面如上所示.右下角是我们已经建好的库.点击其中任何一个就可以查看相应的库了.如果要新建一个项目的话,就点击Start a projec ...
- 为 .NET 打 Call,为国产平台 Gitee 打 Call,我的 .NET/C# 开源项目清单,同步维护于 Github 和 Gitee
所有项目遵循 MIT 开源协议.可以随意使用,但是需在源代码和产品关于画面保留版权声明和我的网站链接,谢谢. Sheng.Winform.IDE Github:https://github.com/i ...
- 全网最详细的Linux命令系列-ls命令
Linux开始必须要会的命令当属ls,在日常工作中用到ls命令时的频率是很多的,作为一个初学者,可能我只会或者顶多ls -l两种用法.但是ls其实是一个非常实用的指令,ls命令就是list的缩写,ls ...
- js 日期加减
加: console.log(moment().format("YYYY-MM-DD HH:mm:ss")); //当前时间 console.log(moment().add(10 ...
- 《进击吧!Blazor!》系列入门教程 第一章 8.部署
<进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...
- windows认证解读
0x00 本地认证 本地认证基础知识 在本地登录Windows的情况下,操作系统会使用用户输入的密码作为凭证去与系统中的密码进行验证,但是操作系统中的密码存储在哪里呢? %SystemRoot%\sy ...
- [Fundamental of Power Electronics]-PART I-4.开关实现-4.1 开关应用
4.1 开关应用 4.1.1 单象限开关 理想的SPST(Single pole single throw)开关如图4.1所示.开关包含电源端子1和0,其电流和电压极性如图所示.在接通状态下,电压\( ...
- SQL语句通过身份证号计算年龄
SQL语句通过身份证号计算年龄 1.截取身份证号上的出生日期 身份证一般为18位数和15位数 18位数身份证的第7-10位数是出生年份,第11-14位数是出生月日,所以18位身份证的年龄计算如下 su ...