上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样只需要对外暴露一个轻量级的http服务器提供restapi即可作为一个云函数提供对外服务。上一篇我们同时也提到了在serverless框架下的函数还可以按需进行自动扩容缩容的,在极端情况下甚至可以将实例缩容至0,理想情况下serverless在无人访问时不占用系统除磁盘外的任何资源,当有访问时通过自动化扩容快速启动应用实例提供服务,当请求增多/减少时又相应的进行自动化扩容/缩容,当请求完全没有时再次缩容到0。那今天我们就看看我们如何通过dapr+prometheus+keda来实现一套自动化扩容缩容吧。

目录:
一、通过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之绑定

十一、通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容
附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址

二、通讯框架地址

  照例得先唠唠这个扩容缩容机制到底是如何实现的熟悉k8sHPA机制的同学请跳过,k8s的HPA(Horizontal Pod Autoscaler),我们直接搬官方文档定义吧:“Pod 水平自动扩缩(Horizontal Pod Autoscaler) 可以基于 CPU 利用率自动扩缩 ReplicationController、Deployment、ReplicaSet 和 StatefulSet 中的 Pod 数量。 除了 CPU 利用率,也可以基于其他应程序提供的自定义度量指标 来执行自动扩缩。 Pod 自动扩缩不适用于无法扩缩的对象,比如 DaemonSet。”,单靠HPA提供的CPU/MEM利用率来做自动扩缩容很难用于真实的生产环境,同时HPA只能作用于1->N,N->1的情况。而serverless需要涵盖实例从0->N,N->0的情况,所以单靠HPA是无法满足我们的诉求的。而这个时候就需要一款基于HPA扩展的k8s组件来为我们提供相应的服务。而Dapr选择微软自家的KEDA(已经开源并捐献给了CNCF基金会)。注意KEDA并不是为了覆盖HPA的功能,而是作为一个轻量化的组件集成在k8s里为hpa提供扩展服务。

  除了keda,我们还需要一些指标,因为keda需要某些指标来作为其对pod的扩容和缩容的凭据,这部分指标目前恰好可以用dapr已经集成好的prometheus来提供。之前链路追踪其实就是dapr+zipkin,而指标同样也可以通过dapr+prometheus来完成。关于指标这部分在dapr的官方文档里monitoring有详细描述,使用起来和之前我们介绍的链路追踪无太大差异,所以就不单开文章讲解了,有诉求的同学可以直接访问文档来自行搭建。

  好了,接下来我们开始搭建,不过照例还是先上流程图。注意此图仅仅是简易示例,真实的调用链会涉及更多的细节,此处不展开:

  首先我们需要将prometheus安装进来,通过Dapr提供的指南,我们可以使用helm进行安装。

kubectl create namespace dapr-monitoring
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install dapr-prom prometheus-community/prometheus -n dapr-monitoring

  tips:由于一个诡异的bug导致在windows平台下的docker环境内无法启动node-exporter,如果你不幸遇到了,可以使用这行代码解决,具体的issuse在这里

kubectl patch ds dapr-prom-prometheus-node-exporter  --type "json" -p '[{"op": "remove", "path" : "/spec/template/spec/containers/0/volumeMounts/2/mountPropagation"}]' -n dapr-monitoring

  检查你的dapr-monitoring,确保所有pod都能启动,接着我们需要公开prometheus-server用于访问页面。通过kubectl edit svc dapr-prom-prometheus-server -n dapr-monitoring 打开svc将spec.service.type从ClusterIP改为NodePort,如果你需要固定端口,再增加spec.ports.nodePort即可。保存文档后我们再查询kubectl get svc dapr-prom-prometheus-server -n dapr-monitoring 看看端口号是多少,然后访问loalhost:port,如果出现以下页面,则说明prometheus部署成功:

  由于dapr会自动将指标写入prometheus,当我们操作一下我们的电商demo之后,我们就可以从prometheus查询到对应指标的情况了,以http请求数的情况为例:

  prometheus先放一边,接着我们安装KEDA,依然参考dapr的文档,不过接下来我们和官方文档有一点出入,官方文档演示的是通过component让keda监听kafka,通过流量指标来确定扩容/缩容订阅器的。我们这里的演示是让keda监听prometheus的特定指标dapr_http_server_request_count来实现扩容/缩的。原理都一样,即借助keda来实现。接下来依然是通过helm安装keda。

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
kubectl create namespace keda
helm install keda kedacore/keda --namespace keda

  同样安装完毕后,观察我们的keda,确保两个pod都已经正确running之后,我们尝试对我们的网关配置keda的ScaledObject来实现自动扩容/缩容:首先还是编写一个ScaledObject,这是keda安装后会自动在k8s里申明的CRD资源符

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: dapreshop
spec:
scaleTargetRef:
name: apigateway
pollingInterval: 15 #指定keda的采集频次,单位秒
minReplicaCount: 1 #指定默认规格
maxReplicaCount: 10 #最大扩容规格
triggers:
- type: prometheus
metadata:
serverAddress: http://dapr-prom-prometheus-server.dapr-monitoring.svc.cluster.local  #prometheus服务的svc用于keda采集指标
metricName: dapr_http_server_request_count #具体的指标名
query: sum(rate(dapr_http_server_request_count{app_id="apigateway"}[2m])) #这是prometheus特有的PromQL,这段query的意思是我们需要采集以2分钟为一个维度对网关的请求平均访问速率,这里不展开,大家可以搜PromQL中文文档了解更多
threshold: '3' #阈值

  当我们apply这个yaml之后,可以通过kubectl get so,hpa观察我们的scaleobject和hpa的资源是否创建成功,一切OK后,我们通过postman的runner请求网关,看看hpa是否可以工作吧:

  可以看到请求过来后,我们的指标已经被正确的收集到了,接着我们查询一下网关的情况,可以看到已经被正确的扩容了:

  当请求归零后,过一段时间再次访问会发现实例被缩容到了默认规格。这就是今天对dapr+keda实现动态扩容/缩容的介绍。当然要做到真正的云函数那样的从0实例快速冷启动还需要一个过程,冷启动在传统云商提供的云函数环境里是通过预热池实现的,而本地化搭建要实现0实例冷启动需要AOT的支持,至少就目前而言.netcore尚未支持AOT编译成本地代码的情况下还很遥远。但是不能说没有实现serverless冷启动做这个就没有意义,当我们在特定场景比如做活动需要动态扩容/缩容时,完全可以通过keda去实现。当请求稀少的夜间我们完全就可以将实例缩容到1份继续运行,或者类似于dapr官方文档示例那样的订阅器平时不需要运行时完全可以缩容到0个实例,等待消息来触发扩容运行消费。

通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧

    之前有很多同学提到如何做容器调试,特别是k8s环境下的容器调试,今天就讲讲我是如何调试的.大家都知道在vs自带的创建项目模板里勾选docker即可通过F5启动docker容器调试.但是对于启动在k8s ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

    之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护

    dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

    在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存

    很久没有更新dapr系列了.今天带来的是一个小的组件集成,通过多级缓存框架来实现对服务的缓存保护,依旧是一个简易的演示以及对其设计原理思路的讲解,欢迎大家转发留言和star 目录:一.通过Dapr实现 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(二十)——Saga框架实现思路分享

    今天这篇博文的主要目的是分享一下我设计Saga的实现思路来抛砖引玉,其实Saga本身非常的类似于一个简单的工作流体系,相比工作流不一样的部分在于它没有工作流的复杂逻辑处理机制(比如会签),没有条件分支 ...

随机推荐

  1. python-自定义一个序列

    python的序列可以包含多个元素,开发者只要实现符合序列要求的特殊方法,就可以实现自己的序列 序列最重要的特征就是可以包含多个元素,序列有关的特使方法: __len__(self):该方法的返回值决 ...

  2. python-for表达式

    for表达式用于其他区间,元组,列表等可迭代对象创建新的列表 [表达式 for 循环计数器 in 可迭代对象] for表达式与普通for循环的区别有两点 在for关键字之前定义一个表达式,该表达式通常 ...

  3. Java并发编程之并发关键字

    volatile 保证可见性 一个线程修改volatile变量的值时,该变量的新值会立即刷新到主内存中,这个新值对其他线程来说是立即可见的 一个线程读取volatile变量的值时,该变量在本地内存中缓 ...

  4. 五个问题,三大策略,手把手教你定制App性能监控方案

    作者:友盟+U-APM团队 Why? 为什么要做应用性能监控? 首先,我们要知道应用性能监控具体指什么?以及目的: 监控是一套完整的"监视+报警"的系统.对于像我们这样的App开发 ...

  5. P1012 拼数(JAVA语言)

    //早起刷题傻一天 题目描述 设有nn个正整数(n≤20)(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3n=3时,33个整数1313,312312,343343联接成的最大整数 ...

  6. java例题_28 冒泡排序

    1 /*28 [程序 28 排序算法] 2 题目:对 10 个数进行排序 3 程序分析:可以利用选择法,即从后 9 个比较过程中,选择一个最小的与第一个元素交换, 下次类推, 4 即用第二个元素与后 ...

  7. .net 预处理指令符的使用

    目录 什么是预处理指令符? 预处理指令符的使用 自定义指令符 使用Visual Studio快速定义指令符 定义指令符区域 什么是预处理指令符? 当C#编译器找到一条预处理指令#if,最后找到一条指令 ...

  8. PYTHON工业互联网应用实战12—客户端操作

    本章节我们将实现与admin里类似的列操作"下达"功能,演示客户端是如何实现操作功能,同时,演示也会强调一点,何时合并你的功能代码,避免相同功能使用不同的代码段来实现,在企业开发中 ...

  9. C++实现控制台学生学籍管理系统

    操作流程 创建文件 创建管理类 ​ 管理类负责的内容如下: 提供与用户的沟通菜单界面 实现对职工增删改查的操作 数组数据与文件的读写交互 菜单功能实现 在StudentManager.h中定义Show ...

  10. Java 使用 Maven BOM 统一管理版本号

    一个中大型的 Java 项目往往包含若干 JAR 包,这些 JAR 包有着不同的版本号.如果这些 JAR 包单独发布,然后直接通过版本号引用相应的 JAR 包,不同版本的兼容性维护将变得十分麻烦.为了 ...