从零开始使用Dapr简化微服务的示例

目录
  • 序言
  • 1、安装Docker
  • 2、安装Dapr CLI
  • 3、安装Net6 SDK
  • 4、创建应用程序
    • 4.1、服务调用
    • 4.2、发布订阅
    • 4.3、状态管理
    • 4.4、链路追踪
  •  5、总结

序言

现有的微服务模式需要再业务代码中集成大量基础设施模块,比如注册中心,服务发现,服务调用链路追踪,请求熔断,重试限流等等,使得系统过于臃肿重量级。

Dapr作为新一代微服务模式,使用sidecar模式,简化了现有微服务系统代码,将基础设施层以sidecar模式分离,使得开发人员更集中于业务逻辑编写。

本文以net6和dapr1.5为基础,搭建一个dapr的简单使用示例。

1、安装Docker

Dapr的运行依赖于Docker环境。

作为学习环境,使用Centos 7系统安装Docker。

安装Docker推荐使用daocloud一键安装命令:

curl -sSL https://get.daocloud.io/docker | sh

安装完成后运行命令:

[root@localhost ~]# docker -v
Docker version 20.10.11, build dea9396

显示对应的Docker版本即安装成功。

2、安装Dapr CLI

官方解释:Dapr CLI 是您用于各种 Dapr 相关任务的主要工具。 您可以使用它来运行一个带有Dapr sidecar的应用程序, 以及查看sidecar日志、列出运行中的服务、运行 Dapr 仪表板。

下载Dapr CLI

wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash

验证安装情况

dapr -v

输出以下内容即安装成功。

CLI version: 1.5.0
Runtime version: 1.5.0

由于国内网络问题,使用官方的Dapr安装方法一般会遇到各种问题,因此把dapr下载下来,通过脚本进行安装。

修改hosts文件

vi /etc/hosts
140.82.114.4 github.com
199.232.69.194 github.global.ssl.fastly.net
140.82.114.9 codeload.github.com

刷新缓存

yum install -y nscd
service nscd restart

首先需要安装Git,然后执行以下命令:

git clone -v https://gitee.com/Two-Twoone/dapr-installer.git
cd dapr-installer/
./install.sh

虽然还是很慢,但是总比下不了好多了。

上面命令启动了几个容器,运行下列操作来验证:

[root@localhost dapr-installer]# docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}"
CONTAINER ID   NAMES            PORTS
a0565f609846   dapr_placement   0.0.0.0:50005->50005/tcp, :::50005->50005/tcp
c392f5cf7a18   dapr_redis       0.0.0.0:6379->6379/tcp, :::6379->6379/tcp
2ee68c450b29   dapr_zipkin      9410/tcp, 0.0.0.0:9411->9411/tcp, :::9411->9411/tcp

3、安装Net6 SDK

rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
 yum update
 yum install dotnet-sdk-6.0

4、创建应用程序

创建2个项目分别为 product,cart 引用Dapr

dotnet add package Dapr.AspNetCore

Program.cs中对 的 AddDapr 调用将 DaprClient 类注册到 ASP.NET Core注入系统。 注册客户端后,现在可以将 的实例注入服务代码, DaprClient 以与 Dapr sidecar、构建基块和组件进行通信。

builder.Services.AddControllers().AddDapr();

4.1、服务调用

在微服务系统中,服务与服务间的调用必不可少,难点主要集中在服务所在位置,发生错误时如何重试,负载均衡等问题。

Dapr中使用sidecar 作为服务的反向代理模块来解决这些问题。

prodcut项目增加下列代码

[Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private ILogger<ProductController> _logger;

        public ProductController(ILogger<ProductController> logger)
        {
            _logger = logger;
        }
        private static readonly List<string> products = new List<string> { "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn" };
        [HttpGet]
        public  ActionResult Get()
        {
            _logger.LogInformation($"调用了获取商品方法");
            string[] temps = new string[5];
            for (int i = 0; i < 5; i++)
            {
                Random random = new Random(Guid.NewGuid().GetHashCode());
                temps[i] = products[random.Next(0, products.Count - 1)];
            }
            return Ok( temps);
        }
    }
# 启动Product 项目
dapr run --app-id ProductDemo --app-port 5010 --dapr-http-port 7015 -- dotnet /root/www/product/Dapr.Product.Sample.dll --urls http://*:5010

cart项目增加下列代码,dapr支持http,grpc调用方式,这里以常用的webapi为例,使用http方式调用。

InvokeMethodAsync方法中appid对应的就是dapr run 中的appid,无需关系调用地址。

[Route("api/[controller]")]
    [ApiController]
    public class CartController : ControllerBase
    {
        private  readonly DaprClient _daprClient;
        private  readonly ILogger<CartController> _logger;
        public CartController(DaprClient daprClient, ILogger<CartController> logger)
        {
            _daprClient = daprClient;
            _logger = logger;
        }

        [HttpGet]
        [Route("GetProducts")]
        public async Task<IActionResult> GetProducts()
        {
            _logger.LogInformation($" Cart 获取商品");
            var products = await _daprClient.InvokeMethodAsync<List<string>>(HttpMethod.Get, "ProductDemo", "/api/Product/GetAll");
            return Ok(products);
        }
    }

将程序上传到linux服务器,运行程序

# 启动 Cart 项目
dapr run --app-id CartDemo --app-port 5020 --dapr-http-port 7025 -- dotnet /root/www/cart/Dapr.Cart.Sample.dll --urls http://*:5020

调用接口,可以看到Cart项目几乎没有代码入侵就实现了接口调用。

[root@localhost ~]# curl -X 'GET'   'http://192.168.2.110:5020/api/Cart/GetProducts'
["aa","bb","cc","dd","ee","ff","gg","hh","ii","jj","kk","ll","mm","nn"]

Dapr内部使用了mDns进行了服务注册发现和负载均衡,部署多个product后调用,可以看到轮询调用效果。

在自承载模式下,Dapr 使用 mDNS 查找它。在 Kubernetes 模式下运行时,Kubernetes DNS 服务确定地址。

在调用失败和瞬态错误的情况下,服务调用会执行自动重试,Dapr 默认是开启了重试,所以接口不支持幂等是十分危险的行为。

4.2、发布订阅

​ 发布订阅模式,主要是用于微服务间基于消息进行相互通信。你可能也会说,这也要拿出来说,我搞个RabbitMQ/Kafka就是了,

原来我们都会根据使用的组件引入不同的sdk,不同的消息队列监听、消费模式还不一样。

​ Dapr 提供了一个构建基块,可显著简化实现发布/订阅功能,从而和底层基础设施解耦,编写业务逻辑时不需要关心是什么消息队列。

再Program中添加发布订阅支持

 app.UseCloudEvents();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapSubscribeHandler();
        });

订阅消息,使用Topic特性,传递pubsub和主题名称

 [Topic("pubsub", "newUser")]
        public ActionResult subUserInfo(UserInfo us)
        {
            _logger.LogInformation($"接收到订阅消息 id:{us.id} name:{us.name},age:{us.age},sex:{us.sex}");
            return Ok("处理完毕");
        }

发布消息,使用dapr公开方法PublishEventAsync,传递pubsub和主题名称,以及消息体

[HttpPost]
        public async Task<IActionResult> PubUserInfo(UserInfo us)
        {
            await _daprClient.PublishEventAsync("pubsub", "newUser", us);
            return Ok();
        }

消息发布订阅组件支持RabbitMQ,Redis,Kafka等。

4.3、状态管理

​Dapr 默认使用 Redis 作为状态存储。它也支持MongoDB,PostgreSQL,SQL Server等。

它不会对上层暴露底层用的那个中间件,也就是说在不同环境下可以使用同一套代码来使用不同的中间件。

[HttpPost]
       [Route("SaveUserList")]
        public async Task<IActionResult> SaveUserList()
        {
            var temps = new List<UserInfo>
            {
                new UserInfo("小红",1,true,Guid.NewGuid().ToString()),
                new UserInfo("小黄",1,true,Guid.NewGuid().ToString()),
                new UserInfo("小蓝",1,true,Guid.NewGuid().ToString())
            };
          	await _daprClient.SaveStateAsync("statestore", "UserList", temps);
            return Ok(1);
        }
        [HttpGet]
        [Route("GetUserList")]
        public async Task<IActionResult> GetUserList()
        {
            var list = await _daprClient.GetStateAsync<List<UserInfo>>("statestore", "UserList");
            return Ok(list);
        }
      	[HttpGet]
        [Route("DeleteUserList")]
        public async Task<IActionResult> DeleteUserList()
        {
            await _daprClient.DeleteStateAsync("statestore", "UserList");
            return Ok(1);
        }

        public record UserInfo(string name, int age, bool sex, string id);

4.4、链路追踪

传统微服务中,要实现链路追踪,对代码的侵入强。

Dapr 在 Sidecar 中添加了一个 http/grpc中间件。拦截所有应用程序流量,并自动注入关联 ID 以跟踪分布式事务。

使用 Zipkin 协议进行分布式跟踪,无需代码检测,使用可配置的跟踪级别自动跟踪所有流量。

 5、总结

​本文只是对Dapr做了一个简单示例,对各个组件具体的实现原理没有做过多深入讲解。

​Dapr区别于传统微服务框架最大的优点就是Sidecar 。以前的微服务框架都需要代码项目引用微服务相关的一些类库,无论是服务注册发现、熔断、配置等都是要调用对应类库实现,这些类库是运行在微服务的进程中的,因此这些类库都需要使用和业务代码一样(或者兼容)的语言来开发,因此是比较重的。

​而Sidecar 这种模式,把“注册发现、熔断、配置”等这些微服务的功能都剥离到一个和业务代码的进程相伴而行的独立进程中,业务代码通过http或者grpc等方式和这个Sidecar 进程通讯来完成微服务的相关服务的调用。

​显而易见,在Sidecar 这种模式中,业务代码中只有极少数和Sidecar 进程通讯的代码,因此非常轻量级。这样Sidecar 进程中的服务可以独立升级,模块可以自由组合,不会干扰业务代码。同时由于Sidecar 的进程是独立的进程,业务代码和Sidecar 进程通讯是采用http、grpc这样语言无关的协议,因此业务代码可以采用任何语言来进行开发。

到此这篇关于从零开始使用Dapr简化微服务的文章就介绍到这了,更多相关Dapr简化微服务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Docker微服务的ETCD集群搭建教程详解

    目录 etcd的特性 Etcd构建自身高可用集群主要有三种形式 本次搭建的基础环境 1.将服务器挨个添加进集群 2.将服务器统一添加进集群 etcd api接口 服务注册与发现 etcd是一个高可用的键值存储系统,主要用于共享配置和服务发现.etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性.Raft是一个来自Stanford的新的一致性算法,适用于分布式系统的日志复制,Raft通过选举的

  • 十分钟学会用docker部署微服务

    2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业. 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?今天就来详细解释,帮助大家理解它,还带有简单易懂的实例,教你如何将它用于日常开发并用其部署微服务. 一. Docker简介 Docker是一个开源的容器引擎,它有助于更快地交付应用. Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理.使用 Docker可更快地打包.测试以及部署应用程序,并可以缩短从编写到部署运行

  • 从零开始使用Dapr简化微服务的示例

    目录 序言 1.安装Docker 2.安装Dapr CLI 3.安装Net6 SDK 4.创建应用程序 4.1.服务调用 4.2.发布订阅 4.3.状态管理 4.4.链路追踪  5.总结 序言 现有的微服务模式需要再业务代码中集成大量基础设施模块,比如注册中心,服务发现,服务调用链路追踪,请求熔断,重试限流等等,使得系统过于臃肿重量级. Dapr作为新一代微服务模式,使用sidecar模式,简化了现有微服务系统代码,将基础设施层以sidecar模式分离,使得开发人员更集中于业务逻辑编写. 本文以

  • 微服务领域Spring Boot自动伸缩的实现方法

    前言 自动伸缩是每个人都想要的,尤其是在微服务领域.让我们看看如何在基于Spring Boot的应用程序中实现. 我们决定使用Kubernetes.Pivotal Cloud Foundry或HashiCorp's Nomad等工具的一个更重要的原因是为了让系统可以自动伸缩.当然,这些工具也提供了许多其他有用的功能,在这里,我们只是用它们来实现系统的自动伸缩.乍一看,这似乎很困难,但是,如果我们使用Spring Boot来构建应用程序,并使用Jenkins来实现CI,那么就用不了太多工作. 今天

  • 浅谈Redis在微服务架构中的几种应用场景

    本文介绍在SpringCloud中使用Redis作为Pub/Sub异步通信.缓存或主数据库和配置服务器的三种场景应用. Redis可以广泛用于微服务架构.它可能是您应用程序以多种不同方式利用的少数流行软件解决方案之一.根据要求,它可以充当主数据库,缓存或消息代理.虽然它也是一个键/值存储,但我们可以将它用作微服务体系结构中的配置服务器或发现服务器.虽然它通常被定义为内存中的数据结构,但我们也可以在持久模式下运行它. 这里我将向您展示一些使用Redis与Spring Boot和Spring Clo

  • NodeJS 基于 Dapr 构建云原生微服务应用快速入门教程

    目录 安装 Dapr CLI 本地环境中初始化 Dapr 运行初始化 CLI 命令 验证容器是否正在运行 验证组件目录是否已初始化 使用 Dapr API 运行 Dapr sidecar 保存状态 获取状态 删除状态 上手实战指南 1. 服务调用 示例仓库 运行 order-processor 服务 运行 checkout 服务 查看服务调用输出 2. 状态管理 操纵服务状态 查看 order-processor 输出 3. 发布和订阅 订阅 topic 发布 topic 查看发布/订阅输出 4

  • SpringBoot+Eureka实现微服务负载均衡的示例代码

    1,什么是Eureka,什么是服务注册与发现 Spring Boot作为目前最火爆的web框架.那么它与Eureka又有什么关联呢? Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现. Eureka由两个组件组成:Eureka服务器和Eureka客户端.Eureka服务器用作服务注册服务器. Eureka客户端是一个java客户端,用来简化与服务器的交互.作为轮询负载均衡器,并提供服务的故障切换支持. Netflix在其生产环境中使用的是另外的客户端,它提供基于流

  • 使用SpringBoot实现微服务超时重试模式的示例

    使用resilience4j的库和Spring Boot设计高弹性的微服务. 微服务本质上是分布式的.当您使用分布式系统时,请始终记住这一第一法则- 网络中可能发生任何事情.处理任何此类意外故障可能很难解决.故障可能是任何东西-应用程序,硬件或网络等. 系统从故障中恢复并保持正常运行的能力使系统更具 弹性.它还避免了下游服务的任何级联故障. 重试模式: 在微服务体系结构中,当有多个服务(A,B,C和D)时,一个服务(A)可能依赖于另一服务(B),而另一服务(B)又可能依赖于C,依此类推.有时由于

  • 微服务架构之服务注册与发现实践示例详解

    目录 1 服务注册中心 4种注册中心技术对比 2 Spring Cloud 框架下实现 2.1 Spring Cloud Eureka 2.1.1 创建注册中心 2.1.2 创建客户端 2.2 Spring Cloud Consul 2.2.1 Consul 的优势 2.2.2 Consul的特性 2.2.3 安装Consul注册中心 2.2.4 创建服务提供者 3 总结 微服务系列前篇 详解微服务架构及其演进史 微服务全景架构全面瓦解 微服务架构拆分策略详解 微服务架构之服务注册与发现功能详解

  • Docker安装jenkins实现微服务多模块打包的示例代码

    目录 1.安装 2.初始化 3.配置jenkins 3.1 安装Maven 3.2 配置Maven插件 3.3 安装svn插件 4. 创建自动化部署任务 4.1 配置清理旧的构建 4.2 创建svn账密凭证 4.3 填写build命令 4.4 首次构建 5. 配置maven运行命令及shell脚本 5.1 maven父子项目依赖指令配置 5.2打包完成之后shell命令 废话不多说,直接讲正事 1.安装 # 1.pull jenkins(若使用jdk11则可pull最新版jenkins,否则最新

  • SpringSecurity OAtu2+JWT实现微服务版本的单点登录的示例

    目录 何为单点登录 认证中心 maven配置 用户登录逻辑 OAtuh2配置 配置服务中心 配置规则中心 请求模块 真实请求 一些小问题 何为单点登录 单点登录通俗的话来讲在微服务当中,在一个服务登录后就能免去另一个服务的登录操作,所谓单点登录. 就好像你在微博总网站里登录后,然后在微博里面的某一个模块点进去后,就发现这个模块竟然不用登录了,不是因为这个模块与主网站是一体的用一个SpringSecurity就可以搞定了,这里面的水深着呢!感兴趣更深这个SpringSecurity建议去看看图灵课

  • go-micro微服务domain层开发示例详解

    目录 一 domain层介绍说明 二 model层开发 三 repository层开发 四 service层开发 最后 一 domain层介绍说明 domain层专注于数据库数据领域开发,我们把数据库相关操作全部写在domain层. model层:数据表字段定义与开发 repository层:数据库数据CURD操作 service层:数据库相关业务操作 对于复杂的业务操作,这样可以使业务逻辑更加清晰,有利于后期开发与维护. 二 model层开发 在model目录下新建 user.go 文件 pa

随机推荐