• 心酸部署dapr经历,最后一步莫名的遗憾


    dapr大概的了解,个人理解他就是一个分布式服务的管理,把微服务常用的组件(缓存,消息中间件、分布式锁、安全id4等)和监控以及服务注册、发现等等一系列功能以一个很抽象的方式管理起来。

    可能我们部署微服务用consul、ocelot、polly套件、orleans等去实现,但是不可避免的会遇到服务之间的调用等问题,更不用说服务本身的一些列骚操作,dapr刚好帮助我们解决了这些,

    服务之间调用Dapr.AspNetCore库,客户端调用的都是dapr管理库Dapr.Client,netcore使用就这两大库,再加上各种yaml配置等,当然它是不局限语言限制。

    下面用一个简单的例子来揭露一下他的真面目,项目也很直白,一个client对外,server就是提供服务的一方。

    至于代码更是简单的出奇,服务端就只需要一行注入的代码,业务代码不需要做任何改动。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    namespace Server
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = WebApplication.CreateBuilder(args);
     
                // Add services to the container.
     
                builder.Services.AddControllers().AddDapr(); //关键的服务注册,只需要引入Dapr.AspNetCore包
                // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                builder.Services.AddEndpointsApiExplorer();
                builder.Services.AddSwaggerGen();
     
                var app = builder.Build();
     
                // Configure the HTTP request pipeline.
                if (app.Environment.IsDevelopment())
                {
                    app.UseSwagger();
                    app.UseSwaggerUI();
                }
     
                //app.UseHttpsRedirection();
     
                app.UseAuthorization();
     
     
                app.MapControllers();
     
                app.Run();
            }
        }
    }

      

    复制代码
    using Microsoft.AspNetCore.Mvc;
    
    namespace Server.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
    
            private readonly ILogger _logger;
    
            public WeatherForecastController(ILogger logger)
            {
                _logger = logger;
            }
    
            [HttpGet(Name = "GetWeatherForecast")]
            public IEnumerable Get()
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                .ToArray();
            }
        }
    }
    namespace Server
    {
        public class WeatherForecast
        {
            public DateTime Date { get; set; }
    
            public int TemperatureC { get; set; }
    
            public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    
            public string? Summary { get; set; }
        }
    }
    复制代码

     

    下面就是客户端调用的代码,只需要引入包Dapr.Client包,当然consul作为服务之间调用就是httpclient调用了。

    复制代码
    namespace Client
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var builder = WebApplication.CreateBuilder(args);
    
                // Add services to the container.
    
                builder.Services.AddControllers();
                // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                builder.Services.AddEndpointsApiExplorer();
                builder.Services.AddSwaggerGen();
    
                var app = builder.Build();
    
                // Configure the HTTP request pipeline.
                if (app.Environment.IsDevelopment())
                {
                    app.UseSwagger();
                    app.UseSwaggerUI();
                }
    
                //app.UseHttpsRedirection();
    
                app.UseAuthorization();
    
    
                app.MapControllers();
    
                app.Run();
            }
        }
    }
    复制代码
    复制代码
    using Dapr.Client;
    using Microsoft.AspNetCore.Mvc;
    
    namespace Client.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private readonly ILogger _logger;
    
            public WeatherForecastController(ILogger logger)
            {
                _logger = logger;
            }
    
            [HttpGet(Name = "GetWeatherForecast")]
            public IEnumerable Get()
            {
                //服务之间没有用httpclient调用,用特有的dapr调用。
                var daprClient = new DaprClientBuilder().Build();
                var content = daprClient.InvokeMethodAsync>(HttpMethod.Get, "getwf", "WeatherForecast").Result;
                _logger.LogInformation($"获取wf成功:{content.ToArray().ToString()}");
                return content.ToArray();
            }
        }
    }
    namespace Client
    {
        public class WeatherForecast
        {
            public DateTime Date { get; set; }
    
            public int TemperatureC { get; set; }
    
            public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    
            public string? Summary { get; set; }
        }
    }
    复制代码

    这个例子仅仅只说明了用Dapr微服务之间的调用,这个不是很服务,但是部署和配置等一系列操作就需要docker基础了。

    首先要有虚拟机,linux系统,安装好docker,本文没有用到任何yaml文件,所以没用docker-compose。

    dapr的安装看官网,还有初始化,安装完docker ps看看这几个服务在不在。

     安装 Dapr CLI 脚手架工具 | Dapr 文档库

    aspnetcore发布代码掠过,下面是发布后的代码,我直接拷贝到我的虚拟机home目录下面。

    开三个窗口,打开Server

    、Client文件夹,分别在对应文件夹执行命令, --app-id 后面就是dapr内部指定的唯一识别,相当于httpclient的IP地址, --dapr-http-port就是dapr的地址端口,--app-port就是dapr服务提供给外部的调用地址端口。

    打个比方一个dapr利弊一个docker,部署一个服务起一个docker,服务之间通信那么也就成了docker之间的通信,而且他负责自己服务的一切事情。

    看调用代码getwf就是Server在dapr起的唯一名字--app-id, WeatherForecast就是控制器,类似于httpclient的 http://*:port/weatherforecast get调用。

    dapr run --app-id clientservice --dapr-http-port 5882 --app-port 5883 dotnet Client.dll
    dapr run --app-id getwf --dapr-http-port 5880 --app-port 5881 dotnet Server.dll
      //服务之间没有用httpclient调用,用特有的dapr调用。
                var daprClient = new DaprClientBuilder().Build();
                var content = daprClient.InvokeMethodAsync>(HttpMethod.Get, "getwf", "WeatherForecast").Result;
                _logger.LogInformation($"获取wf成功:{content.ToArray().ToString()}");

     

    查看dapr list可以看到有两个服务在运行中。正常情况我们调用虚拟机ip:5883/weatherforecast就可以了正常访问客户端拿到数据,但是很不幸我失败了,而且还没找到原因。

    部署的server服务后会有下面的打印信息,而且我是可以通过5096端口访问的,这说明问题出在dapr上,而不是我们部署的问题。

     

    官方文档介绍的不是很多,而且我也只是近期才研究这个,所以这个问题如果有能解答的万分感谢!

    配置文件appsettings.json需要指定端口,否则两个以上服务部署会默认5000冲突。

    以上的部署仅仅体现它的服务之间是怎么调用的代码实现。

    它的其他核心功能状态管理、缓存、异步通信、分布式锁、链路、监控、安全等一系列中间件几乎涵盖了微服务的零零碎碎。

    以前一直以为这个是运维的管理工具,去研究实践才认识到代码层面也是需要大量时间学习,就是各种中间件的使用。作为开发不去学习确实有点跟不上时代了。从docker、k8s 到dapr,对于面试开发也挺不容易。

     

     

    后续来了,一天后查资料发现问题所在。dapr 的--app-port需要跟dotnet启动服的端口保持一致。比较看好dapr,netcore微服务架构是个不错的选择,还有未来也很看好。部署没问题了,后面就是学习微服务中运用dapr的间件。

    w

     源代码:

    exercisebook/Dapr/DaprDemo at main · liuzhixin405/exercisebook (github.com)

  • 相关阅读:
    Java 中项目路径映射物理机磁盘路径配置。
    [附源码]Python计算机毕业设计Django美发店会员管理系统
    融合动态概率阈值和自适应变异的鲸鱼优化算法-附代码
    SIM卡相关知识介绍
    JKTD-1000型铁电材料测试仪
    左偏树
    基于低代码开发平台+BPM流程管理打造的行业KM解决方案
    matlab求矩阵的伪逆或者负二分之一次方
    Bika LIMS 开源LIMS集——实验室检验流程概述及主页、面板
    LightDB兼容Oracle table_exists_action功能
  • 原文地址:https://www.cnblogs.com/morec/p/17131840.html