在非容器(集群)环境下运行dapr

作者:李俱顺

原文:https://www.4async.com/2021/03/2021-03-11-running-dapr-without-container/

前一段时间一直关注的dapr正式发布了v1.0版本(实际上本文发布时还更新了v1.0.1),代表dapr在某些程度上进入稳定状态,可以尝试在实际中进行运用。作为我一直关注的项目,在第一时间中进行了尝试,并试图引入实际项目中,本文则是针对这些的一些先期测试内容.

什么是dapr?

dapr最早是由微软开源的(不愧是你),一个可移植的、事件驱动的程序运行时,它使任何开发者都能轻松地构建运行在云和边缘的弹性、无状态/有状态的应用程序,并且可以灵活支持多种开发语言。换而言之,在我看来,dapr可以作为一个serverless落地方案看待和处理,对程序而言,只关注提供的store和消息队列接口,无需关心架构层面更多内容。

不过在官方的示例教程中,使用的环境为容器环境部署和管理dapr。实际上,除了在容器环境或者容器集群环境下,dapr可以配置为在本地机器上以自托管模式运行。

本地安装

dapr安装可以通过官方的dapr-cli实现,dapr-cli可以通过一键安装命令快速安装:

# wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
Your system is linux_amd64Dapr CLI is detected:
main: line 86: 43656 Segmentation fault      $DAPR_CLI_FILE --version
Reinstalling Dapr CLI - /usr/local/bin/dapr...Getting the latest Dapr CLI...
Installing v1.0.0 Dapr CLI...
Downloading https://github.com/dapr/cli/releases/download/v1.0.0/dapr_linux_amd64.tar.gz ...
dapr installed into /usr/local/bin successfully.
CLI version: 1.0.0
Runtime version: n/aTo get started with Dapr, please visit https://docs.dapr.io/getting-started/

可以通过输入dapr命令确认dapr-cli程序是否被正常安装成功。

接下来使用dapr-cli安装所有的runtime等应用。

# dapr init --slim
⌛  Making the jump to hyperspace...
↘  Downloading binaries and setting up components...
Dapr runtime installed to /root/.dapr/bin, you may run the following to add it to your path if you want to run daprd directly:export PATH=$PATH:/root/.dapr/bin
✅  Downloaded binaries and completed components set up.
ℹ️  daprd binary has been installed to /root/.dapr/bin.
ℹ️  placement binary has been installed to /root/.dapr/bin.
✅  Success! Dapr is up and running. To get started, go here: https://aka.ms/dapr-getting-started# dapr --version
CLI version: 1.0.0
Runtime version: 1.0.1

在官方文档中,如果选择使用init命令初始化,dapr-cli将会自动尝试使用容器环境管理相关程序,只有添加--slim参数才会选择本地化运行。更多用法可以参考dapr help init帮助。默认程序相关内容会安装在$HOME/.dapr目录下,这里因为我为了简便使用了root用户,因此程序命令所在目录为/root/.dapr/bin,共安装了如下命令:

# ls ~/.dapr/bin
daprd  dashboard  placement  web

从文件名可以看出来daprd是deamon进程,dashboard就是管理面板,placement是用于管理actor分布方案和密钥范围的工具。官方文档中提到在安装后会使用Reids作为默认的存储和pub/sub组件,但是我实际安装下来其实是并没没有的,不知道是不是文档有些过期导致的。这时如果按照官方文档的例子进行操作启动程序并尝试在存储中保存数据,则会出现报错的情况:

// 第一个session中执行:
# dapr run --app-id myapp --dapr-http-port 3500// 第二个session中执行:
# curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne"}]' http://localhost:3500/v1.0/state/statestore{"errorCode":"ERR_STATE_STORES_NOT_CONFIGURED","message":"state store is not configured"}

不过实际上添加组件在dapr中也是比较简单的,可以通过在$HOME/.dapr/components下添加对应yaml文件实现。

添加Redis作为组件

我们可以在官方文档中找到一个Redis组件配置模版,可以快速使用:

# redis-store.yml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: redis-storenamespace: default
spec:type: state.redisversion: v1metadata:- name: redisHostvalue: 127.0.0.1:6379- name: redisPasswordvalue: ""

当然我们也可以使用Redis Stream功能做pub/sub功能,虽然这个功能已经GA,但是介于Redis Stream的特点,你需要谨慎使用这个功能,这里只是因为是演示所以无所谓:

# redis-pubsub.yml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: redis-pubsubnamespace: default
spec:type: pubsub.redisversion: v1metadata:- name: redisHostvalue: 127.0.0.1:6379- name: redisPasswordvalue: ""- name: consumerIDvalue: "myGroup"

这里我们定义了一个store名叫做redis-store,所以我们要把上面的命令修改一下:

# curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne"}]' http://localhost:3500/v1.0/state/redis-store// 获取存储内容
# curl http://localhost:3500/v1.0/state/redis-store/name
"Bruce Wayne"

同时也可以通过redis-cli获取Redis中存储的内容:

# redis-cli
127.0.0.1:6379> keys *
1) "myapp||name"
127.0.0.1:6379> hgetall "myapp||name"
1) "data"
2) "\"Bruce Wayne\""
3) "version"
4) "1"

我们在添加Redis作为存储时还额外添加了Redis支持发布/订阅功能,这个功能如何实现呢?这里可能就需要编写额外程序实现了。我们这里采用官方的例子进行。订阅在dapr中有两种形式,一种是采用yaml声明组件形式,另外一种则可以通过编写代码形式实现。当然第一种方式和第二种方式互有优劣,前者更适合无缝集成,后者方便开发控制。这里为了演示直观性直接采用了编写代码方式实现。

package mainimport ("io""log""net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/dapr/subscribe", func(ctx *gin.Context) {ctx.JSON(http.StatusOK, []map[string]string{{"pubsubname": "redis-pubsub","topic":      "deathStarStatus","route":      "dsstatus",},})})r.POST("/dsstatus", func(c *gin.Context) {b, _ := io.ReadAll(c.Request.Body)defer c.Request.Body.Close()log.Println(string(b))c.JSON(http.StatusOK, map[string]interface{}{"success": true})})r.Run("127.0.0.1:5000")
}

使用如下命令启动编译后的daprdemo,注意指定文件名时需要填写路径或者在$PATH中:

# dapr --app-id subapp --app-port 5000 run ~/daprdemo

在程序启动日志中我们可以看到dapr会尝试访问一些默认的endpoint读取可能的配置:

INFO[0000] application discovered on port 5000           app_id=subapp instance=127.0.0.1 scope=dapr.runtime type=log ver=1.0.1
== APP == [GIN] 2021/03/11 - 10:45:02 | 404 |         949ns |       127.0.0.1 | GET      "/dapr/config"INFO[0000] application configuration loaded              app_id=subapp instance=127.0.0.1 scope=dapr.runtime type=log ver=1.0.1
INFO[0000] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s  app_id=subapp instance=127.0.0.1 scope=dapr.runtime.actor type=log ver=1.0.1
== APP == [GIN] 2021/03/11 - 10:45:02 | 200 |     540.891µs |       127.0.0.1 | GET      "/dapr/subscribe"INFO[0000] app is subscribed to the following topics: [deathStarStatus] through pubsub=redis-pubsub  app_id=subapp instance=127.0.0.1 scope=dapr.runtime type=log ver=1.0.1
WARN[0000] redis streams: BUSYGROUP Consumer Group name already exists  app_id=subapp instance=127.0.0.1 scope=dapr.contrib type=log ver=1.0.1
INFO[0000] dapr initialized. Status: Running. Init Elapsed 49.674504ms  app_id=subapp instance=127.0.0.1 scope=dapr.runtime type=log ver=1.0.1

接下来我们尝试使用dapr-cli对我们之前启动的myapp发送消息:

dapr publish --publish-app-id myapp --pubsub redis-pubsub --topic deathStarStatus --data '{"status": "completed"}'

在程序日志中获取到的输出为:

== APP == [GIN] 2021/03/11 - 10:45:05 | 200 |      122.15µs |       127.0.0.1 | POST     "/dsstatus"== APP == 2021/03/11 10:45:05 {"id":"9c237504-7cab-4a13-8582-92d9130fd016","source":"myapp","pubsubname":"redis-pubsub","traceid":"00-fba669a086f84650e882e3cadc55082c-ea466c080e359e68-00","data":{"status":"completed"},"specversion":"1.0","datacontenttype":"application/json","type":"com.dapr.event.sent","topic":"deathStarStatus"}

当然,除了pub/sub方式,我们也可以借助dapr提供的路由功能,直接进行服务调用:

# curl http://127.0.0.1:3500/v1.0/invoke/subapp/method/dsstatus -X POST
{"success":true}

其他的组件功能则可以参考官方文档中描述进行配置即可。

总结

dapr是一个功能强大的serverless运行时,除了上面提到的面向消息和请求存储的功能以外,还可以控制程序的HTTP请求与gRPC请求等等。除了这些功能外,还包含了服务的管理,还有可观测性支持等功能,是一个非常有潜力的运行时选择。

相关文章:

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

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

  • Dapr | 云原生的抽象与实现

  • Dapr 可视化指南

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

  • Dapr 正式发布 1.0

  • Dapr 交通流量控制示例

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

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

  • YARP实现Dapr服务调用的反向代理

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

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

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

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

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

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

  • Windows环境下Dapr入门

  • 云原生 | .NET 5 with Dapr 初体验

  • 通过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之OAuth2授权-百度版

  • 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

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

  • WebAssembly + Dapr = 下一代云原生运行时?

  • dapr 应用开发 | 环境配置

  • 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时

  • Dapr案例之高德 Serverless 平台建设及实践

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

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

相关文章

【Silverlight5矢量打印】如何用C#代码检测打印机和驱动是否支持PostScript

Silverlight5支持PostScript矢量打印,矢量打印相比于位图打印速度更快,生成的打印文件更小。SL5默认会采用PS矢量打印,如果打印机不支持,自动切换到位图打印。 虽然微软SL打印组认为PS已经相当普遍,但我想大多数打印机…

用魔法打开科学,孩子惊叫连连,想不爱科学都难!

随着当今科技快速发展,和大家对于人工智能快速崛起的担忧,父母们对于孩子科学能力的培养,已经紧锣密鼓的提上了早教日程。看看近两年早教市场里火爆的课程,“少儿编程”、“儿童机器人教育”、“儿童STEAM课程”等等便是印证了这一…

java反射 获取局部变量_Java反射:如何获取变量的名称?

呼唤远方如果您使用以下的调试信息进行编译:javac -g),局部变量的名称保存在.class文件中。例如,以这个简单的类为例:class TestLocalVarNames {public String aMethod(int arg) {String local1 "a string";StringBuil…

svn服务端及客户端搭建和使用(三)

接下来,试试用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突等.添加文件在检出的工作副本中添加一个Readme.txt文本文件,这时候这个文本文件会显示为没有版本控制的状态,如图:这时候,你需要告知TortoiseSVN你的操作,如图:加入以后,你的文件会变成这个状态,如图:这时…

Python的小宇宙,怎么样才能发挥出来?

随着科技的发展,计算机对人类的生产活动和社会活动产生了极为重要的影响,同时以强大的生命力飞速发展着。目前计算机正广泛用于社会各个领域,并朝着微型化、网络化、智能化和巨型化的方向前进。而随着计算机飞速发展的背后,人工智…

面试腾讯,过了~

大概需要10分钟。原谅下,又标题党了,不过这篇会提到我应届面试腾讯的经历。前两天在朋友圈发了一条动态:要做读者朋友的指路小火苗,很多人在状态下留言:为啥不是指路明灯?为啥不是小油灯?原因很…

传说中理科生看到会沉默、文科生看到会流泪的【程序员文史综合题目】

全世界只有3.14 % 的人关注了数据与算法之美一、单选题1、以下谁是二进制思想的最早提出者?a,伏羲;b,姬昌;c,莱布尼茨;d,柏拉图。2、以下哪个概念和公孙龙的《指物论》中的“指”字含…

智能制造建设方案

随着新一轮工业革命的发展,工业转型的呼声日渐高涨。面对信息技术和工业技术的革新浪潮,美国人出台了先进制造业回流计划,提出了工业互联网战略,德国人提出了工业4.0战略,中国加紧推进两化深度融合,并发布了…

深入LINQ | 动态构建LINQ表达式

原文:bit.ly/3fwlKQJ作者:Jeremy Likness译者:精致码农-王亮LINQ 是 Language Integrated Query(语言集成查询)的缩写,是我最喜欢的 .NET 和 C# 技术之一。使用 LINQ,开发者可以直接在强类型代码…

java查找字符的方法_Java字符串查找(3种方法)

在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。根据字符查找String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹…

2018 Kaggle 报告:在技术领域,女性从业者持续减少,00后开始展露头脚

全世界只有3.14 % 的人关注了数据与算法之美就在上个月,Kaggle社区发布了《2018 Kaggle机器学习和数据科学调研》,调研结果显示:在技术领域,女性从业者持续减少;00后开始登上从业舞台;而且,23%受…

Nuget Package 支持打包 ReadMe 了

Nuget Package 支持打包 ReadMe 了Intro在 3月份,我们在NuGet生态系统状态上发布了一个博客,其中讨论了过去六个月以来从数百名客户那里获得的见解。客户在我们的调查中发现的最大问题之一是,“大多数软件包的文档不足”,可以从Nu…

幸运从来都只偏爱有准备的人——大龄码农的慌张日记

很多人将一件事的成功归结于能力,也有很多人将其归结为运气。今天要在这里跟大家分享的朋友名叫Leon,他在纽村政府注重本地人就业的大环境下,用时1个月以配偶工签的身份成功拿到大厂offer。接到我们的邀稿后,他花了很多心思写了这…

程序员必备表情包,速速收藏!

全世界只有3.14 % 的人关注了数据与算法之美程序猿怒产品 :程序猿不想和你说话,并… 被吐槽写BUG时怎么办 产品又来提需求 产品又要改需求,怎么办 产品说,这个功能三天后就要 日常怼产品 日常工作内心咆哮 来源:网络版…

深度解读服务治理 ServiceMesh、xDS

最近在同程艺龙蹲坑,聊一聊微服务治理的核心难点、历史演进、最新实现。☺️以上内容属自我思考,如理解有偏差、理解不透彻、现状梳理不清楚的请大家多指教。大纲微服务治理的核心难点方案演进的法宝:代理模式2.1 集中式代理2.2 客户端嵌入Sd…

struts2 kindeditor teatarea拿不到值问题。

2019独角兽企业重金招聘Python工程师标准>>> 源&#xff1a; <script type"text/javascript">var editor;KindEditor.ready(function(K) {editor K.create(textarea[name"userinfo.introduce"], {resizeType : 1,allowPreviewEmoticons …

三个字帮大家总结一下刘强东事件

全世界只有3.14 % 的人关注了数据与算法之美真干了【别和我说话】“工作战衣”的预售活动正在火热进行中&#xff0c;数量有限&#xff0c;欲购从速&#xff01;购买者还将会有机会免费获超级数学建模的第一本书&#xff08;附超模君亲笔签名&#xff0c;只限20名哦&#xff09…

【思维导图】新手该怎么学习C#/WPF

C#和WPF没有什么多大的关系&#xff0c;WPF是一个框架&#xff0c;VB都可以写WPF&#xff0c;至于如何学习C#&#xff0c;还是老样子&#xff01;基础&#xff1a;基础语法基础API基础练习所谓基础语法&#xff0c;包括if /if else &#xff0c;swicth&#xff0c;while&#x…

程序员搞笑故事:给女儿织的辫子 ​​​​,你知道是什么算法吗?

全世界只有3.14 % 的人关注了数据与算法之美1、程序员给女儿织的辫子 &#xff0c;你知道是什么算法吗&#xff1f;推荐阅读《啊哈&#xff01;算法》2、一个姑娘在我女友面前声讨她的男友&#xff0c;女友帮腔说&#xff1a;学土木工程的嘛&#xff0c;肯定又土又木。姑娘问&a…

模块XX.dll已加载,但对DllRegisterServer的调用失败

为什么80%的码农都做不了架构师&#xff1f;>>> 模块"XX.dll"已加载&#xff0c;但对DllRegisterServer的调用失败&#xff0c;错误代码为0x80004005 一句话&#xff0c;权限问题…… 转载于:https://my.oschina.net/szm/blog/76544