首页 > 其他分享 >Orleans简单使用

Orleans简单使用

时间:2023-03-20 21:57:34浏览次数:47  
标签:Orleans .. 简单 cd add client 使用 dotnet

.NET7更新后Orleans也随着更新了一个大版本,但是感觉微软官方的文档并不是很好,这里写个小demo来演示简单的集群管理(本次使用redis,官方文档甚至都没有提过redis),可以参考Orleans 中的群集管理

创建项目

创建文件夹

mkdir Client
mkdir Server
mkdir Grain
mkdir IGrain
mkdir Model

初始化代码

cd Server
dotnet new webapi -minimal
cd ../Client
dotnet new console
cd ../Grain
dotnet new classlib
cd ../IGrain
dotnet new classlib
cd ../Model
dotnet new classlib

添加项目引用

cd ../Server
dotnet add reference ../Grain/Grain.csproj
cd ../Client
dotnet add reference ../IGrain/IGrain.csproj
cd ../IGrain
dotnet add reference ../Model/Model.csproj
cd ../Grain
dotnet add reference ../IGrain/IGrain.csproj

添加包引用

cd ../Server
dotnet add package Microsoft.Orleans.Server
dotnet add package Orleans.Clustering.Redis
dotnet add package Orleans.Persistence.Redis
cd ../Client
dotnet add package Microsoft.Extensions.Hosting
dotnet add package Microsoft.Extensions.Configuration.CommandLine
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
dotnet add package Microsoft.Orleans.Client
dotnet add package Orleans.Clustering.Redis
cd ../Model
dotnet add package Microsoft.Orleans.Sdk
cd ../IGrain
dotnet add package Microsoft.Orleans.Sdk
cd ../Grain
dotnet add package Microsoft.Orleans.Sdk

添加代码

Model:

//File:Message
namespace Model;
[GenerateSerializer]
public class Message
{
    [Id(0)]
    public string Ip { get; set; }
}

IGrain:

//File:IMessageHandler.cs
using Model;
namespace IGrain;
public interface IMessageHandler : IGrainWithIntegerKey
{
    ValueTask<string> Send(Message message);
}

Grain:

//File:MessageHandler.cs
using IGrain;
using Model;
namespace Grain;
public class MessageHandler : IMessageHandler
{
    public ValueTask<string> Send(Message message)
    {
        Console.WriteLine($"[DateTime] {DateTime.Now} [Message:Ip] {message.Ip}");
        return ValueTask.FromResult("ok");
    }
}

Server:

//File:Program.cs
using Orleans.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseOrleans((ctx, orleansBuilder) =>
{
    var redisAddress = builder.Configuration["redisHost"];
    orleansBuilder.UseRedisClustering(options => options.ConnectionString = redisAddress);
    orleansBuilder.AddRedisGrainStorage("votes", options => options.ConnectionString = redisAddress);
});
var app = builder.Build();
app.Run();

Client:

//File:Program.cs
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using IGrain;
using System.Net;
var config = new ServiceCollection()
    .AddSingleton<IConfiguration>(serviceProvider =>
    {
        IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
        configurationBuilder.AddEnvironmentVariables();
        if (args != null)
        {
            configurationBuilder.AddCommandLine(args);
        }
        return configurationBuilder.Build();
    })
    .BuildServiceProvider().GetService<IConfiguration>();
Thread.Sleep(5000);//docker直接跑的话,有可能Server没跑起来Client就已经准备去连接了
try
{
    IHost host = await StartClientAsync(config["redisHost"] ?? "127.0.0.1:6379");
    IClusterClient client = host.Services.GetRequiredService<IClusterClient>();
    //下面做一些事情
    await DoClientWorkAsync(client);
    while (true)
    {
        await Task.Delay(5000);
        await DoClientWorkAsync(client);
    }
    await host.StopAsync();
    return 0;
}
catch (Exception e)
{
    Console.WriteLine($$"""
        Exception while trying to run client: {{e.Message}}
        Make sure the silo the client is trying to connect to is running.
        Press any key to exit.
        """);
    return 1;
}

static async Task<IHost> StartClientAsync(string redisHost)
{
    var redisAddress = redisHost;
    var builder = new HostBuilder()
        .UseOrleansClient(client =>
        {
            client.UseRedisClustering(options => options.ConnectionString = redisAddress);
        })
        .ConfigureLogging(logging => logging.AddConsole());

    var host = builder.Build();
    await host.StartAsync();
    Console.WriteLine("Client successfully connected to silo host \n");
    return host;
}

static async Task DoClientWorkAsync(IClusterClient client)
{
    var friend = client.GetGrain<IMessageHandler>(0);
    var result = await friend.Send(new Model.Message
    {
        Ip = Dns.GetHostName()
    });
}

项目发布

publish

在根目录创建publish.bat

dotnet publish Server -o server_publish
dotnet publish Client -o client_publish

执行./publish

dockerfile

dockerfile_client:

FROM mcr.microsoft.com/dotnet/aspnet:7.0
COPY client_publish /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "Client.dll"]

dockerfile_server

FROM mcr.microsoft.com/dotnet/aspnet:7.0
COPY server_publish /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "Server.dll"]

docker-compose

version: '3'
services:
  redis:
    image: redis:latest
  server:
    build:
      context: ./
      dockerfile: ./dockerfile_server
    depends_on:
      - redis
    environment:
      - redisHost=redis:6379
  client:
    build:
      context: ./
      dockerfile: ./dockerfile_client
    depends_on:
      - server
    environment:
      - redisHost=redis:6379

执行docker compose up --scale client=3 --scale server=2

效果展示


我们关闭server2后,发现他会自动选举别的server

power byzhsun999

标签:Orleans,..,简单,cd,add,client,使用,dotnet
From: https://www.cnblogs.com/zhsun999/p/17237984.html

相关文章

  • 如何使用ChatGPT赚钱之四
    目前网络上最热门的话题之一是如何使用ChatGPT赚钱。我们的文章讨论了使用AI工具赚钱的13种简单方法。我们将提供一些实际示例,说明如何从AI获得您想要的东西。由Elo......
  • docker镜像中所有方法无法使用
    事情的起因是,我在win11的电脑上进行开发,将docker容器打包成镜像,再移植进服务器,再从镜像运行的容器中所有方法和命令都无法使用。最后的原因是,docker版本差别过大,所以应当......
  • Unbuntu22.04使用NVM安装NodeJS
    一、使用NVM(NodeVersionManager)1.在NVMgithub上的readme获取一行命令curl-o-https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh|bash或wge......
  • 从0到1构建springboot web应用镜像并使用容器部署
    文章目录​​一、生成镜像的两种方法​​​​1.1、使用commit生成镜像​​​​1.1.1、拉取Centos基础镜像​​​​1.1.2、启动Centos容器并安装Go​​​​1.1.3、commit生成......
  • 全志系列芯片如何在Tina Linux中使用脚本完成定制化升级?
    1.主题在TinaLinux中,如何使用脚本完成定制化升级2.问题背景硬件:全平台软件:Tina其他:支持OTA升级的平台,可实现脚本定制化升级3.具体表现在OTA升级过程中,添加定制化需......
  • hyperfine 使用指南
    hyperfine使用指南简介测量程序运行耗时是一个常见的需求。我们经常会调整自己编写的程序,来给程序加速。但是自己提出的加速计划,不一定会被机器认可。比如,你觉得++i......
  • 如何使用ChatGPT赚钱之三
    所有人正在谈论ChatGPT,OpenAI的“GPT”聊天机器人。它目前是免费使用的,可以尝试一下。但是你真的能帮助人们并通过ChatGPT赚钱吗?下面我将分享我如何使用它来赚钱并提供......
  • 使用python来模拟端口被占用的测试场景
    一、测试场景拿到一个运维如软件,做安装部署测试。其中,测试过程中存在一种场景:由于环境清理不干净等原因,导致软件安装部署时,某个组件的端口号被占用,而导致部署失败的情况。......
  • 使用 Python 实现一个 RPC 框架
    1.概述RPC是什么?RPC(RemoteProcedureCallProtocol),RPC是指远程过程调用,比如现在有两台服务器A、B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方......
  • 使用ChatGPT赚钱的7个提示
    ChatGPT是OpenAI基于文本的人工智能模型,在短时间内获得了巨大的普及。它在推出后的短短1天内就拥有5万用户。该模型已经过大量资源的训练,可以响应几乎任何类型的查询。在......