Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeeLyn committed Mar 29, 2019
2 parents 01e77f8 + 17170dd commit 2b968ff
Show file tree
Hide file tree
Showing 49 changed files with 645 additions and 270 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Uragano
A simple, high performance RPC library.

Support load balancing, circuit breaker, fallback, caching, intercepting.

## Package & Status
Package | NuGet
--------|------
Expand Down
2 changes: 1 addition & 1 deletion Uragano.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uragano.Core", "src\Uragano
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uragano.DynamicProxy", "src\Uragano.DynamicProxy\Uragano.DynamicProxy.csproj", "{C6AE65C3-DFC2-484F-937E-482363581DE1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{37596B72-254F-41F3-AD1C-F7F421EB5F02}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{37596B72-254F-41F3-AD1C-F7F421EB5F02}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.WebApi", "samples\Sample.WebApi\Sample.WebApi.csproj", "{3F8DE4D5-C985-438C-B144-13813CD1583C}"
EndProject
Expand Down
90 changes: 88 additions & 2 deletions samples/GenericHostSample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Uragano.Abstractions.ConsistentHash;
using Uragano.Consul;
using Uragano.Core;
using Uragano.Logging.Exceptionless;
using Uragano.Remoting.LoadBalancing;

namespace GenericHostSample
{
class Program
{
public class Node
{
public Node(string host)
{
Host = host;
}

public string Host { get; set; }

public int Num { get; set; }

public override string ToString()
{
return $"{Host}:{Num}";
}
}

static async Task Main(string[] args)
{
Expand All @@ -23,25 +43,91 @@ static async Task Main(string[] args)
}).ConfigureAppConfiguration((context, builder) =>
{
builder.AddJsonFile("uragano.json", false, true);
//builder.AddEnvironmentVariables("uragano");
builder.AddCommandLine(args);
})
.ConfigureServices((context, service) =>
{
service.AddUragano(context.Configuration, builder =>
{
builder.AddServer();
builder.AddClient();
builder.AddClient(LoadBalancing.Polling);
builder.AddCircuitBreaker();
builder.AddExceptionlessLogger();
builder.AddConsul();
});
}).ConfigureLogging((context, builder) =>
{
builder.AddConfiguration(context.Configuration.GetSection("Logging"));
builder.AddConsole();
});
await hostBuilder.RunConsoleAsync();

//var nodes = new List<Node> {
// new Node("139f9cbb-be67-460c-9092-b4b29a6e574a"),
// new Node("3f8fa9c8-4c56-486a-baca-bd7d4639e95b"),
// new Node("c2ab77c7-84c7-4310-aaff-9fe767639135"),
// new Node("55cf40c5-250d-4cb8-9cc7-8d1d361a53b0"),
// new Node("6719662f-74b5-46c7-a652-031c3771b812")
//};
//var x = new ConsistentHash<Node>(500);
//nodes.ForEach(item => { x.AddNode(item, item.Host); });
//var dic = new Dictionary<string, Node>();
//while (true)
//{
// var command = Console.ReadLine();
// if (command == "exit")
// break;
// if (command == "gen")
// {
// for (var i = 0; i < 100000; i++)
// {
// var id = Guid.NewGuid().ToString();
// var node = x.GetNodeForKey(id);
// dic[id] = node;
// node.Num++;
// }

// Console.WriteLine("OK");
// }

// if (command == "info")
// {
// nodes.ForEach(item =>
// {
// Console.WriteLine(item.ToString());
// });

// }

// if (command == "add")
// {
// Console.Write("请输入Key:");
// var k = Console.ReadLine();
// var node = new Node(k);
// nodes.Add(node);
// x.AddNode(node, k);
// }

// if (command == "retry")
// {
// var count = 0;
// foreach (var item in dic)
// {
// var node = x.GetNodeForKey(item.Key);
// if (node.Host != item.Value.Host)
// {
// count++;
// node.Num++;
// }
// }

// Console.WriteLine($"{count}个数据重新分配节点");
// }

//}


}
}
}
8 changes: 4 additions & 4 deletions samples/Sample.Server/Controllers/ValuesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public async Task<IActionResult> Get()
//await HelloService.SayHello();
return Ok(new
{
name = await HelloService.SetMeta(("token", "bearer .....")).SayHello(Guid.NewGuid().ToString()),
Reply = await HelloService.SayHello("Owen"),
entity = await HelloService.SayHello(new TestModel { Id = 1, Name = "owen" }),
gen = await HelloService.Test()
name = await HelloService.SetMeta(("token", "bearer ....."), ("x-consistent-hash-key", Guid.NewGuid().ToString())).SayHello(Guid.NewGuid().ToString()),
//Reply = await HelloService.SayHello("Owen"),
//entity = await HelloService.SayHello(new TestModel { Id = 1, Name = "owen" }),
//gen = await HelloService.Test()

});
}
Expand Down
5 changes: 0 additions & 5 deletions samples/Sample.Server/HelloService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,5 @@ public async Task<ResponseResult<string>> Test()
Result = "OK"
});
}

public Task Test(ResponseResult<string> r)
{
throw new NotImplementedException();
}
}
}
20 changes: 5 additions & 15 deletions samples/Sample.Server/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Sample.Common;
using Sample.Service.Interfaces;
using Uragano.Abstractions;
using Uragano.Caching.Memory;
using Uragano.Caching.Redis;
using Uragano.Codec.MessagePack;
using Uragano.Consul;
using Uragano.Core;
using Uragano.Logging.Exceptionless;
using Uragano.Logging.Log4Net;
using Uragano.Logging.NLog;
using Uragano.Remoting.LoadBalancing;
using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment;

namespace Sample.Server
Expand All @@ -41,7 +30,8 @@ public void ConfigureServices(IServiceCollection services)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddUragano(Configuration, builder =>
{
builder.AddClient();
builder.AddClient(LoadBalancing.Polling);
builder.AddServer();
builder.AddConsul();
Expand All @@ -50,8 +40,8 @@ public void ConfigureServices(IServiceCollection services)
builder.AddExceptionlessLogger();
//builder.AddLog4NetLogger();
//builder.AddNLogLogger();
//builder.AddRedisPartitionCaching();
builder.AddRedisCaching();
builder.AddRedisPartitionCaching();
//builder.AddRedisCaching();
//builder.AddMemoryCaching();
builder.AddOption(UraganoOptions.Remoting_Invoke_CancellationTokenSource_Timeout, TimeSpan.FromSeconds(10));
builder.AddOptions();
Expand Down
18 changes: 16 additions & 2 deletions samples/Sample.Server/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"Caching": {
"Redis": {
"KeyPrefix": "Uragano",
"ExpireSeconds": 60,
"ExpireSeconds": 3600,
"KeyGenerator": null,
"ConnectionStrings": [
{
Expand All @@ -47,6 +47,19 @@
"WriteBuffer": 10240,
"TryIt": 0,
"Name": ""
},
{
"Host": "192.168.1.253",
"Port": 6379,
"Password": "nihao123",
"DefaultDatabase": 13,
"PoolSize": 50,
"SSL": false,
"ConnectionTimeout": -1,
"PreHeat": true,
"WriteBuffer": 10240,
"TryIt": 0,
"Name": ""
}
]
},
Expand All @@ -61,7 +74,8 @@
},
"Options": {
"ThreadPool_MinThreads": 100,
"DotNetty_Event_Loop_Count": 100
"DotNetty_Event_Loop_Count": 100,
"Output_DynamicProxy_SourceCode": true
}
}
}
2 changes: 0 additions & 2 deletions samples/Sample.Service.Interfaces/IHelloService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,5 @@ public interface IHelloService : IService
Task<int> Age();

Task<ResponseResult<string>> Test();

Task Test(ResponseResult<string> r);
}
}
116 changes: 116 additions & 0 deletions src/Uragano.Abstract/ConsistentHash/ConsistentHash.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Uragano.Abstractions.ConsistentHash
{
public class ConsistentHash<T> : IConsistentHash<T>
{
private SortedDictionary<int, T> Ring { get; } = new SortedDictionary<int, T>();

private int VirtualReplication { get; set; }

public ConsistentHash(int virtualReplication = 200)
{
VirtualReplication = virtualReplication;
}

public void SetVirtualReplicationCount(int count)
{
VirtualReplication = count;
}

public List<T> GetAllNodes()
{
return Ring.Select(p => p.Value).Distinct().ToList();
}

public void AddNode(T node, string key)
{
for (var i = 0; i < VirtualReplication; i++)
{
var hash = HashAlgorithm.Hash(key + i);
Ring.Add(hash, node);
}
}

public void RemoveNode(string key)
{
for (var i = 0; i < VirtualReplication; i++)
{
var hash = HashAlgorithm.Hash(key + i);
Ring.Remove(hash);
}
}

public T GetNodeForKey(string key)
{
if (!Ring.Any())
throw new InvalidOperationException("Can not find the available nodes, please call the AddNode method to add nodes.");

var hash = HashAlgorithm.Hash(key);
if (Ring.ContainsKey(hash))
return Ring[hash];
var node = Ring.Where(p => p.Key > hash).OrderBy(i => i.Key).Select(p => p.Value).FirstOrDefault();
if (node != null)
return node;
return Ring.FirstOrDefault().Value;
}
}

internal class HashAlgorithm
{
private const uint m = 0x5bd1e995;
private const int r = 24;
public static int Hash(byte[] data, uint seed = 0xc58f1a7b)
{
var length = data.Length;
if (length == 0)
return 0;

var h = seed ^ (uint)length;
var c = 0;
while (length >= 4)
{
var k = (uint)(
data[c++]
| data[c++] << 8
| data[c++] << 16
| data[c++] << 24);
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
length -= 4;
}
switch (length)
{
case 3:
h ^= (ushort)(data[c++] | data[c++] << 8);
h ^= (uint)(data[c] << 16);
h *= m;
break;
case 2:
h ^= (ushort)(data[c++] | data[c] << 8);
h *= m;
break;
case 1:
h ^= data[c];
h *= m;
break;
}

h ^= h >> 13;
h *= m;
h ^= h >> 15;
return (int)h;
}

public static int Hash(string data, uint seed = 0xc58f1a7b)
{
return Hash(Encoding.UTF8.GetBytes(data), seed);
}
}
}
Loading

0 comments on commit 2b968ff

Please sign in to comment.