AutoCSer is an out-of-the-box RPC framework implemented by C#, which has high concurrency, high throughput and other high performance characteristics, and is an ideal distributed application infrastructure.
AutoCSer 是一个 C# 实现的开箱即用的 RPC 框架,具有高并发、高吞吐等高性能特性,是理想的分布式应用基础设施。
Based on AutoCSer RPC implementation of object-oriented programming memory database, support traditional database level reliable persistence, persistence API has natural transaction characteristics, support according to business logic to customize data structure nodes, support local embedding mode to meet the needs of high-performance game intra-office service.
基于 AutoCSer RPC 实现的面向对象编程的内存数据库,支持传统数据库级别的可靠持久化,持久化 API 具有天然的事务特性,支持根据业务逻辑自定义数据结构节点,支持本地嵌入模式满足高性能游戏局内服务需求。
/// <summary>
/// Interface symmetry service definition
/// 接口对称服务定义
/// </summary>
[AutoCSer.Net.CommandServerControllerInterface]
public interface ISymmetryService
{
/// <summary>
/// Asynchronous API definition
/// 异步 API 定义
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
Task<int> AddAsync(int left, int right);
/// <summary>
/// Synchronization API definition (It is not recommended to define synchronization apis in interface symmetric services because the client synchronization blocking mode may cause performance bottlenecks)
/// 同步 API 定义(不建议在接口对称服务中定义同步 API,因为客户端同步阻塞模式可能造成性能瓶颈)
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
int Add(int left, int right);
}
/// <summary>
/// Interface symmetry service
/// 接口对称服务
/// </summary>
internal sealed class SymmetryService : ISymmetryService
{
/// <summary>
/// Asynchronous API definition
/// 异步 API 定义
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
Task<int> ISymmetryService.AddAsync(int left, int right) { return Task.FromResult(left + right); }
/// <summary>
/// Synchronization API definition
/// 同步 API 定义
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public int Add(int left, int right) { return left + right; }
}
AutoCSer.Net.CommandServerConfig config = new AutoCSer.Net.CommandServerConfig
{
Host = new AutoCSer.Net.HostEndPoint((ushort)AutoCSer.TestCase.Common.CommandServerPortEnum.Document)
};
await using (AutoCSer.Net.CommandListener commandListener = new AutoCSer.Net.CommandListener(config
, AutoCSer.Net.CommandServerInterfaceControllerCreator.GetCreator<ISymmetryService>(new SymmetryService())))
{
if (await commandListener.Start())
{
Console.WriteLine("Press quit to exit.");
while (Console.ReadLine() != "quit") ;
}
}
/// <summary>
/// Test client
/// </summary>
private static readonly AutoCSer.Net.CommandClient<ISymmetryService> commandClient = new AutoCSer.Net.CommandClientConfig<ISymmetryService>
{
Host = new AutoCSer.Net.HostEndPoint((ushort)AutoCSer.TestCase.Common.CommandServerPortEnum.Document),
}.CreateSymmetryClient();
/// <summary>
/// Client test
/// </summary>
/// <returns></returns>
internal static async Task Test()
{
var client = await commandClient.GetSocketEvent();
if (client != null)
{
Console.WriteLine($"2 + 3 = {await client.InterfaceController.AddAsync(2, 3)}");
Console.WriteLine($"1 + 2 = {client.InterfaceController.Add(1, 2)}");
}
}
RPC is the core foundation component of AutoCSer, and the high concurrent throughput test performance exceeds .NET gRPC by an order of magnitude.
RPC 是 AutoCSer 的核心基础组件,高并发吞吐测试性能超过 .NET gRPC 一个数量级。
- 从接口对称 RPC 开始 - 1.SymmetryService
- 数据序列化 - 2.ServiceDataSerialize
- 线程调度策略 - 3.ServiceThreadStrategy
- 鉴权与传输数据编码 - 4.ServiceAuthentication
- 服务信息注册与推送 - 9.ServerRegistry
- 反向 RPC 服务 - 10.ReverseServer
/// <summary>
/// Log stream persistence in memory database server configuration
/// 日志流持久化内存数据库服务端配置
/// </summary>
internal sealed class ServiceConfig : AutoCSer.CommandService.StreamPersistenceMemoryDatabaseServiceConfig
{
/// <summary>
/// The test environment deletes historical persistent files from the previous 15 minutes. The production environment processes the files based on site requirements
/// 测试环境删除 15 分钟以前的历史持久化文件,生产环境根据实际需求处理
/// </summary>
/// <returns></returns>
public override DateTime GetRemoveHistoryFileTime()
{
return AutoCSer.Threading.SecondTimer.UtcNow.AddMinutes(-15);
}
/// <summary>
/// The test environment deletes persistent files once a minute. The production environment deletes persistent files based on site requirements
/// 测试环境每分钟执行一次删除历史持久化文件操作,生产环境根据实际需求处理
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public override void RemoveHistoryFile(AutoCSer.CommandService.StreamPersistenceMemoryDatabaseService service)
{
new AutoCSer.CommandService.StreamPersistenceMemoryDatabase.RemoveHistoryFile(service).Remove(new AutoCSer.Threading.TaskRunTimer(60.0)).NotWait();
}
/// <summary>
/// Set the rebuild file size to at least 10MB
/// 重建文件大小设置为至少 10MB
/// </summary>
/// <param name="service"></param>
/// <returns></returns>
public override bool CheckRebuild(AutoCSer.CommandService.StreamPersistenceMemoryDatabaseService service)
{
long persistencePosition = service.GetPersistencePosition();
return (persistencePosition >> 1) >= service.RebuildSnapshotPosition && persistencePosition > 10 << 20;
}
}
AutoCSer.Document.MemoryDatabaseNode.Server.ServiceConfig databaseServiceConfig = new AutoCSer.Document.MemoryDatabaseNode.Server.ServiceConfig
{
PersistencePath = Path.Combine(AutoCSer.TestCase.Common.Config.AutoCSerTemporaryFilePath, nameof(AutoCSer.Document.MemoryDatabaseNode)),
PersistenceSwitchPath = Path.Combine(AutoCSer.TestCase.Common.Config.AutoCSerTemporaryFilePath, nameof(AutoCSer.Document.MemoryDatabaseNode) + nameof(AutoCSer.Document.MemoryDatabaseNode.Server.ServiceConfig.PersistenceSwitchPath))
};
AutoCSer.CommandService.StreamPersistenceMemoryDatabaseService databaseService = databaseServiceConfig.Create();
AutoCSer.Net.CommandServerConfig commandServerConfig = new AutoCSer.Net.CommandServerConfig
{
Host = new AutoCSer.Net.HostEndPoint((ushort)AutoCSer.TestCase.Common.CommandServerPortEnum.Document),
};
await using (AutoCSer.Net.CommandListener commandListener = new AutoCSer.Net.CommandListenerBuilder(0)
.Append<AutoCSer.CommandService.IStreamPersistenceMemoryDatabaseService>(databaseService)
.CreateCommandListener(commandServerConfig))
{
if (await commandListener.Start())
{
Console.WriteLine("Press quit to exit.");
while (Console.ReadLine() != "quit") ;
}
}
/// <summary>
/// Command client socket event
/// 命令客户端套接字事件
/// </summary>
internal sealed class CommandClientSocketEvent : AutoCSer.Net.CommandClientSocketEventTask<CommandClientSocketEvent>, AutoCSer.CommandService.IStreamPersistenceMemoryDatabaseClientSocketEvent
{
/// <summary>
/// Log stream persistence memory database client interface
/// 日志流持久化内存数据库客户端接口
/// </summary>
[AllowNull]
public AutoCSer.CommandService.IStreamPersistenceMemoryDatabaseClient StreamPersistenceMemoryDatabaseClient { get; private set; }
/// <summary>
/// Client controller creator parameter set
/// 客户端控制器创建器参数集合
/// </summary>
public override IEnumerable<AutoCSer.Net.CommandClientControllerCreatorParameter> ControllerCreatorParameters
{
get
{
yield return new AutoCSer.Net.CommandClientControllerCreatorParameter(typeof(AutoCSer.CommandService.IStreamPersistenceMemoryDatabaseService), typeof(AutoCSer.CommandService.IStreamPersistenceMemoryDatabaseClient));
}
}
/// <summary>
/// Command client socket event
/// 命令客户端套接字事件
/// </summary>
/// <param name="client">Command client
/// 命令客户端</param>
public CommandClientSocketEvent(AutoCSer.Net.ICommandClient client) : base(client) { }
/// <summary>
/// Log stream persistence memory database client single example
/// 日志流持久化内存数据库客户端单例
/// </summary>
public static readonly AutoCSer.CommandService.StreamPersistenceMemoryDatabaseClientCache<AutoCSer.CommandService.StreamPersistenceMemoryDatabase.IServiceNodeClientNode, CommandClientSocketEvent> StreamPersistenceMemoryDatabaseClientCache = new AutoCSer.CommandService.StreamPersistenceMemoryDatabaseClientCache<AutoCSer.CommandService.StreamPersistenceMemoryDatabase.IServiceNodeClientNode, CommandClientSocketEvent>(new AutoCSer.Net.CommandClientConfig
{
Host = new AutoCSer.Net.HostEndPoint((ushort)AutoCSer.TestCase.Common.CommandServerPortEnum.Document),
GetSocketEventDelegate = (client) => new CommandClientSocketEvent(client)
});
Based on AutoCSer RPC implementation of memory database, high concurrent throughput test performance is much higher than Garnet + StackExchange.Redis combination.
基于 AutoCSer RPC 实现的内存数据库,高并发吞吐测试性能远高于 Garnet + StackExchange.Redis 组合。