Dapr牵手.NET学习笔记:状态管理之docker-compose发布

Dapr牵手.NET学习笔记:想入非非的服务调用

Dapr牵手.NET学习笔记:跨物理机负载均衡服务调用

Dapr牵手.NET学习笔记:用docker-compose部署服务

说明:为了给出demo的全貌,这篇有点长,如果有上一篇的基础,会更容易阅读一些。

在分布式应用,有状态服务是常态,特别是多副本应用,就需要共用缓存来解决数据统一的状况,所以dapr也把状态管理做成一个标准组件。

下面通过docker-compose来发布OrderSystem项目和PaymentSystem项目,他们分别有自己的状态数据,并且测试它们之间的访问性。

下面是项目的目录结构,components文件是dapr组件配置文件夹,B2C是docker-compose的文件夹

ea61c91621cc2c39dc6e1da309e23002.png

OrderSystem项目

HomeController.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;namespace OrderSystem.Controllers;
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{private readonly ILogger<HomeController> _logger;private readonly IHttpClientFactory _clientFactory;private readonly string? _payUrl;private readonly string _stateUrl;public HomeController(ILogger<HomeController> logger, IHttpClientFactory clientFactory, IConfiguration configuration){_stateUrl = configuration.GetSection("StateUrl").Value;_payUrl = configuration.GetSection("payurl").Value;_clientFactory = clientFactory;_logger = logger;}[HttpGet("/order")]public async Task<IActionResult> Order(){try{_logger.LogInformation($"下单开始");await Task.Delay(400);_logger.LogInformation($"订单完成   调用支付系统");var client = _clientFactory.CreateClient();var content = await client.GetStringAsync(_payUrl);return new JsonResult(new { order_result = "订单成功", pay_result = content });}catch (Exception exc){_logger.LogCritical(exc, exc.Message);return new JsonResult(new { order_result = "订单成功,支付失败", message = exc.Message });}}[HttpPost("/writekeys")]public async Task<IActionResult> WriteKeys([FromBody] KeyEntity[] keys){var client = _clientFactory.CreateClient();var jsonContent = System.Text.Json.JsonSerializer.Serialize(keys);var content = new StringContent(jsonContent);var response = await client.PostAsync(_stateUrl, content);return Ok(await response.Content.ReadAsStringAsync());}[HttpGet("/readekey/{key}")]public async Task<IActionResult> ReadKey(string key){var client = _clientFactory.CreateClient();var response = await client.GetAsync($"{_stateUrl}/{key}");return new JsonResult(new { key = await response.Content.ReadAsStringAsync(), host = Dns.GetHostName() });}[HttpPost("/readekeys")]public async Task<IActionResult> ReadKeys([FromBody] string[] keys){var client = _clientFactory.CreateClient();var jsonContent = System.Text.Json.JsonSerializer.Serialize(keys);var content = new StringContent(jsonContent);var response = await client.PostAsync($"{_stateUrl}/bulk", content);return Ok(await response.Content.ReadAsStringAsync());}[HttpDelete("/deletekey/{key}")]public async Task<IActionResult> DeleteData(string key){var client = _clientFactory.CreateClient();var response = await client.DeleteAsync($"{_stateUrl}/{key}");return Ok(await response.Content.ReadAsStringAsync());}
}
public class KeyEntity
{public string Key { get; set; }public string Value { get; set; }
}

appsettings.json

{"Urls": "http://*:80","Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"AllowedHosts": "*","PayUrl": "http://localhost:3500/v1.0/invoke/pay/method/pay","StateUrl": "http://localhost:3500/v1.0/state/statestore"
}

OrderSystem项目的Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["/OrderSystem/OrderSystem.csproj", "OrderSystem/"]
RUN dotnet restore "OrderSystem/OrderSystem.csproj"
COPY . .
WORKDIR "/src/OrderSystem"
RUN dotnet build "OrderSystem.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "OrderSystem.csproj" -c Release -o /app/publishFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "OrderSystem.dll"]

PaymentSystem项目

HomeControllers.cs与OrderSystem的状态代码是一样的,这里就不占篇幅。

PaymentSystem项目的appsettings.json

{"Urls": "http://*:80","Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"AllowedHosts": "*","StateUrl": "http://localhost:3500/v1.0/state/statestore"
}

PaymentSystem项目的Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["/PaymentSystem/PaymentSystem.csproj", "PaymentSystem/"]
RUN dotnet restore "PaymentSystem/PaymentSystem.csproj"
COPY . .
WORKDIR "/src/PaymentSystem"
RUN dotnet build "PaymentSystem.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "PaymentSystem.csproj" -c Release -o /app/publishFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PaymentSystem.dll"]

OrderSystem项目和PaymentSystem项目的Dockerfile中的路径要和docker-compose.yml中的设置有关,所以分享出来,以供参考。

B2C

docker-compose.yml,这里定义了一个b2c-dapr,作为互通网络,打通应用与redis等服务的通道。其中ordersystem对宿主机的端口还是3500,paymentsystem对宿主机的端口分别是3601,3602

version: '3.4'services:#┌────────────────────────────────┐#│ ordersystem app + Dapr sidecar │#└────────────────────────────────┘ordersystem:image: ${DOCKER_REGISTRY-}ordersystemdepends_on:- redis- placementbuild:context: ../dockerfile: /OrderSystem/Dockerfileports:- "3500:3500"volumes:   - ../OrderSystem:/OrderSystem  networks:- b2c-daprordersystem-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "order", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components"]build:context: ../depends_on:- ordersystemnetwork_mode: "service:ordersystem"volumes:   - ../components:/components  #┌───────────────────────────────────┐#│ paymentsystem1 app + Dapr sidecar │#└───────────────────────────────────┘  paymentsystem1:image: ${DOCKER_REGISTRY-}paymentsystembuild:context: ../dockerfile: /PaymentSystem/Dockerfileports:- "3601:3500"volumes:   - ../PaymentSystem:/PaymentSystem      networks:- b2c-dapr      paymentsystem1-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "pay", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]build:context: ../depends_on:- paymentsystem1network_mode: "service:paymentsystem1"volumes:   - ../components:/components #┌───────────────────────────────────┐#│ paymentsystem2 app + Dapr sidecar │#└───────────────────────────────────┘   paymentsystem2:image: ${DOCKER_REGISTRY-}paymentsystembuild:context: ../dockerfile: /PaymentSystem/Dockerfilevolumes:   - ../PaymentSystem:/PaymentSystem            ports:- "3602:3500"networks:- b2c-dapr      paymentsystem2-dapr:image: "daprio/daprd:latest"command: [ "./daprd", "-app-id", "pay", "-app-port", "80" ,"-placement-host-address", "placement:50006","-components-path","/components"]build:context: ../depends_on:- paymentsystem2network_mode: "service:paymentsystem2"volumes:   - ../components:/components       #┌────────────────────────┐#│ Dapr placement service │#└────────────────────────┘  placement:image: "daprio/dapr"command: ["./placement", "-port", "50006"]ports:- "50006:50006"networks:- b2c-dapr#┌───────────────────┐#│ Redis state store │#└───────────────────┘  redis:image: "redis:latest"ports:- "6380:6379"networks:- b2c-dapr
networks:b2c-dapr:

Dapr组件配置

statestore.yaml,其中value的值要改成redis,而不是localhost,这里要连接同一个网络里的redis服务

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: statestore
spec:type: state.redisversion: v1metadata:- name: redisHostvalue: redis:6379- name: redisPasswordvalue: ""- name: actorStateStorevalue: "true"

启动docker-compose

docker-compose up -d

449df6a2fd9868ae607133a6eba7cf93.png

启动后各服务的状态

a9e9ad383ab567bd7646f37df5abe7de.png

测试:

对order服务进行设置状态,这里调用的是dpar服务调用对外的接口,3500是order服务sidecar对外端口。

192bfdd396a9d049ad49b05690fa8111.png

同理调用order服务的状态数据,返回设置的值

d8380ebe0e7f79928d827fb3aeb9c59d.png

接下来测试从pay服务中调用order服务的状态,返回结果为空,这里的地址为:localhost:3601/v1.0/invoke/pay/method/readekey/USER00001

b8292630ae7cb5849317a385e952e72c.png

下面换成从pay1服务的3601中访问order服务的状态,结果有值,url为localhost:3601/v1.0/invoke/order/method/readekey/USER00001,根本原因可能你想到了,这本质上调的还是order服务的接口,只不过是利用pay1的sidecar调用order的sidecar实现的,因为服务调用是通着,所以能调用到,这里可以通过查看返回的host值证明。

c5377b0e17e2201bd381018c33d2a61e.png

接下来测试pay服务,两个副本,访问状态数据的case。下面是通过3601设置状态。

1c232ceaf5b8676aaa81bbd5ef63a4c7.png

通过pay1的sidecar对外端口访问,url是localhost:3601/v1.0/invoke/pay/method/readekey/PAY00001

c4104c5a3bd4bfd05ff853b4b2f3a640.png

通过pay2的sidecar对外端口访问,url是localhost:3602/v1.0/invoke/pay/method/readekey/PAY00001

c12536a031971b3bebedc4f1171005e4.png

可见状态数据很好的被隔了,如果跨服务访问状态数据,可以通过服务开放api来实现。

最后看一眼redis数据吧,清晰的展示了服务和数据的关系。

b802b3da2a42af8a85a4d5b7a62fefa0.png

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

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

相关文章

linux tomcat 启动权限不足解决办法

2019独角兽企业重金招聘Python工程师标准>>> 用命令 chmod 755 文件名 即可 转载于:https://my.oschina.net/pioneeer/blog/10374

她在哭,但我没资格安慰她......​

1 我没资格安慰她......▼2 妈妈的关心总是突如其来▼3 突然就热得离谱了▼4 当贾玲和沈腾开始演起韩剧▼5 有些菜一旦错过就不在▼6 这要不是德高望重的长老还真带不了这样的帽子▼7 连狗都比你会放风筝▼你点的每个赞&#xff0c;我都认真当成了喜欢

指定的文件不是虚拟磁盘 没有快照_vmware workstaiton 15 虚拟机克隆(4)

安装客户机操作系统和应用程序可能要耗费很多时间。通过使用克隆&#xff0c;您可以通过一次安装及配置过程制作很多虚拟机副本。克隆虚拟机比复制虚拟机更简单、更快速。当您需要将多个相同的虚拟机部署到一个组时&#xff0c;克隆功能会非常有用。例如&#xff0c;MIS 部门可…

源码免杀处理的技巧与tips

2019独角兽企业重金招聘Python工程师标准>>> 首先,要了解编译中MAP的利用: 第一步设置VC编译环境生成Map文件。在 VC 中&#xff0c;点击菜单“Project -> Settings”选项页&#xff08;或按下 AltF7&#xff09;&#xff0c;选择 C/C 选项卡&#xff0c;并在…

广东计算机专业软件排名前十大学,2017年全国计算机专业大学排名一览表

2017年全国计算机专业大学排名一览表计算机科学是一门包含各种各样与计算和信息处理相关主题的系统学科&#xff0c;从抽象的.算法分析、形式化语法等等&#xff0c;到更具体的主题如编程语言、程序设计、软件和硬件等。下面是小编收集的全国计算机专业大学排名一览表&#xff…

C# 通过正则表达式来限制控件输入有效性

&#xff0c;界面上允许用户输入的控件&#xff0c;大多是有一定限定的&#xff0c;比如电话号码&#xff0c;只允许11的数字&#xff0c;比如一些算法参数有取值范围限定&#xff0c;比如只允许[1,255]等&#xff0c;这种情况如果等用户输入运行后再在后台验证数据的有效性&am…

C# Winform编程之Button

参考了这篇文章&#xff1a; http://www.cnblogs.com/qianlifeng/archive/2010/04/13/1710869.html 我的代码&#xff1a; JButton.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.…

电热水器和插座之间的相亲故事

2019独角兽企业重金招聘Python工程师标准>>> 回到武汉&#xff0c;租房&#xff0c;然后发现原来的热水器不出水。让房产公司派师傅过来修理&#xff0c;终究还是放弃治疗了。不久&#xff0c;安装了一个新的电热水器。 我喜出望外&#xff0c;等了两个周&#xff0…

mysql in优化_MySQL 探秘: 1 整体架构

新开坑&#xff0c;计划做一系列专辑。由于 MySQL 源码太庞大&#xff0c;不可能面面俱到&#xff0c;先从丁奇《MySQL 实战 45 讲》[1] 案例开始入手&#xff0c;case by case 来做分享。同时强烈推荐丁奇的课&#xff0c;真的是受益匪浅&#xff0c;感谢感谢~~最新版本己经是…

清华姚班/智班2020级新生来了!中国奥数新晋“一姐”在列,湖南、湖北人数最多...

全世界只有3.14 % 的人关注了爆炸吧知识乾明 金磊 发自 凹非寺量子位 报道 | 公众号 QbitAI清华姚班/智班&#xff0c;又双叒叕纳一批英才。根据教育部公示的保送生拟录取名单的信息&#xff0c;清华大学姚班/智班2020年已拟定录取31名应届生&#xff0c;他们都是来自各省的顶级…

成长 | 《大厂晋升指南》学习总结(下)

【学习总结】| Edison Zhou上一篇总结了面评技巧和学习方法部分&#xff0c;本篇总结做事方法和转向提升部分。温馨提示&#xff1a;文中的贴图均来自极客时间《大厂晋升指南》课程。1做事方法概要关于做事能力&#xff0c;有三条业界达成共识的判断标准&#xff0c;分别是闭环…

在SD/MMC卡中可读写的FAT文件系统

2019独角兽企业重金招聘Python工程师标准>>> FAT文件系统 关于eLua中FAT文件系统的实现是使用了来自Elm Chan的一个很好的FatFS文件包。它可以在读写模式中处理FAT12,FAT16和FAT32文件系统。而且它打包了很多功能通过封装的形式。跟ROM文件系统一样它也与C库集成在一…

hql取满足条件最新一条记录_MySql 之一条查询sql的执行过程

每当我把一条查询sql语句写完了&#xff0c;并且执行完得到想要的结果。这时我就在想为什么我写这样的一条sql语句&#xff0c;就能给我查询出我想要的结果&#xff0c;为什么我写了update就能更新一条语句&#xff1f;它们的执行过程是什么样的&#xff1f;它们的原理是什么&a…

高糊马赛克秒变高清,表情帝:这还是我吗?

全世界有3.14 % 的人已经关注了爆炸吧知识来源&#xff1a;机器之心参与&#xff1a;魔王、杜伟有了这个工具&#xff0c;我们终于能够看到马赛克下的那张脸了。给出一张高糊人脸照片&#xff0c;你能用它做什么&#xff1f;杜克大学近期的一项研究可以将高糊人脸照片转换成清晰…

diy计算机组装注意事项,自己组装电脑要注意什么?DIY老司机教你装机注意事项...

相比品牌机&#xff0c;组装电脑的优势在于个性化的DIY硬件定制&#xff0c;让玩家可以自由选择适合自己的配置&#xff0c;可以说可玩度非常高。如今&#xff0c;电脑硬件设计已经十分人性化&#xff0c;网上还有很多直播教程&#xff0c;用视频的方式直观地教大家装机&#x…

Dapr + .NET Core实战(三)状态管理

状态管理解决了什么分布式应用程序中的状态可能很有挑战性。例如&#xff1a;应用程序可能需要不同类型的数据存储。访问和更新数据可能需要不同的一致性级别。多个用户可以同时更新数据&#xff0c;这需要解决冲突。服务必须重试 与数据存储交互 时发生的任何短期暂时性错误。…

Building JavaScript Games for Phones Tablets and Desktop(3)-创造一个游戏世界

2019独角兽企业重金招聘Python工程师标准>>> 创造一个游戏世界 这章教会你如何通过内存中储存的信息创造一个游戏世界。介绍了基本类型和变量并且这些变量是如何储存和改变信息的。接下来&#xff0c;你会看到如何用对象储存更复杂的信息&#xff0c;里面包含成员变…

我女朋友让我删前任,我明明删了她还是要分手...

1 人家都已经删了你还有什么不满意&#xff1f;&#xff1f;&#xff1f;▼2 高跟鞋翻车现场▼3 渣男总能渣出新花样▼4 现在的小朋友懂得也太多了吧&#xff01;▼5 耍帅不可怕&#xff0c;谁失败谁尴尬▼6 朋友&#xff0c;你清醒一点&#xff01;那个小手是鼠标&#…

你知道哪些开源基金会?

从 RMS 创立 FSF 发起自由软件运动&#xff0c;再到 OSI 成立并明确开源软件定义&#xff0c;这种崇尚开放协作的软件开发模式迅速席卷全球。除 FSF 与 OSI 外&#xff0c;还陆续诞生了许多致力于推广和发展开源的基金会。开源基金会对于开源软件和开源社区的组织、发展、协同创…

bpmn如何查看代码 idea_提高程序员效率的IDEA插件推荐(五大神器)

1. SequenceDiagramSequenceDiagram 可以根据代码调用链路自动生成时序图&#xff0c;超级赞&#xff0c;超级推荐&#xff01;这对研究源码&#xff0c;梳理工作中的业务代码有极大的帮助&#xff0c;堪称神器。安装完成后&#xff0c;在某个类的某个函数中&#xff0c;右键 -…