一、安装
我这里直接下载的二进制文件
https://github.com/dapr/dapr/releases/download/v1.3.0/daprd_linux_amd64.tar.gz
tar zxvf dapr_linux_amd64.tar.gz
cp dapr /usr/bin/
chmod +x /usr/bin/dapr
dapr init 
默认安装1.3.0版本
二、本地运行程序
编写Demo程序,一个很简单的Asp.net core 程序
using DaprTest.Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace DaprTest
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddDapr();
            
            services.AddActors(options =>
            {
                options.Actors.RegisterActor<IncrActorOne>();
            });
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseRouting();
            app.UseCloudEvents();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapSubscribeHandler();
                endpoints.MapControllers();
                endpoints.MapActorsHandlers();
            });
        }
    }
}
 
1 using Dapr; 2 using Dapr.Actors; 3 using Dapr.Actors.Client; 4 using Dapr.Actors.Runtime; 5 using Dapr.Client; 6 using Microsoft.AspNetCore.Mvc; 7 using Microsoft.Extensions.Logging; 8 using System.Threading.Tasks; 9 10 namespace DaprTest.Controllers 11 { 12 [ApiController] 13 [Route("[controller]/[action]")] 14 public class DaprController : ControllerBase 15 { 16 private readonly ILogger<DaprController> _logger; 17 18 public DaprController(ILogger<DaprController> logger) 19 { 20 _logger = logger; 21 } 22 23 private static object _lockOjbect = new object(); 24 public static int incr = 0; 25 26 [HttpGet] 27 public async Task<int> Incr() 28 { 29 int value = 0; 30 lock(_lockOjbect) 31 { 32 value= ++incr; 33 } 34 35 return await Task.FromResult(value); 36 } 37 38 [HttpGet] 39 public async Task<int> IncrActor() 40 { 41 var actorId = new ActorId("123"); 42 var actor = ActorProxy.Create<IIncrActor>(actorId,nameof(IncrActorOne)); 43 var counterValue= await actor.IncrAcor(); 44 45 return counterValue; 46 } 47 48 [Topic("redis-pubsub", "daprpub")] 49 [HttpGet] 50 public async Task<int> Pub([FromServices] DaprClient daprClient) 51 { 52 var eventData = new EnventData { Id = "17", Amount = 10m, }; 53 await daprClient.PublishEventAsync("redis-pubsub", "daprpub", eventData); 54 return await Task.FromResult(4); 55 } 56 57 58 [HttpPost] 59 public string Sub([FromBody]EnventData enventData) 60 { 61 _logger.LogInformation($"来啦,小老弟!{enventData.Amount},{enventData.Id}"); 62 return "123"; 63 } 64 65 [Route("/kafka-binding")] 66 [HttpPost] 67 public string KafkaBinding([FromBody] EnventData enventData) 68 { 69 _logger.LogInformation($"来啦,小老弟!{enventData.Amount},{enventData.Name}"); 70 return "123"; 71 } 72 } 73 74 public class EnventData 75 { 76 public string Name { get; set; } 77 78 public decimal Amount { get; set; } 79 } 80 public interface IIncrActor: IActor 81 { 82 Task<int> IncrAcor(); 83 } 84 85 public class IncrActorOne : Actor, IIncrActor 86 { 87 private static int COUNT = 0; 88 public IncrActorOne(ActorHost host) : base(host) { } 89 90 public async Task<int> IncrAcor() 91 { 92 return await Task.FromResult(++COUNT); 93 } 94 95 public async Task<int> IncrStateAcor() 96 { 97 var currntScore = await StateManager.AddOrUpdateStateAsync("score", 1,(key, currentScore) => currentScore + 1); 98 return currntScore; 99 } 100 } 101 }
dapr run --app-id DaprTest --app-port 5000 dotnet run
这里要注意 --app-port参数,我之前没指定这个参数一直报无法通信。
三、k8s运行demo
要在k8s中运行dapr首先要在k8s中安装dapr相关的组件
dapr init -k
首先要确保执行命令的服务器上能够连接上k8s服务器,等待安装成功。


截图中使用的k8s管理工具kuboard,在测试k8s集群中安装了Dapr、Istio(后续一定要记一些istio、Envoy的知识点)。
安装成功后就可以将Demo程序打镜像发布到k8s中了。
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY ["DaprTest/DaprTest.csproj", "DaprTest/"] RUN dotnet restore "DaprTest/DaprTest.csproj" COPY . . WORKDIR "/src/DaprTest" RUN dotnet build "DaprTest.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "DaprTest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . RUN ls ENTRYPOINT ["dotnet", "DaprTest.dll"]
docker build -t 镜像名 docker push //推送镜像
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: dotnet-daprtest
  namespace: dapr-test
spec:
  hosts:
  - "*"
  gateways:
  - dapr-test-gateway
  http:
  - match:
    - uri:
        prefix: /betadaprtest/
    rewrite:
      uri: /
    route:
    - destination:
        host: dotnet-daprtest
        port:
          number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: dapr-test-gateway
  namespace: dapr-test
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - xxx.xxx.com
      port:
        name: http
        number: 80
        protocol: HTTP
apiVersion: v1
kind: Service
metadata:
  name: dotnet-daprtest
  namespace: dapr-test
  labels:
    app: dotnet-daprtest
    service: dotnet-daprtest
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: dotnet-daprtest
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: dapr-test
  name: dotnet-daprtest
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-daprtest
  template: 
    metadata:
      labels:
        app: dotnet-daprtest
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "dotnet-daprtest"
        dapr.io/app-port: "80"
    spec:
      imagePullSecrets:
      - name: xxxx
      restartPolicy: Always
      containers:
      - name: dotnet-daprtest
        image: xxxxx
        ports:
        - containerPort: 80
virtualservice、gateway 定义如何访问服务。
出于测试目的就没有在命名空间级别启用dapr 注入,直接在metadata -》annotaions 中启用dapr。
pod启动成功后就可以看到Pod中启动了两个容器,一个是Demo本身,还有一个就是daprd的边车容器

可以看下daprd容器中的日志,看看这个容器在启动时都做了些什么

可以看拿到都是一些初始化,加载component组件等,这里要注意,如果发现daprd容器启动失败,可以从这个容器日志看到一些信息,一版都是一些组件加载失败,找到对应的组件修改即可。
也可以用命令查看daprd容器日志,kubectl logs -f --tail=100 -n 命名空间 podId -c daprd
四、StatusDemo
dapr在初始化k8s组件时并不会初始化Status组件(单机初始化时会创建一个redis 作为status实现),所以需要我们自行安装redis或者其他dapr支持的存储组件,Demo里使用自建的redis
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: dapr-test
spec:
  metadata:
    - name: redisHost
      value: ‘xxx:6379‘
    - name: actorStateStore
      value: ‘true‘
    - name: redisDB
      value: ‘17‘
  type: state.redis
  version: v1
五、Actor编程模型
对于Actor并发编程模型的定义就不过多赘述了。
对于Actor只需要在代码中预先定义好,并注册即可
[httpGet]
public async Task<int> IncrActor()
{
var actorId=new ActorId("123");
var actor= ActorProxy.Create<IIncrActor>(actorId,nameof(IncrActorOne));
var counterValue = await actor.incrAcor();
}
public interface IIncrActor: IActor { Task<int> IncrAcor(); } public class IncrActorOne : Actor, IIncrActor { private static int COUNT = 0; public IncrActorOne(ActorHost host) : base(host) { } public async Task<int> IncrAcor() { return await Task.FromResult(++COUNT); } public async Task<int> IncrStateAcor() { var currntScore = await StateManager.AddOrUpdateStateAsync("score", 1,(key, currentScore) => currentScore + 1); return currntScore; } } public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddDapr(); services.AddActors(options => { options.Actors.RegisterActor<IncrActorOne>(); }); }
Actor是动态,可以根据实际情况动态添加,例如根据用户id等标识一个Actor,可以在Dapr自带的Dashboard中查看Actor

六、发布订阅
发布订阅也同样需要定义Component组件
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: redis-pubsub
  namespace: dapr-test
spec:
  type: pubsub.redis
  version: v1
  metadata:
  - name: redisHost
    value: xxxx:6379
  - name: consumerID
    value: "myGroup"
  - name: enableTLS
    value: "false"
  - name: redisPassword
    value: 12345678
---
apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:
  name: dotnet-subscription
  namespace: dapr-test
spec:
  pubsubname: redis-pubsub
  topic: daprpub
  route: /Dapr/Sub
scopes:
- dotnet-daprtest
这里定义了 发布组件、订阅组件,使用Redis实现。使用方式如下
[HttpGet] public async Task<int> Pub([FromServices] DaprClient daprClient) { var eventData = new EnventData { Id = "17", Amount = 10m, }; await daprClient.PublishEventAsync("redis-pubsub", "daprpub", eventData);//redis-pubsub 要使用的组件名称,daprpub topic return await Task.FromResult(4); }
如果想更改实现组件,例如从redis切换到kafka,只需要更改一下 发布组件即可
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: redis-pubsub namespace: dapr-test spec: type: pubsub.kafka version: v1 metadata: - name: brokers value: "xxxxx:9092" - name: consumerGroup value: "daprtest" - name: clientID value: "dotnet-daprtest" - name: authRequired value: "false" - name: maxMessageBytes value: 1024
组件名称依旧是 redis-pubsub,但是实现已经更改为了 kafka。需要注意的是,这里虽然更改了组件但是因为daprd容器并没有监听这种变化,这就导致了要手动去重启pod,这里后期应该会被优化掉。
七、bindings
bindings同样也是添加component即可
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: kafka-binding
  namespace: -test
spec:
  metadata:
    - name: topics
      value: daprtest
    - name: brokers
      value: ‘ffffff:9092‘
    - name: consumerGroup
      value: daprtest
    - name: publishTopic
      value: daprtest
    - name: authRequired
      value: false
    - name: maxMessageBytes
      value: 1024
  type: bindings.kafka
  version: v1
这里需要注意的是 bindings是通http通信的 这就需要http的url要与bindings组件名一致,当然也有可能是我理解的不到位。
原文:https://www.cnblogs.com/pjjwpc/p/15196435.html