Blazor+Dapr+K8s微服务之开发环境调试
1 安装Dapr开发调试环境
1.1 Dapr 完整安装模式不支持开发调试
在上一篇随笔《Blazor+Dapr+K8s微服务之服务调用》中,我们通过为每个微服务运行dapr run ….dotnet run命令,以自宿主的方式在本地开发环境成功运行了服务调用的例子。
但是,这种运行方式是不支持调试的,我们无法在程序中进行断点。这就很不实用了!
搜索一番,找到这么一篇文章:Simple approach to run and debug multiple .NET Dapr projects (w/o Docker) - DEV Community,根据文章,我们可以不依赖Docker,就可以对我们的Dapr微服务本地进行调试。
其主要原理是:通过Dapr简易安装的Daprd命令,以自宿主方式先启动每个微服务的Dapr SideCar, 指定这些SideCar 监听的每个微服务的Http端口,然后,我们就可以在VS中按照监听端口启动每个微服务,这样我们的微服务就能够和Dapr的SideCar实现通信,从而实现服务调用,状态存储的功能。
1.2 修改Dapr完整安装模式为简易模式
我们需要先卸载我们已经安装好的完整模式,命令如下:
Dapr uninstall
然后安装简易模式,命令如下:
dapr init --slim
2 通用Dapr开发调试脚本
我对文章中作者的脚本做了简化处理,实现了一个”通用Dapr 微服务开发调试文件夹”,以方便我们可以利用这个文件夹对任何Dapr微服务进行调试。该文件夹结构如下:

2.1 微服务Dapr SideCar启动脚本。
其中start-daprd.ps1为启动每个微服务SideCar的PowerShell脚本,内容如下:
# pre-requisites:
# - initialized with: dapr init --slim
# so that redis is running as container and placement service is started on demand # --------------------------------------------------------------------------------
# projects
# - appId = needs to be Dapr id commonly used to address service $configProjects = @(
@{
appId = "blazorweb"
}
@{
appId = "serviceapi1"
}
) # --------------------------------------------------------------------------------
# INIT $ErrorActionPreference = "Stop" # stop and remove previous jobs
$jobNamePattern = $configProjects | Join-String -Property appId -Separator "|" -OutputPrefix "(placement|" -OutputSuffix ")"
Get-Job | ? { $_.Name -match $jobNamePattern } | Stop-Job -PassThru | Remove-Job # --------------------------------------------------------------------------------
# MAIN $jobs = @() # start placement service/job
$DAPR_PLACEMENT_PORT = 6050
$jobName = "placement"
Start-Job -Name $jobName -ScriptBlock {
param( $port ) placement --port $port } -Argument $DAPR_PLACEMENT_PORT Write-Host "started" $jobName "in background, listening port:"$DAPR_PLACEMENT_PORT
"-" * 80
$jobs += $jobName # start jobs for app and dapr sidecar
$DAPR_HTTP_PORT = 3500
$DAPR_GRPC_PORT = 50001
$METRICS_PORT = 9091
$APP_PORT = 5000 foreach ($configProject in $configProjects) { $jobName = $configProject.appId + "-daprd"
$componentsPath = "components/"
$configFile = "config.yaml" Start-Job -Name $jobName -ScriptBlock {
param( $appId, $appPort, $DAPR_HTTP_PORT, $DAPR_GRPC_PORT, $DAPR_PLACEMENT_PORT, $METRICS_PORT, $componentsPath, $configFile) daprd --app-id $appId `
--app-port $appPort `
--placement-host-address $("localhost:" + $DAPR_PLACEMENT_PORT) `
--log-level debug `
--components-path $componentsPath `
--config $configFile `
--dapr-http-port $DAPR_HTTP_PORT `
--dapr-grpc-port $DAPR_GRPC_PORT `
--metrics-port $METRICS_PORT } -Argument $configProject.appId, $APP_PORT, $DAPR_HTTP_PORT, $DAPR_GRPC_PORT, $DAPR_PLACEMENT_PORT, $METRICS_PORT, $componentsPath, $configFile
Write-Host "started "$jobName" in background, DAPR_HTTP_PORT: "$DAPR_HTTP_PORT "DAPR_GRPC_PORT:"$DAPR_GRPC_PORT "METRICS_PORT:"$METRICS_PORT
Write-Host "expecting "$configProject.appId" to be started on listening port:"$APP_PORT
"-" * 80
$jobs += $jobName $DAPR_HTTP_PORT += 10
$DAPR_GRPC_PORT += 10
$APP_PORT += 10
$METRICS_PORT += 1
} # handle menu $running = $true while ($running) {
Write-Host "s: job status"
Write-Host "e: check all logs for errors"
Write-Host "q: stop jobs and quit"
$jobId = 0
foreach ($job in $jobs) {
Write-Host $($jobId.ToString() + ": show log of " + $job)
$jobId += 1
} $option = Read-Host "Enter option" switch ($option.ToUpper()) {
"S" {
Get-Job | ? { $_.Name -match $jobNamePattern } | Format-Table Name, State
}
"E" {
foreach ($job in $jobs) {
$errors = $null
if ($job -match "-app$") {
$errors = (Receive-Job -Name $job -Keep) -match "(error|fail)\:"
}
else {
$errors = (Receive-Job -Name $job -Keep) -match "level\=error"
}
if ($errors) {
"-" * 80
Write-Host "ERROR IN JOB:" $job -ForegroundColor Red
$errors
}
}
}
"Q" {
Get-Job | ? { $_.Name -match $jobNamePattern } | Stop-Job -PassThru | Remove-Job
$running = $false
}
default {
if ([int32]::TryParse($option , [ref]$jobId )) {
if ($jobId -ge 0 -and $jobId -lt $jobs.Count) {
Receive-Job -Name $jobs[$jobId] -Keep | code -
}
}
}
}
}
对于每个微服务,我们需要在变量configProjects中定义每个微服务的名字/ID,这里使用的是上一节服务调用中的两个微服务的名字 blazorweb和serviceapi1。其它内容不需要变动。
2.2 其它配置文件
其中components文件夹和config.yml 分别定义了SideCar启动需要的组件和配置。组件包括订阅发布组件和状态存储组件,如下:

这两个组件的内容很简单,都是连结到一个Redis服务,提供订阅发布需要的消息队列和状态存储需要的缓存。这两个组件的文件和config.yml配置文件其实我是拷贝的完整安装目录(C:\Users\XXX\.dapr)下面的文件。
3 调试服务调用
3.1 为每个微服务启动Dapr SideCar 服务
启动每个微服务的SideCar:

可以看到,我们以Job方式分别启动了三个服务,分别是,placement, blazorweb-daprd 和serviceapi1-daprd, placement 服务是Dapr用来实现Actor模式的。而blazorweb-daprd 和serviceapi1-daprd则分别是我们两个微服务的Dapr SideCar。两个SideCar分别要求我们的微服务在5000和5010端口启动。
需要说明的是,启动微服务SideCar之前,先要启动Dapr组件需要的Redis服务,我这边启动了一个简易的Windows Redis Server。

这时候,我们查看每个服务的状态都是运行状态:

3.2 启动每个微服务
我们在VS中,修改每个微服务宿主项目的launchSettings文件,分别在5000端口和5010端口启动我们的两个微服务:


3.3 调试服务调用

我们在DaprTest1.ServiceApi1项目的WeatherForecastController.cs文件中打个断点,然后点击Blazor界面中的Fetch Data菜单,可以看到程序停在了我们的断点上。

这里需要说明一个问题,我们在做服务调用的时候,在简易安装模式下,Dapr会始终调用127.0.0.1的3500端口,例如http://127.0.0.1:3500/v1.0/invoke/serviceapi1/method/WeatherForecast,并不会调用当前微服务SideCar指定的Dapr Http 端口。其实,我们如果访问http://127.0.0.1:3510/v1.0/invoke/serviceapi1/method/WeatherForecast,也是可以调用微服务的。
相关代码:iamxiaozhuang/dapr-test (github.com)
Blazor+Dapr+K8s微服务之开发环境调试的更多相关文章
- Blazor+Dapr+K8s微服务之服务调用
1.1 Dapr环境配置 1.1.1 在开发机安装Docker Desktop并启用Kubernetes 安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和 ...
- Blazor+Dapr+K8s微服务之基于WSL安装K8s集群并部署微服务
前面文章已经演示过,将我们的示例微服务程序DaprTest1部署到k8s上并运行.当时用的k8s是Docker for desktop 自带的k8s,只要在Docker for deskto ...
- Blazor+Dapr+K8s微服务之事件发布订阅
我们要实现的是:在blazorweb服务中发布一个事件,并传递事件参数,然后在serviceapi1服务中订阅该事件,接收到blazorweb服务中发布的事件和参数. 1 在blazo ...
- Blazor+Dapr+K8s微服务之状态管理
1 状态管理服务器端接口 1.1 添加Dapr.AspNetCore包 在DaprTest1.Server项目中添加Dapr.AspNetCore包,该包实现了ASP. ...
- Dapr微服务应用开发系列2:Hello World与SDK初接触
题记:上篇介绍了Dapr的环境配置,这次我们来动手尝试一下Dapr应用的开发 Hello World Dapr应用的Hello World其实和其他的Hello World一样简单: 首先用你喜欢的语 ...
- 【性能测试实战】jmeter + k8s + 微服务 + skywalking + efk,测试都在学的热门技术
原文持续更新完善:https://www.cnblogs.com/uncleyong/p/15475614.html 前言:当前的热门主流技术是哪些?测开为啥那么火?90%以上的测试对测开认识不准确 ...
- Dapr微服务应用开发系列1:环境配置
题记:上篇Dapr系列文章简要介绍了Dapr,这篇来谈一下开发和运行环境配置 本机开发环境配置 安装Docker 为了方便进行Dapr开发,最好(其实不一定必须)首先在本机(开发机器)上安装Docke ...
- Apollo-open-capacity-platform 微服务能力开发平台 (转)
来自大佬的apollo整合微服务的教程:欢迎大家点评和star,链接如下:https://gitee.com/owenwangwen/open-capacity-platform 官方demo链接:h ...
- 微服务项目开发学成在线_day02 CMS前端开发
1 Vue.js与Webpack研究 开发版的浏览器:https://www.google.cn/intl/zh-CN/chrome/dev/ 前端的开发框架:微服务项目开发学成在线_Vue.js与W ...
随机推荐
- shell运维习题训练
注:初学shell,以下为本人自己写的答案,如果有更好的,请指教! 1. 求2个数之和: 2. 计算1-100的和 3. 将一目录下所有的文件的扩展名改为bak 4.编译并执行当前目录下的所有.c文件 ...
- 打开设置windows10内置linux功能-启用linux子系统
第一步设置开发者模式 步骤:windows+s打开娜娜,输入设置,并点击. 点击更新与安全 点击开发者选项,选择开发者模型,弹出的对话框选确定之后等待安装完毕. 第二步:安装linux 点击确定后等待 ...
- 深入理解索引和AVL树、B-树、B+树的关系
目录 什么是索引 索引的分类 索引和AVL树.B-树.B+树的关系 AVL树.红黑树 B-树 B+树 SQL和NoSQL索引 什么是索引 索引时数据库的一种数据结构,数据库与索引的关系可以看作书籍和目 ...
- String、StringBuilder和StringBuffer的比较
目录 1.String特性 1.1 不可变 1.2 字符串常量池 2.StringBuilder和StringBuffer 2.1 区别 2.2 应用场景 1.String特性 1.1 不可变 它是I ...
- 浅淡fhq_Treap
浅淡 \(fhq\_Treap\) 前言 fhq_Treap \(yyds\)! \(sto\ FHQ\ orz\) 机房大佬们都打的 \(Splay\) 只有蒟蒻打的 \(fhq\) (防火墙)(范 ...
- [刘阳Java]_TortoiseSVN基础应用_第1讲
TortoiseSVN是一个免费的SVN客户端,非常好用.这里我们介绍一下TortoiseSVN基础应用. 下面的内容是转载博客园的某兄弟写的,个人觉得很不错.所以尊重转载的这篇文章,必须要给出这篇博 ...
- HTML5-CSS(二)
一. CSS 文本样式 1.font-size p { font-size: 50px;}解释:设置文本的大小. xx-small.x-small.small.medium.large.x-larg ...
- SpringMvc接受请求参数的几种情况演示
说明: 通常get请求获取的参数是在url后面,而post请求获取的是请求体当中的参数.因此两者在请求方式上会有所不同. 1.直接将接受的参数写在controller对应方法的形参当中(适用于get提 ...
- spring boot(二)整合mybatis plus+ 分页插件 + 代码生成
先创建spring boot项目,不知道怎么创建项目的 可以看我上一篇文章 用到的环境 JDK8 .maven.lombok.mysql 5.7 swagger 是为了方便接口测试 一.Spring ...
- Guava - Set集合
当我们在统计一个字符串中每个单词出现的次数时,通常的做法是分割字符串,遍历字符串,然后放到一个map里面,来进行统计,Guava中提供了类似功能的集合,Multiset String strWorld ...