.NET Core下去中心化访问HTTP服务集群
(给DotNet加星标,提升.Net技能)
转自:smark
cnblogs.com/smark/p/10114989.html
一般应用服务都会部署到多台服务器之上
1、可以通过硬件得到更多的并发处理能力;
2、可以避免单点太故障的出现,从而确保服务7X24有效运作。
public class HomeController : Controller
{
[HttpPost]
public int EmployeeAdd([FromBody]List<Employee> items)
{
return items == null ? 0 : items.Count;
}
[HttpPost]
public Employee EmployeeEdit(int id, [FromBody]Employee emp)
{
Employee record = DataHelper.Employees.Find(e => e.EmployeeID == id);
if (record != null)
{
record.City = emp.City;
record.Address = emp.Address;
record.Title = emp.Title;
record.HomePhone = emp.HomePhone;
return record;
}
return null;
}
public object EmployeesGetName()
{
return from e in DataHelper.Employees select new { ID = e.EmployeeID, Name = e.FirstName + " " + e.LastName };
}
public object Customers(int count)
{
List<Customer> result = new List<Customer>();
if (count > DataHelper.Customers.Count)
count = DataHelper.Customers.Count;
for (int i = 0; i < count; i++)
{
result.Add(DataHelper.Customers[i]);
}
return result;
}
public object CustomersGetName()
{
return from c in DataHelper.Customers select new { ID = c.CustomerID, Name = c.CompanyName };
}
}
定义访问接口
组件支持通过接口的方式来描述HTTP接口服务,接口的访问方式对使用和维护都具有着极大的便利性,以下是针对以上服务描述的接口
[JsonFormater]
[Controller(BaseUrl = "Home")]
public interface IDataService
{
[Get]
Task<DateTime> GetTime();
[Get]
Task<string> Hello(string name);
[Get]
Task<bool> Login(string name, string pwd);
[Get]
Task<List<Employee>> Employees();
[Get]
Task<Employee> EmployeeGet(int id);
[Post]
Task<int> EmployeeAdd(params Employee[] items);
[Post]
Task<Employee> EmployeeEdit([CQuery]int id, Employee emp);
[Get]
Task<List<EmployeeName>> EmployeesGetName();
[Get]
Task<List<Customer>> Customers(int count);
[Get]
Task<List<CustomerName>> CustomersGetName();
[Get]
Task<List<Order>> Orders(int? employeeid, string customerid, int index, int size);
}
private static HttpClusterApi HttpClusterApi = new HttpClusterApi();
HttpClusterApi对象是线程安全的,所以定义成静态即可;也可以根据服务分类来定义不同的HttpClusterApi(之于内部的工作原理这里就不详细解说了,可以到GitHub上过一步了解)。创建了集群接口对象之后就可以用它来创建接口实例。
private static IDataService DataService;
DataService = HttpClusterApi.Create<IDataService>();
同样接口实例也是线程安的,只需要创建一个即可在不同线程和方法里同时调用。其实这样创建接口后还没能正常使用,因为没有定义相应服务地址,可以通过HttpClusterApi添加不同服务地址:
HttpClusterApi.AddHost("*", Host25, Host29);
以上是所有请求都负载到Host25和Host29,一般情况都不会直这样定义;*的优先级是最低的,只有没有匹配到其他url描述的情况才会匹配*
平均负载
平均负载是一种最常用的方式,主要是把并发请求平均到不同的服务器上;以下是针对employee相关请求的地址负载到5个服务上.
HttpClusterApi.AddHost("employee.*", Host26, Host27, Host28, Host29, Host30);
接下简单地测试一下
System.Threading.ThreadPool.QueueUserWorkItem(async (o) =>
{
while (true)
{
try
{
await DataService.EmployeeGet(2);
}
catch (Exception e_)
{
Console.WriteLine(e_.Message);
}
}
});
测试结果:
HttpClusterApi.GetUrlNode("employee.*").Add(new string[] { Host26, Host27, Host28 }).Add(Host29,5).Add(Host30,5);
以上代码分别把Host29和Host30的权重设置为5其他均为10.
public class HTTPRemoteSourceHandler : INodeSourceHandler
{
private HttpClusterApi mHttpClusterApi = new HttpClusterApi();
private IHttpSourceApi mRemoteSourceApi;
public HTTPRemoteSourceHandler(string name, params string[] hosts)
{
mHttpClusterApi.AddHost("*", hosts);
mRemoteSourceApi = mHttpClusterApi.Create<IHttpSourceApi>();
Name = name;
}
public string Name { get; set; }
public int UpdateTime { get; set; } = 5;
public Task<ApiClusterInfo> Load()
{
return mRemoteSourceApi._GetCluster(Name);
}
}
实现是每5秒钟检则一下信息源,集成到HttpClusterApi如下:
HTTPRemoteSourceHandler remoteSourceHandler = new HTTPRemoteSourceHandler("default", "http://localhost:8080");
HttpClusterApi.NodeSourceHandler = remoteSourceHandler;
var result = await HttpClusterApi.LoadNodeSource();
设置INodeSourceHandler后组件就会检配置信息,检测错误或版本没有变化的情况就不会更新配置。以下是针对测编写的一个HTTP配置服务:
详细的代码可以访问 https://github.com/IKende/FastHttpApi
推荐阅读
(点击标题可跳转阅读)
看完本文有收获?请转发分享给更多人
关注「DotNet」加星标,提升.Net技能